OLD | NEW |
1 /* IBM S/390-specific support for 64-bit ELF | 1 /* IBM S/390-specific support for 64-bit ELF |
2 Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, | 2 Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, |
3 2010, 2011 Free Software Foundation, Inc. | 3 2010, 2011, 2012 Free Software Foundation, Inc. |
4 Contributed Martin Schwidefsky (schwidefsky@de.ibm.com). | 4 Contributed Martin Schwidefsky (schwidefsky@de.ibm.com). |
5 | 5 |
6 This file is part of BFD, the Binary File Descriptor library. | 6 This file is part of BFD, the Binary File Descriptor library. |
7 | 7 |
8 This program is free software; you can redistribute it and/or modify | 8 This program is free software; you can redistribute it and/or modify |
9 it under the terms of the GNU General Public License as published by | 9 it under the terms of the GNU General Public License as published by |
10 the Free Software Foundation; either version 3 of the License, or | 10 the Free Software Foundation; either version 3 of the License, or |
11 (at your option) any later version. | 11 (at your option) any later version. |
12 | 12 |
13 This program is distributed in the hope that it will be useful, | 13 This program is distributed in the hope that it will be useful, |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 GNU General Public License for more details. | 16 GNU General Public License for more details. |
17 | 17 |
18 You should have received a copy of the GNU General Public License | 18 You should have received a copy of the GNU General Public License |
19 along with this program; if not, write to the Free Software | 19 along with this program; if not, write to the Free Software |
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA | 20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA |
21 02110-1301, USA. */ | 21 02110-1301, USA. */ |
22 | 22 |
23 #include "sysdep.h" | 23 #include "sysdep.h" |
24 #include "bfd.h" | 24 #include "bfd.h" |
25 #include "bfdlink.h" | 25 #include "bfdlink.h" |
26 #include "libbfd.h" | 26 #include "libbfd.h" |
27 #include "elf-bfd.h" | 27 #include "elf-bfd.h" |
28 | |
29 static reloc_howto_type *elf_s390_reloc_type_lookup | |
30 PARAMS ((bfd *, bfd_reloc_code_real_type)); | |
31 static void elf_s390_info_to_howto | |
32 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); | |
33 static bfd_boolean elf_s390_is_local_label_name | |
34 PARAMS ((bfd *, const char *)); | |
35 static struct bfd_hash_entry *link_hash_newfunc | |
36 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); | |
37 static struct bfd_link_hash_table *elf_s390_link_hash_table_create | |
38 PARAMS ((bfd *)); | |
39 static bfd_boolean create_got_section | |
40 PARAMS((bfd *, struct bfd_link_info *)); | |
41 static bfd_boolean elf_s390_create_dynamic_sections | |
42 PARAMS((bfd *, struct bfd_link_info *)); | |
43 static void elf_s390_copy_indirect_symbol | |
44 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, | |
45 struct elf_link_hash_entry *)); | |
46 static bfd_boolean elf_s390_check_relocs | |
47 PARAMS ((bfd *, struct bfd_link_info *, asection *, | |
48 const Elf_Internal_Rela *)); | |
49 struct elf_s390_link_hash_entry; | |
50 static void elf_s390_adjust_gotplt | |
51 PARAMS ((struct elf_s390_link_hash_entry *)); | |
52 static bfd_boolean elf_s390_adjust_dynamic_symbol | |
53 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); | |
54 static bfd_boolean allocate_dynrelocs | |
55 PARAMS ((struct elf_link_hash_entry *, PTR)); | |
56 static bfd_boolean readonly_dynrelocs | |
57 PARAMS ((struct elf_link_hash_entry *, PTR)); | |
58 static bfd_boolean elf_s390_size_dynamic_sections | |
59 PARAMS ((bfd *, struct bfd_link_info *)); | |
60 static bfd_boolean elf_s390_relocate_section | |
61 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, | |
62 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); | |
63 static bfd_boolean elf_s390_finish_dynamic_symbol | |
64 PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, | |
65 Elf_Internal_Sym *)); | |
66 static enum elf_reloc_type_class elf_s390_reloc_type_class | |
67 PARAMS ((const Elf_Internal_Rela *)); | |
68 static bfd_boolean elf_s390_finish_dynamic_sections | |
69 PARAMS ((bfd *, struct bfd_link_info *)); | |
70 static bfd_boolean elf_s390_object_p | |
71 PARAMS ((bfd *)); | |
72 static int elf_s390_tls_transition | |
73 PARAMS ((struct bfd_link_info *, int, int)); | |
74 static bfd_reloc_status_type s390_tls_reloc | |
75 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); | |
76 static bfd_vma dtpoff_base | |
77 PARAMS ((struct bfd_link_info *)); | |
78 static bfd_vma tpoff | |
79 PARAMS ((struct bfd_link_info *, bfd_vma)); | |
80 static void invalid_tls_insn | |
81 PARAMS ((bfd *, asection *, Elf_Internal_Rela *)); | |
82 static bfd_reloc_status_type s390_elf_ldisp_reloc | |
83 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); | |
84 | |
85 #include "elf/s390.h" | 28 #include "elf/s390.h" |
86 | 29 |
87 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value | 30 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value |
88 from smaller values. Start with zero, widen, *then* decrement. */ | 31 from smaller values. Start with zero, widen, *then* decrement. */ |
89 #define MINUS_ONE (((bfd_vma)0) - 1) | 32 #define MINUS_ONE (((bfd_vma)0) - 1) |
90 | 33 |
| 34 static bfd_reloc_status_type |
| 35 s390_tls_reloc (bfd *, arelent *, asymbol *, void *, |
| 36 asection *, bfd *, char **); |
| 37 static bfd_reloc_status_type |
| 38 s390_elf_ldisp_reloc (bfd *, arelent *, asymbol *, void *, |
| 39 asection *, bfd *, char **); |
| 40 |
91 /* The relocation "howto" table. */ | 41 /* The relocation "howto" table. */ |
92 static reloc_howto_type elf_howto_table[] = | 42 static reloc_howto_type elf_howto_table[] = |
93 { | 43 { |
94 HOWTO (R_390_NONE, /* type */ | 44 HOWTO (R_390_NONE, /* type */ |
95 0, /* rightshift */ | 45 0, /* rightshift */ |
96 0, /* size (0 = byte, 1 = short, 2 = long) */ | 46 0, /* size (0 = byte, 1 = short, 2 = long) */ |
97 0, /* bitsize */ | 47 0, /* bitsize */ |
98 FALSE, /* pc_relative */ | 48 FALSE, /* pc_relative */ |
99 0, /* bitpos */ | 49 0, /* bitpos */ |
100 complain_overflow_dont, /* complain_on_overflow */ | 50 complain_overflow_dont, /* complain_on_overflow */ |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 HOWTO(R_390_TLS_TPOFF, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, | 162 HOWTO(R_390_TLS_TPOFF, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, |
213 bfd_elf_generic_reloc, "R_390_TLS_TPOFF", FALSE, 0, MINUS_ONE, FALSE), | 163 bfd_elf_generic_reloc, "R_390_TLS_TPOFF", FALSE, 0, MINUS_ONE, FALSE), |
214 HOWTO(R_390_20, 0, 2, 20, FALSE, 8, complain_overflow_dont, | 164 HOWTO(R_390_20, 0, 2, 20, FALSE, 8, complain_overflow_dont, |
215 s390_elf_ldisp_reloc, "R_390_20", FALSE, 0,0x0fffff00, FALSE), | 165 s390_elf_ldisp_reloc, "R_390_20", FALSE, 0,0x0fffff00, FALSE), |
216 HOWTO(R_390_GOT20, 0, 2, 20, FALSE, 8, complain_overflow_dont, | 166 HOWTO(R_390_GOT20, 0, 2, 20, FALSE, 8, complain_overflow_dont, |
217 s390_elf_ldisp_reloc, "R_390_GOT20", FALSE, 0,0x0fffff00, FALSE), | 167 s390_elf_ldisp_reloc, "R_390_GOT20", FALSE, 0,0x0fffff00, FALSE), |
218 HOWTO(R_390_GOTPLT20, 0, 2, 20, FALSE, 8, complain_overflow_dont, | 168 HOWTO(R_390_GOTPLT20, 0, 2, 20, FALSE, 8, complain_overflow_dont, |
219 s390_elf_ldisp_reloc, "R_390_GOTPLT20", FALSE, 0,0x0fffff00, FALSE), | 169 s390_elf_ldisp_reloc, "R_390_GOTPLT20", FALSE, 0,0x0fffff00, FALSE), |
220 HOWTO(R_390_TLS_GOTIE20, 0, 2, 20, FALSE, 8, complain_overflow_dont, | 170 HOWTO(R_390_TLS_GOTIE20, 0, 2, 20, FALSE, 8, complain_overflow_dont, |
221 s390_elf_ldisp_reloc, "R_390_TLS_GOTIE20", FALSE, 0,0x0fffff00, FALSE), | 171 s390_elf_ldisp_reloc, "R_390_TLS_GOTIE20", FALSE, 0,0x0fffff00, FALSE), |
| 172 HOWTO(R_390_IRELATIVE, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, |
| 173 bfd_elf_generic_reloc, "R_390_IRELATIVE", FALSE, 0, MINUS_ONE, FALSE), |
| 174 |
222 }; | 175 }; |
223 | 176 |
224 /* GNU extension to record C++ vtable hierarchy. */ | 177 /* GNU extension to record C++ vtable hierarchy. */ |
225 static reloc_howto_type elf64_s390_vtinherit_howto = | 178 static reloc_howto_type elf64_s390_vtinherit_howto = |
226 HOWTO (R_390_GNU_VTINHERIT, 0,4,0,FALSE,0,complain_overflow_dont, NULL, "R_390
_GNU_VTINHERIT", FALSE,0, 0, FALSE); | 179 HOWTO (R_390_GNU_VTINHERIT, 0,4,0,FALSE,0,complain_overflow_dont, NULL, "R_390
_GNU_VTINHERIT", FALSE,0, 0, FALSE); |
227 static reloc_howto_type elf64_s390_vtentry_howto = | 180 static reloc_howto_type elf64_s390_vtentry_howto = |
228 HOWTO (R_390_GNU_VTENTRY, 0,4,0,FALSE,0,complain_overflow_dont, _bfd_elf_rel_v
table_reloc_fn,"R_390_GNU_VTENTRY", FALSE,0,0, FALSE); | 181 HOWTO (R_390_GNU_VTENTRY, 0,4,0,FALSE,0,complain_overflow_dont, _bfd_elf_rel_v
table_reloc_fn,"R_390_GNU_VTENTRY", FALSE,0,0, FALSE); |
229 | 182 |
230 static reloc_howto_type * | 183 static reloc_howto_type * |
231 elf_s390_reloc_type_lookup (abfd, code) | 184 elf_s390_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, |
232 bfd *abfd ATTRIBUTE_UNUSED; | 185 » » » bfd_reloc_code_real_type code) |
233 bfd_reloc_code_real_type code; | |
234 { | 186 { |
235 switch (code) | 187 switch (code) |
236 { | 188 { |
237 case BFD_RELOC_NONE: | 189 case BFD_RELOC_NONE: |
238 return &elf_howto_table[(int) R_390_NONE]; | 190 return &elf_howto_table[(int) R_390_NONE]; |
239 case BFD_RELOC_8: | 191 case BFD_RELOC_8: |
240 return &elf_howto_table[(int) R_390_8]; | 192 return &elf_howto_table[(int) R_390_8]; |
241 case BFD_RELOC_390_12: | 193 case BFD_RELOC_390_12: |
242 return &elf_howto_table[(int) R_390_12]; | 194 return &elf_howto_table[(int) R_390_12]; |
243 case BFD_RELOC_16: | 195 case BFD_RELOC_16: |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 case BFD_RELOC_390_TLS_TPOFF: | 291 case BFD_RELOC_390_TLS_TPOFF: |
340 return &elf_howto_table[(int) R_390_TLS_TPOFF]; | 292 return &elf_howto_table[(int) R_390_TLS_TPOFF]; |
341 case BFD_RELOC_390_20: | 293 case BFD_RELOC_390_20: |
342 return &elf_howto_table[(int) R_390_20]; | 294 return &elf_howto_table[(int) R_390_20]; |
343 case BFD_RELOC_390_GOT20: | 295 case BFD_RELOC_390_GOT20: |
344 return &elf_howto_table[(int) R_390_GOT20]; | 296 return &elf_howto_table[(int) R_390_GOT20]; |
345 case BFD_RELOC_390_GOTPLT20: | 297 case BFD_RELOC_390_GOTPLT20: |
346 return &elf_howto_table[(int) R_390_GOTPLT20]; | 298 return &elf_howto_table[(int) R_390_GOTPLT20]; |
347 case BFD_RELOC_390_TLS_GOTIE20: | 299 case BFD_RELOC_390_TLS_GOTIE20: |
348 return &elf_howto_table[(int) R_390_TLS_GOTIE20]; | 300 return &elf_howto_table[(int) R_390_TLS_GOTIE20]; |
| 301 case BFD_RELOC_390_IRELATIVE: |
| 302 return &elf_howto_table[(int) R_390_IRELATIVE]; |
349 case BFD_RELOC_VTABLE_INHERIT: | 303 case BFD_RELOC_VTABLE_INHERIT: |
350 return &elf64_s390_vtinherit_howto; | 304 return &elf64_s390_vtinherit_howto; |
351 case BFD_RELOC_VTABLE_ENTRY: | 305 case BFD_RELOC_VTABLE_ENTRY: |
352 return &elf64_s390_vtentry_howto; | 306 return &elf64_s390_vtentry_howto; |
353 default: | 307 default: |
354 break; | 308 break; |
355 } | 309 } |
356 return 0; | 310 return 0; |
357 } | 311 } |
358 | 312 |
(...skipping 15 matching lines...) Expand all Loading... |
374 if (strcasecmp (elf64_s390_vtentry_howto.name, r_name) == 0) | 328 if (strcasecmp (elf64_s390_vtentry_howto.name, r_name) == 0) |
375 return &elf64_s390_vtentry_howto; | 329 return &elf64_s390_vtentry_howto; |
376 | 330 |
377 return NULL; | 331 return NULL; |
378 } | 332 } |
379 | 333 |
380 /* We need to use ELF64_R_TYPE so we have our own copy of this function, | 334 /* We need to use ELF64_R_TYPE so we have our own copy of this function, |
381 and elf64-s390.c has its own copy. */ | 335 and elf64-s390.c has its own copy. */ |
382 | 336 |
383 static void | 337 static void |
384 elf_s390_info_to_howto (abfd, cache_ptr, dst) | 338 elf_s390_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, |
385 bfd *abfd ATTRIBUTE_UNUSED; | 339 » » » arelent *cache_ptr, |
386 arelent *cache_ptr; | 340 » » » Elf_Internal_Rela *dst) |
387 Elf_Internal_Rela *dst; | |
388 { | 341 { |
389 unsigned int r_type = ELF64_R_TYPE(dst->r_info); | 342 unsigned int r_type = ELF64_R_TYPE(dst->r_info); |
390 switch (r_type) | 343 switch (r_type) |
391 { | 344 { |
392 case R_390_GNU_VTINHERIT: | 345 case R_390_GNU_VTINHERIT: |
393 cache_ptr->howto = &elf64_s390_vtinherit_howto; | 346 cache_ptr->howto = &elf64_s390_vtinherit_howto; |
394 break; | 347 break; |
395 | 348 |
396 case R_390_GNU_VTENTRY: | 349 case R_390_GNU_VTENTRY: |
397 cache_ptr->howto = &elf64_s390_vtentry_howto; | 350 cache_ptr->howto = &elf64_s390_vtentry_howto; |
398 break; | 351 break; |
399 | 352 |
400 default: | 353 default: |
401 if (r_type >= sizeof (elf_howto_table) / sizeof (elf_howto_table[0])) | 354 if (r_type >= sizeof (elf_howto_table) / sizeof (elf_howto_table[0])) |
402 { | 355 { |
403 (*_bfd_error_handler) (_("%B: invalid relocation type %d"), | 356 (*_bfd_error_handler) (_("%B: invalid relocation type %d"), |
404 abfd, (int) r_type); | 357 abfd, (int) r_type); |
405 r_type = R_390_NONE; | 358 r_type = R_390_NONE; |
406 } | 359 } |
407 cache_ptr->howto = &elf_howto_table[r_type]; | 360 cache_ptr->howto = &elf_howto_table[r_type]; |
408 } | 361 } |
409 } | 362 } |
410 | 363 |
411 /* A relocation function which doesn't do anything. */ | 364 /* A relocation function which doesn't do anything. */ |
412 static bfd_reloc_status_type | 365 static bfd_reloc_status_type |
413 s390_tls_reloc (abfd, reloc_entry, symbol, data, input_section, | 366 s390_tls_reloc (bfd *abfd ATTRIBUTE_UNUSED, |
414 » » output_bfd, error_message) | 367 » » arelent *reloc_entry, |
415 bfd *abfd ATTRIBUTE_UNUSED; | 368 » » asymbol *symbol ATTRIBUTE_UNUSED, |
416 arelent *reloc_entry; | 369 » » void * data ATTRIBUTE_UNUSED, |
417 asymbol *symbol ATTRIBUTE_UNUSED; | 370 » » asection *input_section, |
418 PTR data ATTRIBUTE_UNUSED; | 371 » » bfd *output_bfd, |
419 asection *input_section; | 372 » » char **error_message ATTRIBUTE_UNUSED) |
420 bfd *output_bfd; | |
421 char **error_message ATTRIBUTE_UNUSED; | |
422 { | 373 { |
423 if (output_bfd) | 374 if (output_bfd) |
424 reloc_entry->address += input_section->output_offset; | 375 reloc_entry->address += input_section->output_offset; |
425 return bfd_reloc_ok; | 376 return bfd_reloc_ok; |
426 } | 377 } |
427 | 378 |
428 /* Handle the large displacement relocs. */ | 379 /* Handle the large displacement relocs. */ |
429 static bfd_reloc_status_type | 380 static bfd_reloc_status_type |
430 s390_elf_ldisp_reloc (abfd, reloc_entry, symbol, data, input_section, | 381 s390_elf_ldisp_reloc (bfd *abfd, |
431 output_bfd, error_message) | 382 » » arelent *reloc_entry, |
432 bfd *abfd; | 383 » » asymbol *symbol, |
433 arelent *reloc_entry; | 384 » » void * data, |
434 asymbol *symbol; | 385 » » asection *input_section, |
435 PTR data; | 386 » » bfd *output_bfd, |
436 asection *input_section; | 387 » » char **error_message ATTRIBUTE_UNUSED) |
437 bfd *output_bfd; | |
438 char **error_message ATTRIBUTE_UNUSED; | |
439 { | 388 { |
440 reloc_howto_type *howto = reloc_entry->howto; | 389 reloc_howto_type *howto = reloc_entry->howto; |
441 bfd_vma relocation; | 390 bfd_vma relocation; |
442 bfd_vma insn; | 391 bfd_vma insn; |
443 | 392 |
444 if (output_bfd != (bfd *) NULL | 393 if (output_bfd != (bfd *) NULL |
445 && (symbol->flags & BSF_SECTION_SYM) == 0 | 394 && (symbol->flags & BSF_SECTION_SYM) == 0 |
446 && (! howto->partial_inplace | 395 && (! howto->partial_inplace |
447 || reloc_entry->addend == 0)) | 396 || reloc_entry->addend == 0)) |
448 { | 397 { |
(...skipping 22 matching lines...) Expand all Loading... |
471 bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address); | 420 bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address); |
472 | 421 |
473 if ((bfd_signed_vma) relocation < - 0x80000 | 422 if ((bfd_signed_vma) relocation < - 0x80000 |
474 || (bfd_signed_vma) relocation > 0x7ffff) | 423 || (bfd_signed_vma) relocation > 0x7ffff) |
475 return bfd_reloc_overflow; | 424 return bfd_reloc_overflow; |
476 else | 425 else |
477 return bfd_reloc_ok; | 426 return bfd_reloc_ok; |
478 } | 427 } |
479 | 428 |
480 static bfd_boolean | 429 static bfd_boolean |
481 elf_s390_is_local_label_name (abfd, name) | 430 elf_s390_is_local_label_name (bfd *abfd, const char *name) |
482 bfd *abfd; | |
483 const char *name; | |
484 { | 431 { |
485 if (name[0] == '.' && (name[1] == 'X' || name[1] == 'L')) | 432 if (name[0] == '.' && (name[1] == 'X' || name[1] == 'L')) |
486 return TRUE; | 433 return TRUE; |
487 | 434 |
488 return _bfd_elf_is_local_label_name (abfd, name); | 435 return _bfd_elf_is_local_label_name (abfd, name); |
489 } | 436 } |
490 | 437 |
491 /* Functions for the 390 ELF linker. */ | 438 /* Functions for the 390 ELF linker. */ |
492 | 439 |
493 /* The name of the dynamic interpreter. This is put in the .interp | 440 /* The name of the dynamic interpreter. This is put in the .interp |
494 section. */ | 441 section. */ |
495 | 442 |
496 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1" | 443 #define ELF_DYNAMIC_INTERPRETER "/lib/ld64.so.1" |
497 | 444 |
498 /* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid | 445 /* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid |
499 copying dynamic variables from a shared lib into an app's dynbss | 446 copying dynamic variables from a shared lib into an app's dynbss |
500 section, and instead use a dynamic relocation to point into the | 447 section, and instead use a dynamic relocation to point into the |
501 shared lib. */ | 448 shared lib. */ |
502 #define ELIMINATE_COPY_RELOCS 1 | 449 #define ELIMINATE_COPY_RELOCS 1 |
503 | 450 |
504 /* The size in bytes of the first entry in the procedure linkage table. */ | 451 /* The size in bytes of the first entry in the procedure linkage table. */ |
505 #define PLT_FIRST_ENTRY_SIZE 32 | 452 #define PLT_FIRST_ENTRY_SIZE 32 |
506 /* The size in bytes of an entry in the procedure linkage table. */ | 453 /* The size in bytes of an entry in the procedure linkage table. */ |
507 #define PLT_ENTRY_SIZE 32 | 454 #define PLT_ENTRY_SIZE 32 |
508 | 455 |
509 #define GOT_ENTRY_SIZE 8 | 456 #define GOT_ENTRY_SIZE 8 |
510 | 457 |
| 458 #define RELA_ENTRY_SIZE sizeof (Elf64_External_Rela) |
| 459 |
511 /* The first three entries in a procedure linkage table are reserved, | 460 /* The first three entries in a procedure linkage table are reserved, |
512 and the initial contents are unimportant (we zero them out). | 461 and the initial contents are unimportant (we zero them out). |
513 Subsequent entries look like this. See the SVR4 ABI 386 | 462 Subsequent entries look like this. See the SVR4 ABI 386 |
514 supplement to see how this works. */ | 463 supplement to see how this works. */ |
515 | 464 |
516 /* For the s390, simple addr offset can only be 0 - 4096. | 465 /* For the s390, simple addr offset can only be 0 - 4096. |
517 To use the full 16777216 TB address space, several instructions | 466 To use the full 16777216 TB address space, several instructions |
518 are needed to load an address in a register and execute | 467 are needed to load an address in a register and execute |
519 a branch( or just saving the address) | 468 a branch( or just saving the address) |
520 | 469 |
(...skipping 12 matching lines...) Expand all Loading... |
533 28(15) = Offset in symbol table | 482 28(15) = Offset in symbol table |
534 The loader must then find the module where the function is | 483 The loader must then find the module where the function is |
535 and insert the address in the GOT. | 484 and insert the address in the GOT. |
536 | 485 |
537 PLT1: LARL 1,<fn>@GOTENT # 6 bytes Load address of GOT entry in r1 | 486 PLT1: LARL 1,<fn>@GOTENT # 6 bytes Load address of GOT entry in r1 |
538 LG 1,0(1) # 6 bytes Load address from GOT in r1 | 487 LG 1,0(1) # 6 bytes Load address from GOT in r1 |
539 BCR 15,1 # 2 bytes Jump to address | 488 BCR 15,1 # 2 bytes Jump to address |
540 RET1: BASR 1,0 # 2 bytes Return from GOT 1st time | 489 RET1: BASR 1,0 # 2 bytes Return from GOT 1st time |
541 LGF 1,12(1) # 6 bytes Load offset in symbl table in r1 | 490 LGF 1,12(1) # 6 bytes Load offset in symbl table in r1 |
542 BRCL 15,-x # 6 bytes Jump to start of PLT | 491 BRCL 15,-x # 6 bytes Jump to start of PLT |
543 .long ? # 4 bytes offset into symbol table | 492 .long ? # 4 bytes offset into .rela.plt |
544 | 493 |
545 Total = 32 bytes per PLT entry | 494 Total = 32 bytes per PLT entry |
546 Fixup at offset 2: relative address to GOT entry | 495 Fixup at offset 2: relative address to GOT entry |
547 Fixup at offset 22: relative branch to PLT0 | 496 Fixup at offset 22: relative branch to PLT0 |
548 Fixup at offset 28: 32 bit offset into symbol table | 497 Fixup at offset 28: 32 bit offset into .rela.plt |
549 | 498 |
550 A 32 bit offset into the symbol table is enough. It allows for symbol | 499 A 32 bit offset into the symbol table is enough. It allows for |
551 tables up to a size of 2 gigabyte. A single dynamic object (the main | 500 .rela.plt sections up to a size of 2 gigabyte. A single dynamic |
552 program, any shared library) is limited to 4GB in size and I want to see | 501 object (the main program, any shared library) is limited to 4GB in |
553 the program that manages to have a symbol table of more than 2 GB with a | 502 size. Having a .rela.plt of 2GB would already make the .plt |
554 total size of at max 4 GB. */ | 503 section bigger than 8GB. */ |
555 | 504 |
556 #define PLT_ENTRY_WORD0 (bfd_vma) 0xc0100000 | 505 static const bfd_byte elf_s390x_plt_entry[PLT_ENTRY_SIZE] = |
557 #define PLT_ENTRY_WORD1 (bfd_vma) 0x0000e310 | 506 { |
558 #define PLT_ENTRY_WORD2 (bfd_vma) 0x10000004 | 507 0xc0, 0x10, 0x00, 0x00, 0x00, 0x00, /* larl %r1,. */ |
559 #define PLT_ENTRY_WORD3 (bfd_vma) 0x07f10d10 | 508 0xe3, 0x10, 0x10, 0x00, 0x00, 0x04, /* lg %r1,0(%r1) */ |
560 #define PLT_ENTRY_WORD4 (bfd_vma) 0xe310100c | 509 0x07, 0xf1, /* br %r1 */ |
561 #define PLT_ENTRY_WORD5 (bfd_vma) 0x0014c0f4 | 510 0x0d, 0x10, /* basr %r1,%r0 */ |
562 #define PLT_ENTRY_WORD6 (bfd_vma) 0x00000000 | 511 0xe3, 0x10, 0x10, 0x0c, 0x00, 0x14, /* lgf %r1,12(%r1) */ |
563 #define PLT_ENTRY_WORD7 (bfd_vma) 0x00000000 | 512 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg first plt */ |
| 513 0x00, 0x00, 0x00, 0x00 /* .long 0x00000000 */ |
| 514 }; |
564 | 515 |
565 /* The first PLT entry pushes the offset into the symbol table | 516 /* The first PLT entry pushes the offset into the symbol table |
566 from R1 onto the stack at 8(15) and the loader object info | 517 from R1 onto the stack at 56(15) and the loader object info |
567 at 12(15), loads the loader address in R1 and jumps to it. */ | 518 at 48(15), loads the loader address in R1 and jumps to it. */ |
568 | 519 |
569 /* The first entry in the PLT: | 520 /* The first entry in the PLT: |
570 | 521 |
571 PLT0: | 522 PLT0: |
572 STG 1,56(15) # r1 contains the offset into the symbol table | 523 STG 1,56(15) # r1 contains the offset into the symbol table |
573 LARL 1,_GLOBAL_OFFSET_TABLE # load address of global offset table | 524 LARL 1,_GLOBAL_OFFSET_TABLE # load address of global offset table |
574 MVC 48(8,15),8(1) # move loader ino (object struct address) to stack | 525 MVC 48(8,15),8(1) # move loader ino (object struct address) to stack |
575 LG 1,16(1) # get entry address of loader | 526 LG 1,16(1) # get entry address of loader |
576 BCR 15,1 # jump to loader | 527 BCR 15,1 # jump to loader |
577 | 528 |
578 Fixup at offset 8: relative address to start of GOT. */ | 529 Fixup at offset 8: relative address to start of GOT. */ |
579 | 530 |
580 #define PLT_FIRST_ENTRY_WORD0 (bfd_vma) 0xe310f038 | 531 static const bfd_byte elf_s390x_first_plt_entry[PLT_FIRST_ENTRY_SIZE] = |
581 #define PLT_FIRST_ENTRY_WORD1 (bfd_vma) 0x0024c010 | 532 { |
582 #define PLT_FIRST_ENTRY_WORD2 (bfd_vma) 0x00000000 | 533 0xe3, 0x10, 0xf0, 0x38, 0x00, 0x24, /* stg %r1,56(%r15) */ |
583 #define PLT_FIRST_ENTRY_WORD3 (bfd_vma) 0xd207f030 | 534 0xc0, 0x10, 0x00, 0x00, 0x00, 0x00, /* larl %r1,. */ |
584 #define PLT_FIRST_ENTRY_WORD4 (bfd_vma) 0x1008e310 | 535 0xd2, 0x07, 0xf0, 0x30, 0x10, 0x08, /* mvc 48(8,%r15),8(%r1) */ |
585 #define PLT_FIRST_ENTRY_WORD5 (bfd_vma) 0x10100004 | 536 0xe3, 0x10, 0x10, 0x10, 0x00, 0x04, /* lg %r1,16(%r1) */ |
586 #define PLT_FIRST_ENTRY_WORD6 (bfd_vma) 0x07f10700 | 537 0x07, 0xf1, /* br %r1 */ |
587 #define PLT_FIRST_ENTRY_WORD7 (bfd_vma) 0x07000700 | 538 0x07, 0x00, /* nopr %r0 */ |
| 539 0x07, 0x00, /* nopr %r0 */ |
| 540 0x07, 0x00 /* nopr %r0 */ |
| 541 }; |
588 | 542 |
589 /* The s390 linker needs to keep track of the number of relocs that it | |
590 decides to copy as dynamic relocs in check_relocs for each symbol. | |
591 This is so that it can later discard them if they are found to be | |
592 unnecessary. We store the information in a field extending the | |
593 regular ELF linker hash table. */ | |
594 | |
595 struct elf_s390_dyn_relocs | |
596 { | |
597 struct elf_s390_dyn_relocs *next; | |
598 | |
599 /* The input section of the reloc. */ | |
600 asection *sec; | |
601 | |
602 /* Total number of relocs copied for the input section. */ | |
603 bfd_size_type count; | |
604 | |
605 /* Number of pc-relative relocs copied for the input section. */ | |
606 bfd_size_type pc_count; | |
607 }; | |
608 | 543 |
609 /* s390 ELF linker hash entry. */ | 544 /* s390 ELF linker hash entry. */ |
610 | 545 |
611 struct elf_s390_link_hash_entry | 546 struct elf_s390_link_hash_entry |
612 { | 547 { |
613 struct elf_link_hash_entry elf; | 548 struct elf_link_hash_entry elf; |
614 | 549 |
615 /* Track dynamic relocs copied for this symbol. */ | 550 /* Track dynamic relocs copied for this symbol. */ |
616 struct elf_s390_dyn_relocs *dyn_relocs; | 551 struct elf_dyn_relocs *dyn_relocs; |
617 | 552 |
618 /* Number of GOTPLT references for a function. */ | 553 /* Number of GOTPLT references for a function. */ |
619 bfd_signed_vma gotplt_refcount; | 554 bfd_signed_vma gotplt_refcount; |
620 | 555 |
621 #define GOT_UNKNOWN 0 | 556 #define GOT_UNKNOWN 0 |
622 #define GOT_NORMAL 1 | 557 #define GOT_NORMAL 1 |
623 #define GOT_TLS_GD 2 | 558 #define GOT_TLS_GD 2 |
624 #define GOT_TLS_IE 3 | 559 #define GOT_TLS_IE 3 |
625 #define GOT_TLS_IE_NLT 3 | 560 #define GOT_TLS_IE_NLT 3 |
626 unsigned char tls_type; | 561 unsigned char tls_type; |
| 562 |
| 563 /* For pointer equality reasons we might need to change the symbol |
| 564 type from STT_GNU_IFUNC to STT_FUNC together with its value and |
| 565 section entry. So after alloc_dynrelocs only these values should |
| 566 be used. In order to check whether a symbol is IFUNC use |
| 567 s390_is_ifunc_symbol_p. */ |
| 568 bfd_vma ifunc_resolver_address; |
| 569 asection *ifunc_resolver_section; |
627 }; | 570 }; |
628 | 571 |
629 #define elf_s390_hash_entry(ent) \ | 572 #define elf_s390_hash_entry(ent) \ |
630 ((struct elf_s390_link_hash_entry *)(ent)) | 573 ((struct elf_s390_link_hash_entry *)(ent)) |
631 | 574 |
| 575 /* This structure represents an entry in the local PLT list needed for |
| 576 local IFUNC symbols. */ |
| 577 struct plt_entry |
| 578 { |
| 579 /* The section of the local symbol. |
| 580 Set in relocate_section and used in finish_dynamic_sections. */ |
| 581 asection *sec; |
| 582 |
| 583 union |
| 584 { |
| 585 bfd_signed_vma refcount; |
| 586 bfd_vma offset; |
| 587 } plt; |
| 588 }; |
| 589 |
632 /* NOTE: Keep this structure in sync with | 590 /* NOTE: Keep this structure in sync with |
633 the one declared in elf32-s390.c. */ | 591 the one declared in elf32-s390.c. */ |
634 struct elf_s390_obj_tdata | 592 struct elf_s390_obj_tdata |
635 { | 593 { |
636 struct elf_obj_tdata root; | 594 struct elf_obj_tdata root; |
637 | 595 |
| 596 /* A local PLT is needed for ifunc symbols. */ |
| 597 struct plt_entry *local_plt; |
| 598 |
638 /* TLS type for each local got entry. */ | 599 /* TLS type for each local got entry. */ |
639 char *local_got_tls_type; | 600 char *local_got_tls_type; |
640 }; | 601 }; |
641 | 602 |
642 #define elf_s390_tdata(abfd) \ | 603 #define elf_s390_tdata(abfd) \ |
643 ((struct elf_s390_obj_tdata *) (abfd)->tdata.any) | 604 ((struct elf_s390_obj_tdata *) (abfd)->tdata.any) |
644 | 605 |
| 606 #define elf_s390_local_plt(abfd) \ |
| 607 (elf_s390_tdata (abfd)->local_plt) |
| 608 |
645 #define elf_s390_local_got_tls_type(abfd) \ | 609 #define elf_s390_local_got_tls_type(abfd) \ |
646 (elf_s390_tdata (abfd)->local_got_tls_type) | 610 (elf_s390_tdata (abfd)->local_got_tls_type) |
647 | 611 |
648 #define is_s390_elf(bfd) \ | 612 #define is_s390_elf(bfd) \ |
649 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \ | 613 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \ |
650 && elf_tdata (bfd) != NULL \ | 614 && elf_tdata (bfd) != NULL \ |
651 && elf_object_id (bfd) == S390_ELF_DATA) | 615 && elf_object_id (bfd) == S390_ELF_DATA) |
652 | 616 |
653 static bfd_boolean | 617 static bfd_boolean |
654 elf_s390_mkobject (bfd *abfd) | 618 elf_s390_mkobject (bfd *abfd) |
655 { | 619 { |
656 return bfd_elf_allocate_object (abfd, sizeof (struct elf_s390_obj_tdata), | 620 return bfd_elf_allocate_object (abfd, sizeof (struct elf_s390_obj_tdata), |
657 S390_ELF_DATA); | 621 S390_ELF_DATA); |
658 } | 622 } |
659 | 623 |
660 static bfd_boolean | 624 static bfd_boolean |
661 elf_s390_object_p (abfd) | 625 elf_s390_object_p (bfd *abfd) |
662 bfd *abfd; | |
663 { | 626 { |
664 /* Set the right machine number for an s390 elf32 file. */ | 627 /* Set the right machine number for an s390 elf32 file. */ |
665 return bfd_default_set_arch_mach (abfd, bfd_arch_s390, bfd_mach_s390_64); | 628 return bfd_default_set_arch_mach (abfd, bfd_arch_s390, bfd_mach_s390_64); |
666 } | 629 } |
667 | 630 |
668 /* s390 ELF linker hash table. */ | 631 /* s390 ELF linker hash table. */ |
669 | 632 |
670 struct elf_s390_link_hash_table | 633 struct elf_s390_link_hash_table |
671 { | 634 { |
672 struct elf_link_hash_table elf; | 635 struct elf_link_hash_table elf; |
673 | 636 |
674 /* Short-cuts to get to dynamic linker sections. */ | 637 /* Short-cuts to get to dynamic linker sections. */ |
675 asection *sgot; | |
676 asection *sgotplt; | |
677 asection *srelgot; | |
678 asection *splt; | |
679 asection *srelplt; | |
680 asection *sdynbss; | 638 asection *sdynbss; |
681 asection *srelbss; | 639 asection *srelbss; |
| 640 asection *irelifunc; |
682 | 641 |
683 union { | 642 union { |
684 bfd_signed_vma refcount; | 643 bfd_signed_vma refcount; |
685 bfd_vma offset; | 644 bfd_vma offset; |
686 } tls_ldm_got; | 645 } tls_ldm_got; |
687 | 646 |
688 /* Small local sym cache. */ | 647 /* Small local sym cache. */ |
689 struct sym_cache sym_cache; | 648 struct sym_cache sym_cache; |
690 }; | 649 }; |
691 | 650 |
692 /* Get the s390 ELF linker hash table from a link_info structure. */ | 651 /* Get the s390 ELF linker hash table from a link_info structure. */ |
693 | 652 |
694 #define elf_s390_hash_table(p) \ | 653 #define elf_s390_hash_table(p) \ |
695 (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \ | 654 (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \ |
696 == S390_ELF_DATA ? ((struct elf_s390_link_hash_table *) ((p)->hash)) : NULL) | 655 == S390_ELF_DATA ? ((struct elf_s390_link_hash_table *) ((p)->hash)) : NULL) |
697 | 656 |
| 657 #define ELF64 1 |
| 658 #include "elf-s390-common.c" |
| 659 |
698 /* Create an entry in an s390 ELF linker hash table. */ | 660 /* Create an entry in an s390 ELF linker hash table. */ |
699 | 661 |
700 static struct bfd_hash_entry * | 662 static struct bfd_hash_entry * |
701 link_hash_newfunc (entry, table, string) | 663 link_hash_newfunc (struct bfd_hash_entry *entry, |
702 struct bfd_hash_entry *entry; | 664 » » struct bfd_hash_table *table, |
703 struct bfd_hash_table *table; | 665 » » const char *string) |
704 const char *string; | |
705 { | 666 { |
706 /* Allocate the structure if it has not already been allocated by a | 667 /* Allocate the structure if it has not already been allocated by a |
707 subclass. */ | 668 subclass. */ |
708 if (entry == NULL) | 669 if (entry == NULL) |
709 { | 670 { |
710 entry = bfd_hash_allocate (table, | 671 entry = bfd_hash_allocate (table, |
711 sizeof (struct elf_s390_link_hash_entry)); | 672 sizeof (struct elf_s390_link_hash_entry)); |
712 if (entry == NULL) | 673 if (entry == NULL) |
713 return entry; | 674 return entry; |
714 } | 675 } |
715 | 676 |
716 /* Call the allocation method of the superclass. */ | 677 /* Call the allocation method of the superclass. */ |
717 entry = _bfd_elf_link_hash_newfunc (entry, table, string); | 678 entry = _bfd_elf_link_hash_newfunc (entry, table, string); |
718 if (entry != NULL) | 679 if (entry != NULL) |
719 { | 680 { |
720 struct elf_s390_link_hash_entry *eh; | 681 struct elf_s390_link_hash_entry *eh; |
721 | 682 |
722 eh = (struct elf_s390_link_hash_entry *) entry; | 683 eh = (struct elf_s390_link_hash_entry *) entry; |
723 eh->dyn_relocs = NULL; | 684 eh->dyn_relocs = NULL; |
724 eh->gotplt_refcount = 0; | 685 eh->gotplt_refcount = 0; |
725 eh->tls_type = GOT_UNKNOWN; | 686 eh->tls_type = GOT_UNKNOWN; |
| 687 eh->ifunc_resolver_address = 0; |
| 688 eh->ifunc_resolver_section = NULL; |
726 } | 689 } |
727 | 690 |
728 return entry; | 691 return entry; |
729 } | 692 } |
730 | 693 |
731 /* Create an s390 ELF linker hash table. */ | 694 /* Create an s390 ELF linker hash table. */ |
732 | 695 |
733 static struct bfd_link_hash_table * | 696 static struct bfd_link_hash_table * |
734 elf_s390_link_hash_table_create (abfd) | 697 elf_s390_link_hash_table_create (bfd *abfd) |
735 bfd *abfd; | |
736 { | 698 { |
737 struct elf_s390_link_hash_table *ret; | 699 struct elf_s390_link_hash_table *ret; |
738 bfd_size_type amt = sizeof (struct elf_s390_link_hash_table); | 700 bfd_size_type amt = sizeof (struct elf_s390_link_hash_table); |
739 | 701 |
740 ret = (struct elf_s390_link_hash_table *) bfd_malloc (amt); | 702 ret = (struct elf_s390_link_hash_table *) bfd_malloc (amt); |
741 if (ret == NULL) | 703 if (ret == NULL) |
742 return NULL; | 704 return NULL; |
743 | 705 |
744 if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc, | 706 if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc, |
745 sizeof (struct elf_s390_link_hash_entry), | 707 sizeof (struct elf_s390_link_hash_entry), |
746 S390_ELF_DATA)) | 708 S390_ELF_DATA)) |
747 { | 709 { |
748 free (ret); | 710 free (ret); |
749 return NULL; | 711 return NULL; |
750 } | 712 } |
751 | 713 |
752 ret->sgot = NULL; | 714 ret->elf.sgot = NULL; |
753 ret->sgotplt = NULL; | 715 ret->elf.sgotplt = NULL; |
754 ret->srelgot = NULL; | 716 ret->elf.srelgot = NULL; |
755 ret->splt = NULL; | 717 ret->elf.splt = NULL; |
756 ret->srelplt = NULL; | 718 ret->elf.srelplt = NULL; |
757 ret->sdynbss = NULL; | 719 ret->sdynbss = NULL; |
758 ret->srelbss = NULL; | 720 ret->srelbss = NULL; |
759 ret->tls_ldm_got.refcount = 0; | 721 ret->tls_ldm_got.refcount = 0; |
760 ret->sym_cache.abfd = NULL; | 722 ret->sym_cache.abfd = NULL; |
761 | 723 |
762 return &ret->elf.root; | 724 return &ret->elf.root; |
763 } | 725 } |
764 | 726 |
765 /* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up | 727 /* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up |
766 shortcuts to them in our hash table. */ | 728 shortcuts to them in our hash table. */ |
767 | 729 |
768 static bfd_boolean | 730 static bfd_boolean |
769 create_got_section (bfd *dynobj, | 731 create_got_section (bfd *dynobj, |
770 struct bfd_link_info *info) | 732 struct bfd_link_info *info) |
771 { | 733 { |
772 struct elf_s390_link_hash_table *htab; | 734 struct elf_s390_link_hash_table *htab; |
773 | 735 |
774 if (! _bfd_elf_create_got_section (dynobj, info)) | 736 if (! _bfd_elf_create_got_section (dynobj, info)) |
775 return FALSE; | 737 return FALSE; |
776 | 738 |
777 htab = elf_s390_hash_table (info); | 739 htab = elf_s390_hash_table (info); |
778 if (htab == NULL) | 740 if (htab == NULL) |
779 return FALSE; | 741 return FALSE; |
780 | 742 |
781 htab->sgot = bfd_get_section_by_name (dynobj, ".got"); | 743 htab->elf.sgot = bfd_get_linker_section (dynobj, ".got"); |
782 htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt"); | 744 htab->elf.sgotplt = bfd_get_linker_section (dynobj, ".got.plt"); |
783 htab->srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); | 745 htab->elf.srelgot = bfd_get_linker_section (dynobj, ".rela.got"); |
784 if (!htab->sgot || !htab->sgotplt || !htab->srelgot) | 746 if (!htab->elf.sgot || !htab->elf.sgotplt || !htab->elf.srelgot) |
785 abort (); | 747 abort (); |
786 return TRUE; | 748 return TRUE; |
787 } | 749 } |
788 | 750 |
789 /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and | 751 /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and |
790 .rela.bss sections in DYNOBJ, and set up shortcuts to them in our | 752 .rela.bss sections in DYNOBJ, and set up shortcuts to them in our |
791 hash table. */ | 753 hash table. */ |
792 | 754 |
793 static bfd_boolean | 755 static bfd_boolean |
794 elf_s390_create_dynamic_sections (bfd *dynobj, | 756 elf_s390_create_dynamic_sections (bfd *dynobj, |
795 struct bfd_link_info *info) | 757 struct bfd_link_info *info) |
796 { | 758 { |
797 struct elf_s390_link_hash_table *htab; | 759 struct elf_s390_link_hash_table *htab; |
798 | 760 |
799 htab = elf_s390_hash_table (info); | 761 htab = elf_s390_hash_table (info); |
800 if (htab == NULL) | 762 if (htab == NULL) |
801 return FALSE; | 763 return FALSE; |
802 | 764 |
803 if (!htab->sgot && !create_got_section (dynobj, info)) | 765 if (!htab->elf.sgot && !create_got_section (dynobj, info)) |
804 return FALSE; | 766 return FALSE; |
805 | 767 |
806 if (!_bfd_elf_create_dynamic_sections (dynobj, info)) | 768 if (!_bfd_elf_create_dynamic_sections (dynobj, info)) |
807 return FALSE; | 769 return FALSE; |
808 | 770 |
809 htab->splt = bfd_get_section_by_name (dynobj, ".plt"); | 771 htab->elf.splt = bfd_get_linker_section (dynobj, ".plt"); |
810 htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt"); | 772 htab->elf.srelplt = bfd_get_linker_section (dynobj, ".rela.plt"); |
811 htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss"); | 773 htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss"); |
812 if (!info->shared) | 774 if (!info->shared) |
813 htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss"); | 775 htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss"); |
814 | 776 |
815 if (!htab->splt || !htab->srelplt || !htab->sdynbss | 777 if (!htab->elf.splt || !htab->elf.srelplt || !htab->sdynbss |
816 || (!info->shared && !htab->srelbss)) | 778 || (!info->shared && !htab->srelbss)) |
817 abort (); | 779 abort (); |
818 | 780 |
819 return TRUE; | 781 return TRUE; |
820 } | 782 } |
821 | 783 |
822 /* Copy the extra info we tack onto an elf_link_hash_entry. */ | 784 /* Copy the extra info we tack onto an elf_link_hash_entry. */ |
823 | 785 |
824 static void | 786 static void |
825 elf_s390_copy_indirect_symbol (info, dir, ind) | 787 elf_s390_copy_indirect_symbol (struct bfd_link_info *info, |
826 struct bfd_link_info *info; | 788 » » » struct elf_link_hash_entry *dir, |
827 struct elf_link_hash_entry *dir, *ind; | 789 » » » struct elf_link_hash_entry *ind) |
828 { | 790 { |
829 struct elf_s390_link_hash_entry *edir, *eind; | 791 struct elf_s390_link_hash_entry *edir, *eind; |
830 | 792 |
831 edir = (struct elf_s390_link_hash_entry *) dir; | 793 edir = (struct elf_s390_link_hash_entry *) dir; |
832 eind = (struct elf_s390_link_hash_entry *) ind; | 794 eind = (struct elf_s390_link_hash_entry *) ind; |
833 | 795 |
834 if (eind->dyn_relocs != NULL) | 796 if (eind->dyn_relocs != NULL) |
835 { | 797 { |
836 if (edir->dyn_relocs != NULL) | 798 if (edir->dyn_relocs != NULL) |
837 { | 799 { |
838 » struct elf_s390_dyn_relocs **pp; | 800 » struct elf_dyn_relocs **pp; |
839 » struct elf_s390_dyn_relocs *p; | 801 » struct elf_dyn_relocs *p; |
840 | 802 |
841 /* Add reloc counts against the indirect sym to the direct sym | 803 /* Add reloc counts against the indirect sym to the direct sym |
842 list. Merge any entries against the same section. */ | 804 list. Merge any entries against the same section. */ |
843 for (pp = &eind->dyn_relocs; (p = *pp) != NULL; ) | 805 for (pp = &eind->dyn_relocs; (p = *pp) != NULL; ) |
844 { | 806 { |
845 » struct elf_s390_dyn_relocs *q; | 807 » struct elf_dyn_relocs *q; |
846 | 808 |
847 for (q = edir->dyn_relocs; q != NULL; q = q->next) | 809 for (q = edir->dyn_relocs; q != NULL; q = q->next) |
848 if (q->sec == p->sec) | 810 if (q->sec == p->sec) |
849 { | 811 { |
850 q->pc_count += p->pc_count; | 812 q->pc_count += p->pc_count; |
851 q->count += p->count; | 813 q->count += p->count; |
852 *pp = p->next; | 814 *pp = p->next; |
853 break; | 815 break; |
854 } | 816 } |
855 if (q == NULL) | 817 if (q == NULL) |
(...skipping 23 matching lines...) Expand all Loading... |
879 dir->ref_dynamic |= ind->ref_dynamic; | 841 dir->ref_dynamic |= ind->ref_dynamic; |
880 dir->ref_regular |= ind->ref_regular; | 842 dir->ref_regular |= ind->ref_regular; |
881 dir->ref_regular_nonweak |= ind->ref_regular_nonweak; | 843 dir->ref_regular_nonweak |= ind->ref_regular_nonweak; |
882 dir->needs_plt |= ind->needs_plt; | 844 dir->needs_plt |= ind->needs_plt; |
883 } | 845 } |
884 else | 846 else |
885 _bfd_elf_link_hash_copy_indirect (info, dir, ind); | 847 _bfd_elf_link_hash_copy_indirect (info, dir, ind); |
886 } | 848 } |
887 | 849 |
888 static int | 850 static int |
889 elf_s390_tls_transition (info, r_type, is_local) | 851 elf_s390_tls_transition (struct bfd_link_info *info, |
890 struct bfd_link_info *info; | 852 » » » int r_type, |
891 int r_type; | 853 » » » int is_local) |
892 int is_local; | |
893 { | 854 { |
894 if (info->shared) | 855 if (info->shared) |
895 return r_type; | 856 return r_type; |
896 | 857 |
897 switch (r_type) | 858 switch (r_type) |
898 { | 859 { |
899 case R_390_TLS_GD64: | 860 case R_390_TLS_GD64: |
900 case R_390_TLS_IE64: | 861 case R_390_TLS_IE64: |
901 if (is_local) | 862 if (is_local) |
902 return R_390_TLS_LE64; | 863 return R_390_TLS_LE64; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
945 local_got_refcounts = elf_local_got_refcounts (abfd); | 906 local_got_refcounts = elf_local_got_refcounts (abfd); |
946 | 907 |
947 sreloc = NULL; | 908 sreloc = NULL; |
948 | 909 |
949 rel_end = relocs + sec->reloc_count; | 910 rel_end = relocs + sec->reloc_count; |
950 for (rel = relocs; rel < rel_end; rel++) | 911 for (rel = relocs; rel < rel_end; rel++) |
951 { | 912 { |
952 unsigned int r_type; | 913 unsigned int r_type; |
953 unsigned long r_symndx; | 914 unsigned long r_symndx; |
954 struct elf_link_hash_entry *h; | 915 struct elf_link_hash_entry *h; |
| 916 Elf_Internal_Sym *isym; |
955 | 917 |
956 r_symndx = ELF64_R_SYM (rel->r_info); | 918 r_symndx = ELF64_R_SYM (rel->r_info); |
957 | 919 |
958 if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr)) | 920 if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr)) |
959 { | 921 { |
960 (*_bfd_error_handler) (_("%B: bad symbol index: %d"), | 922 (*_bfd_error_handler) (_("%B: bad symbol index: %d"), |
961 abfd, | 923 abfd, |
962 r_symndx); | 924 r_symndx); |
963 return FALSE; | 925 return FALSE; |
964 } | 926 } |
965 | 927 |
966 if (r_symndx < symtab_hdr->sh_info) | 928 if (r_symndx < symtab_hdr->sh_info) |
967 » h = NULL; | 929 » { |
| 930 » /* A local symbol. */ |
| 931 » isym = bfd_sym_from_r_symndx (&htab->sym_cache, |
| 932 » » » » » abfd, r_symndx); |
| 933 » if (isym == NULL) |
| 934 » return FALSE; |
| 935 |
| 936 » if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC) |
| 937 » { |
| 938 » struct plt_entry *plt; |
| 939 |
| 940 » if (!s390_elf_create_ifunc_sections (htab->elf.dynobj, info)) |
| 941 » » return FALSE; |
| 942 |
| 943 » if (local_got_refcounts == NULL) |
| 944 » » { |
| 945 » » if (!elf_s390_allocate_local_syminfo (abfd, symtab_hdr)) |
| 946 » » return FALSE; |
| 947 » » local_got_refcounts = elf_local_got_refcounts (abfd); |
| 948 » » } |
| 949 » plt = elf_s390_local_plt (abfd); |
| 950 » plt[r_symndx].plt.refcount++; |
| 951 » } |
| 952 » h = NULL; |
| 953 » } |
968 else | 954 else |
969 { | 955 { |
970 h = sym_hashes[r_symndx - symtab_hdr->sh_info]; | 956 h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
971 while (h->root.type == bfd_link_hash_indirect | 957 while (h->root.type == bfd_link_hash_indirect |
972 || h->root.type == bfd_link_hash_warning) | 958 || h->root.type == bfd_link_hash_warning) |
973 h = (struct elf_link_hash_entry *) h->root.u.i.link; | 959 h = (struct elf_link_hash_entry *) h->root.u.i.link; |
974 } | 960 } |
975 | 961 |
976 /* Create got section and local_got_refcounts array if they | 962 /* Create got section and local_got_refcounts array if they |
977 are needed. */ | 963 are needed. */ |
(...skipping 17 matching lines...) Expand all Loading... |
995 case R_390_TLS_GD64: | 981 case R_390_TLS_GD64: |
996 case R_390_TLS_GOTIE12: | 982 case R_390_TLS_GOTIE12: |
997 case R_390_TLS_GOTIE20: | 983 case R_390_TLS_GOTIE20: |
998 case R_390_TLS_GOTIE64: | 984 case R_390_TLS_GOTIE64: |
999 case R_390_TLS_IEENT: | 985 case R_390_TLS_IEENT: |
1000 case R_390_TLS_IE64: | 986 case R_390_TLS_IE64: |
1001 case R_390_TLS_LDM64: | 987 case R_390_TLS_LDM64: |
1002 if (h == NULL | 988 if (h == NULL |
1003 && local_got_refcounts == NULL) | 989 && local_got_refcounts == NULL) |
1004 { | 990 { |
1005 » bfd_size_type size; | 991 » if (!elf_s390_allocate_local_syminfo (abfd, symtab_hdr)) |
| 992 » » return FALSE; |
| 993 » local_got_refcounts = elf_local_got_refcounts (abfd); |
| 994 » } |
1006 | 995 |
1007 size = symtab_hdr->sh_info; | |
1008 size *= (sizeof (bfd_signed_vma) + sizeof(char)); | |
1009 local_got_refcounts = ((bfd_signed_vma *) | |
1010 bfd_zalloc (abfd, size)); | |
1011 if (local_got_refcounts == NULL) | |
1012 return FALSE; | |
1013 elf_local_got_refcounts (abfd) = local_got_refcounts; | |
1014 elf_s390_local_got_tls_type (abfd) | |
1015 = (char *) (local_got_refcounts + symtab_hdr->sh_info); | |
1016 } | |
1017 /* Fall through. */ | 996 /* Fall through. */ |
1018 case R_390_GOTOFF16: | 997 case R_390_GOTOFF16: |
1019 case R_390_GOTOFF32: | 998 case R_390_GOTOFF32: |
1020 case R_390_GOTOFF64: | 999 case R_390_GOTOFF64: |
1021 case R_390_GOTPC: | 1000 case R_390_GOTPC: |
1022 case R_390_GOTPCDBL: | 1001 case R_390_GOTPCDBL: |
1023 » if (htab->sgot == NULL) | 1002 » if (htab->elf.sgot == NULL) |
1024 { | 1003 { |
1025 if (htab->elf.dynobj == NULL) | 1004 if (htab->elf.dynobj == NULL) |
1026 htab->elf.dynobj = abfd; | 1005 htab->elf.dynobj = abfd; |
1027 if (!create_got_section (htab->elf.dynobj, info)) | 1006 if (!create_got_section (htab->elf.dynobj, info)) |
1028 return FALSE; | 1007 return FALSE; |
1029 } | 1008 } |
1030 } | 1009 } |
1031 | 1010 |
| 1011 if (h != NULL) |
| 1012 { |
| 1013 if (htab->elf.dynobj == NULL) |
| 1014 htab->elf.dynobj = abfd; |
| 1015 if (!s390_elf_create_ifunc_sections (htab->elf.dynobj, info)) |
| 1016 return FALSE; |
| 1017 |
| 1018 /* Make sure an IFUNC symbol defined in a non-shared object |
| 1019 always gets a PLT slot. */ |
| 1020 if (s390_is_ifunc_symbol_p (h) && h->def_regular) |
| 1021 { |
| 1022 /* The symbol is called by the dynamic loader in order |
| 1023 to resolve the relocation. So it is in fact also |
| 1024 referenced. */ |
| 1025 h->ref_regular = 1; |
| 1026 h->needs_plt = 1; |
| 1027 } |
| 1028 } |
| 1029 |
1032 switch (r_type) | 1030 switch (r_type) |
1033 { | 1031 { |
1034 case R_390_GOTOFF16: | 1032 case R_390_GOTOFF16: |
1035 case R_390_GOTOFF32: | 1033 case R_390_GOTOFF32: |
1036 case R_390_GOTOFF64: | 1034 case R_390_GOTOFF64: |
1037 case R_390_GOTPC: | 1035 case R_390_GOTPC: |
1038 case R_390_GOTPCDBL: | 1036 case R_390_GOTPCDBL: |
1039 » /* Got is created, nothing to be done. */ | 1037 » /* These relocs do not need a GOT slot. They just load the |
| 1038 » GOT pointer itself or address something else relative to |
| 1039 » the GOT. Since the GOT pointer has been set up above we |
| 1040 » are done. */ |
1040 break; | 1041 break; |
1041 | 1042 |
1042 case R_390_PLT16DBL: | 1043 case R_390_PLT16DBL: |
1043 case R_390_PLT32: | 1044 case R_390_PLT32: |
1044 case R_390_PLT32DBL: | 1045 case R_390_PLT32DBL: |
1045 case R_390_PLT64: | 1046 case R_390_PLT64: |
1046 case R_390_PLTOFF16: | 1047 case R_390_PLTOFF16: |
1047 case R_390_PLTOFF32: | 1048 case R_390_PLTOFF32: |
1048 case R_390_PLTOFF64: | 1049 case R_390_PLTOFF64: |
1049 /* This symbol requires a procedure linkage table entry. We | 1050 /* This symbol requires a procedure linkage table entry. We |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1176 | 1177 |
1177 case R_390_8: | 1178 case R_390_8: |
1178 case R_390_16: | 1179 case R_390_16: |
1179 case R_390_32: | 1180 case R_390_32: |
1180 case R_390_64: | 1181 case R_390_64: |
1181 case R_390_PC16: | 1182 case R_390_PC16: |
1182 case R_390_PC16DBL: | 1183 case R_390_PC16DBL: |
1183 case R_390_PC32: | 1184 case R_390_PC32: |
1184 case R_390_PC32DBL: | 1185 case R_390_PC32DBL: |
1185 case R_390_PC64: | 1186 case R_390_PC64: |
1186 » if (h != NULL && !info->shared) | 1187 » if (h != NULL) |
1187 { | 1188 { |
1188 /* If this reloc is in a read-only section, we might | 1189 /* If this reloc is in a read-only section, we might |
1189 need a copy reloc. We can't check reliably at this | 1190 need a copy reloc. We can't check reliably at this |
1190 stage whether the section is read-only, as input | 1191 stage whether the section is read-only, as input |
1191 sections have not yet been mapped to output sections. | 1192 sections have not yet been mapped to output sections. |
1192 Tentatively set the flag for now, and correct in | 1193 Tentatively set the flag for now, and correct in |
1193 adjust_dynamic_symbol. */ | 1194 adjust_dynamic_symbol. */ |
1194 h->non_got_ref = 1; | 1195 h->non_got_ref = 1; |
1195 | 1196 |
1196 » /* We may need a .plt entry if the function this reloc | 1197 » if (!info->shared) |
1197 » » refers to is in a shared lib. */ | 1198 » » { |
1198 » h->plt.refcount += 1; | 1199 » » /* We may need a .plt entry if the function this reloc |
| 1200 » » refers to is in a shared lib. */ |
| 1201 » » h->plt.refcount += 1; |
| 1202 » » } |
1199 } | 1203 } |
1200 | 1204 |
1201 /* If we are creating a shared library, and this is a reloc | 1205 /* If we are creating a shared library, and this is a reloc |
1202 against a global symbol, or a non PC relative reloc | 1206 against a global symbol, or a non PC relative reloc |
1203 against a local symbol, then we need to copy the reloc | 1207 against a local symbol, then we need to copy the reloc |
1204 into the shared library. However, if we are linking with | 1208 into the shared library. However, if we are linking with |
1205 -Bsymbolic, we do not need to copy a reloc against a | 1209 -Bsymbolic, we do not need to copy a reloc against a |
1206 global symbol which is defined in an object we are | 1210 global symbol which is defined in an object we are |
1207 including in the link (i.e., DEF_REGULAR is set). At | 1211 including in the link (i.e., DEF_REGULAR is set). At |
1208 this point we have not seen all the input files, so it is | 1212 this point we have not seen all the input files, so it is |
(...skipping 21 matching lines...) Expand all Loading... |
1230 && (! SYMBOLIC_BIND (info, h) | 1234 && (! SYMBOLIC_BIND (info, h) |
1231 || h->root.type == bfd_link_hash_defweak | 1235 || h->root.type == bfd_link_hash_defweak |
1232 || !h->def_regular)))) | 1236 || !h->def_regular)))) |
1233 || (ELIMINATE_COPY_RELOCS | 1237 || (ELIMINATE_COPY_RELOCS |
1234 && !info->shared | 1238 && !info->shared |
1235 && (sec->flags & SEC_ALLOC) != 0 | 1239 && (sec->flags & SEC_ALLOC) != 0 |
1236 && h != NULL | 1240 && h != NULL |
1237 && (h->root.type == bfd_link_hash_defweak | 1241 && (h->root.type == bfd_link_hash_defweak |
1238 || !h->def_regular))) | 1242 || !h->def_regular))) |
1239 { | 1243 { |
1240 » struct elf_s390_dyn_relocs *p; | 1244 » struct elf_dyn_relocs *p; |
1241 » struct elf_s390_dyn_relocs **head; | 1245 » struct elf_dyn_relocs **head; |
1242 | 1246 |
1243 /* We must copy these reloc types into the output file. | 1247 /* We must copy these reloc types into the output file. |
1244 Create a reloc section in dynobj and make room for | 1248 Create a reloc section in dynobj and make room for |
1245 this reloc. */ | 1249 this reloc. */ |
1246 if (sreloc == NULL) | 1250 if (sreloc == NULL) |
1247 { | 1251 { |
1248 if (htab->elf.dynobj == NULL) | 1252 if (htab->elf.dynobj == NULL) |
1249 htab->elf.dynobj = abfd; | 1253 htab->elf.dynobj = abfd; |
1250 | 1254 |
1251 sreloc = _bfd_elf_make_dynamic_reloc_section | 1255 sreloc = _bfd_elf_make_dynamic_reloc_section |
1252 (sec, htab->elf.dynobj, 3, abfd, /*rela?*/ TRUE); | 1256 (sec, htab->elf.dynobj, 3, abfd, /*rela?*/ TRUE); |
1253 | 1257 |
1254 if (sreloc == NULL) | 1258 if (sreloc == NULL) |
1255 return FALSE; | 1259 return FALSE; |
1256 } | 1260 } |
1257 | 1261 |
1258 /* If this is a global symbol, we count the number of | 1262 /* If this is a global symbol, we count the number of |
1259 relocations we need for this symbol. */ | 1263 relocations we need for this symbol. */ |
1260 if (h != NULL) | 1264 if (h != NULL) |
1261 { | 1265 { |
1262 head = &((struct elf_s390_link_hash_entry *) h)->dyn_relocs; | 1266 head = &((struct elf_s390_link_hash_entry *) h)->dyn_relocs; |
1263 } | 1267 } |
1264 else | 1268 else |
1265 { | 1269 { |
1266 /* Track dynamic relocs needed for local syms too. | 1270 /* Track dynamic relocs needed for local syms too. |
1267 We really need local syms available to do this | 1271 We really need local syms available to do this |
1268 easily. Oh well. */ | 1272 easily. Oh well. */ |
1269 asection *s; | 1273 asection *s; |
1270 void *vpp; | 1274 void *vpp; |
1271 Elf_Internal_Sym *isym; | |
1272 | 1275 |
1273 isym = bfd_sym_from_r_symndx (&htab->sym_cache, | 1276 isym = bfd_sym_from_r_symndx (&htab->sym_cache, |
1274 abfd, r_symndx); | 1277 abfd, r_symndx); |
1275 if (isym == NULL) | 1278 if (isym == NULL) |
1276 return FALSE; | 1279 return FALSE; |
1277 | 1280 |
1278 s = bfd_section_from_elf_index (abfd, isym->st_shndx); | 1281 s = bfd_section_from_elf_index (abfd, isym->st_shndx); |
1279 if (s == NULL) | 1282 if (s == NULL) |
1280 s = sec; | 1283 s = sec; |
1281 | 1284 |
1282 vpp = &elf_section_data (s)->local_dynrel; | 1285 vpp = &elf_section_data (s)->local_dynrel; |
1283 » » head = (struct elf_s390_dyn_relocs **) vpp; | 1286 » » head = (struct elf_dyn_relocs **) vpp; |
1284 } | 1287 } |
1285 | 1288 |
1286 p = *head; | 1289 p = *head; |
1287 if (p == NULL || p->sec != sec) | 1290 if (p == NULL || p->sec != sec) |
1288 { | 1291 { |
1289 bfd_size_type amt = sizeof *p; | 1292 bfd_size_type amt = sizeof *p; |
1290 » » p = ((struct elf_s390_dyn_relocs *) | 1293 » » p = ((struct elf_dyn_relocs *) |
1291 bfd_alloc (htab->elf.dynobj, amt)); | 1294 bfd_alloc (htab->elf.dynobj, amt)); |
1292 if (p == NULL) | 1295 if (p == NULL) |
1293 return FALSE; | 1296 return FALSE; |
1294 p->next = *head; | 1297 p->next = *head; |
1295 *head = p; | 1298 *head = p; |
1296 p->sec = sec; | 1299 p->sec = sec; |
1297 p->count = 0; | 1300 p->count = 0; |
1298 p->pc_count = 0; | 1301 p->pc_count = 0; |
1299 } | 1302 } |
1300 | 1303 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1384 for (rel = relocs; rel < relend; rel++) | 1387 for (rel = relocs; rel < relend; rel++) |
1385 { | 1388 { |
1386 unsigned long r_symndx; | 1389 unsigned long r_symndx; |
1387 unsigned int r_type; | 1390 unsigned int r_type; |
1388 struct elf_link_hash_entry *h = NULL; | 1391 struct elf_link_hash_entry *h = NULL; |
1389 | 1392 |
1390 r_symndx = ELF64_R_SYM (rel->r_info); | 1393 r_symndx = ELF64_R_SYM (rel->r_info); |
1391 if (r_symndx >= symtab_hdr->sh_info) | 1394 if (r_symndx >= symtab_hdr->sh_info) |
1392 { | 1395 { |
1393 struct elf_s390_link_hash_entry *eh; | 1396 struct elf_s390_link_hash_entry *eh; |
1394 » struct elf_s390_dyn_relocs **pp; | 1397 » struct elf_dyn_relocs **pp; |
1395 » struct elf_s390_dyn_relocs *p; | 1398 » struct elf_dyn_relocs *p; |
1396 | 1399 |
1397 h = sym_hashes[r_symndx - symtab_hdr->sh_info]; | 1400 h = sym_hashes[r_symndx - symtab_hdr->sh_info]; |
1398 while (h->root.type == bfd_link_hash_indirect | 1401 while (h->root.type == bfd_link_hash_indirect |
1399 || h->root.type == bfd_link_hash_warning) | 1402 || h->root.type == bfd_link_hash_warning) |
1400 h = (struct elf_link_hash_entry *) h->root.u.i.link; | 1403 h = (struct elf_link_hash_entry *) h->root.u.i.link; |
1401 eh = (struct elf_s390_link_hash_entry *) h; | 1404 eh = (struct elf_s390_link_hash_entry *) h; |
1402 | 1405 |
1403 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next) | 1406 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next) |
1404 if (p->sec == sec) | 1407 if (p->sec == sec) |
1405 { | 1408 { |
1406 /* Everything must go for SEC. */ | 1409 /* Everything must go for SEC. */ |
1407 *pp = p->next; | 1410 *pp = p->next; |
1408 break; | 1411 break; |
1409 } | 1412 } |
1410 } | 1413 } |
| 1414 else |
| 1415 { |
| 1416 Elf_Internal_Sym *isym; |
| 1417 |
| 1418 /* A local symbol. */ |
| 1419 isym = bfd_sym_from_r_symndx (&htab->sym_cache, |
| 1420 abfd, r_symndx); |
| 1421 if (isym == NULL) |
| 1422 return FALSE; |
| 1423 |
| 1424 if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC) |
| 1425 { |
| 1426 struct plt_entry *plt = elf_s390_local_plt (abfd); |
| 1427 if (plt[r_symndx].plt.refcount > 0) |
| 1428 plt[r_symndx].plt.refcount--; |
| 1429 } |
| 1430 } |
1411 | 1431 |
1412 r_type = ELF64_R_TYPE (rel->r_info); | 1432 r_type = ELF64_R_TYPE (rel->r_info); |
1413 r_type = elf_s390_tls_transition (info, r_type, h != NULL); | 1433 r_type = elf_s390_tls_transition (info, r_type, h != NULL); |
1414 switch (r_type) | 1434 switch (r_type) |
1415 { | 1435 { |
1416 case R_390_TLS_LDM64: | 1436 case R_390_TLS_LDM64: |
1417 if (htab->tls_ldm_got.refcount > 0) | 1437 if (htab->tls_ldm_got.refcount > 0) |
1418 htab->tls_ldm_got.refcount -= 1; | 1438 htab->tls_ldm_got.refcount -= 1; |
1419 break; | 1439 break; |
1420 | 1440 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1506 } | 1526 } |
1507 | 1527 |
1508 /* Make sure we emit a GOT entry if the symbol was supposed to have a PLT | 1528 /* Make sure we emit a GOT entry if the symbol was supposed to have a PLT |
1509 entry but we found we will not create any. Called when we find we will | 1529 entry but we found we will not create any. Called when we find we will |
1510 not have any PLT for this symbol, by for example | 1530 not have any PLT for this symbol, by for example |
1511 elf_s390_adjust_dynamic_symbol when we're doing a proper dynamic link, | 1531 elf_s390_adjust_dynamic_symbol when we're doing a proper dynamic link, |
1512 or elf_s390_size_dynamic_sections if no dynamic sections will be | 1532 or elf_s390_size_dynamic_sections if no dynamic sections will be |
1513 created (we're only linking static objects). */ | 1533 created (we're only linking static objects). */ |
1514 | 1534 |
1515 static void | 1535 static void |
1516 elf_s390_adjust_gotplt (h) | 1536 elf_s390_adjust_gotplt (struct elf_s390_link_hash_entry *h) |
1517 struct elf_s390_link_hash_entry *h; | |
1518 { | 1537 { |
1519 if (h->elf.root.type == bfd_link_hash_warning) | 1538 if (h->elf.root.type == bfd_link_hash_warning) |
1520 h = (struct elf_s390_link_hash_entry *) h->elf.root.u.i.link; | 1539 h = (struct elf_s390_link_hash_entry *) h->elf.root.u.i.link; |
1521 | 1540 |
1522 if (h->gotplt_refcount <= 0) | 1541 if (h->gotplt_refcount <= 0) |
1523 return; | 1542 return; |
1524 | 1543 |
1525 /* We simply add the number of gotplt references to the number | 1544 /* We simply add the number of gotplt references to the number |
1526 * of got references for this symbol. */ | 1545 * of got references for this symbol. */ |
1527 h->elf.got.refcount += h->gotplt_refcount; | 1546 h->elf.got.refcount += h->gotplt_refcount; |
1528 h->gotplt_refcount = -1; | 1547 h->gotplt_refcount = -1; |
1529 } | 1548 } |
1530 | 1549 |
1531 /* Adjust a symbol defined by a dynamic object and referenced by a | 1550 /* Adjust a symbol defined by a dynamic object and referenced by a |
1532 regular object. The current definition is in some section of the | 1551 regular object. The current definition is in some section of the |
1533 dynamic object, but we're not including those sections. We have to | 1552 dynamic object, but we're not including those sections. We have to |
1534 change the definition to something the rest of the link can | 1553 change the definition to something the rest of the link can |
1535 understand. */ | 1554 understand. */ |
1536 | 1555 |
1537 static bfd_boolean | 1556 static bfd_boolean |
1538 elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info, | 1557 elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info, |
1539 struct elf_link_hash_entry *h) | 1558 struct elf_link_hash_entry *h) |
1540 { | 1559 { |
1541 struct elf_s390_link_hash_table *htab; | 1560 struct elf_s390_link_hash_table *htab; |
1542 asection *s; | 1561 asection *s; |
1543 | 1562 |
| 1563 /* STT_GNU_IFUNC symbol must go through PLT. */ |
| 1564 if (s390_is_ifunc_symbol_p (h)) |
| 1565 return TRUE; |
| 1566 |
1544 /* If this is a function, put it in the procedure linkage table. We | 1567 /* If this is a function, put it in the procedure linkage table. We |
1545 will fill in the contents of the procedure linkage table later | 1568 will fill in the contents of the procedure linkage table later |
1546 (although we could actually do it here). */ | 1569 (although we could actually do it here). */ |
1547 if (h->type == STT_FUNC | 1570 if (h->type == STT_FUNC |
1548 || h->needs_plt) | 1571 || h->needs_plt) |
1549 { | 1572 { |
1550 if (h->plt.refcount <= 0 | 1573 if (h->plt.refcount <= 0 |
1551 || SYMBOL_CALLS_LOCAL (info, h) | 1574 || SYMBOL_CALLS_LOCAL (info, h) |
1552 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT | 1575 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT |
1553 && h->root.type == bfd_link_hash_undefweak)) | 1576 && h->root.type == bfd_link_hash_undefweak)) |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1604 /* If -z nocopyreloc was given, we won't generate them either. */ | 1627 /* If -z nocopyreloc was given, we won't generate them either. */ |
1605 if (info->nocopyreloc) | 1628 if (info->nocopyreloc) |
1606 { | 1629 { |
1607 h->non_got_ref = 0; | 1630 h->non_got_ref = 0; |
1608 return TRUE; | 1631 return TRUE; |
1609 } | 1632 } |
1610 | 1633 |
1611 if (ELIMINATE_COPY_RELOCS) | 1634 if (ELIMINATE_COPY_RELOCS) |
1612 { | 1635 { |
1613 struct elf_s390_link_hash_entry * eh; | 1636 struct elf_s390_link_hash_entry * eh; |
1614 struct elf_s390_dyn_relocs *p; | 1637 struct elf_dyn_relocs *p; |
1615 | 1638 |
1616 eh = (struct elf_s390_link_hash_entry *) h; | 1639 eh = (struct elf_s390_link_hash_entry *) h; |
1617 for (p = eh->dyn_relocs; p != NULL; p = p->next) | 1640 for (p = eh->dyn_relocs; p != NULL; p = p->next) |
1618 { | 1641 { |
1619 s = p->sec->output_section; | 1642 s = p->sec->output_section; |
1620 if (s != NULL && (s->flags & SEC_READONLY) != 0) | 1643 if (s != NULL && (s->flags & SEC_READONLY) != 0) |
1621 break; | 1644 break; |
1622 } | 1645 } |
1623 | 1646 |
1624 /* If we didn't find any dynamic relocs in read-only sections, then | 1647 /* If we didn't find any dynamic relocs in read-only sections, then |
1625 we'll be keeping the dynamic relocs and avoiding the copy reloc. */ | 1648 we'll be keeping the dynamic relocs and avoiding the copy reloc. */ |
1626 if (p == NULL) | 1649 if (p == NULL) |
1627 { | 1650 { |
1628 h->non_got_ref = 0; | 1651 h->non_got_ref = 0; |
1629 return TRUE; | 1652 return TRUE; |
1630 } | 1653 } |
1631 } | 1654 } |
1632 | 1655 |
1633 if (h->size == 0) | |
1634 { | |
1635 (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"), | |
1636 h->root.root.string); | |
1637 return TRUE; | |
1638 } | |
1639 | |
1640 /* We must allocate the symbol in our .dynbss section, which will | 1656 /* We must allocate the symbol in our .dynbss section, which will |
1641 become part of the .bss section of the executable. There will be | 1657 become part of the .bss section of the executable. There will be |
1642 an entry for this symbol in the .dynsym section. The dynamic | 1658 an entry for this symbol in the .dynsym section. The dynamic |
1643 object will contain position independent code, so all references | 1659 object will contain position independent code, so all references |
1644 from the dynamic object to this symbol will go through the global | 1660 from the dynamic object to this symbol will go through the global |
1645 offset table. The dynamic linker will use the .dynsym entry to | 1661 offset table. The dynamic linker will use the .dynsym entry to |
1646 determine the address it must put in the global offset table, so | 1662 determine the address it must put in the global offset table, so |
1647 both the dynamic object and the regular object will refer to the | 1663 both the dynamic object and the regular object will refer to the |
1648 same memory location for the variable. */ | 1664 same memory location for the variable. */ |
1649 | 1665 |
1650 htab = elf_s390_hash_table (info); | 1666 htab = elf_s390_hash_table (info); |
1651 if (htab == NULL) | 1667 if (htab == NULL) |
1652 return FALSE; | 1668 return FALSE; |
1653 | 1669 |
1654 /* We must generate a R_390_COPY reloc to tell the dynamic linker to | 1670 /* We must generate a R_390_COPY reloc to tell the dynamic linker to |
1655 copy the initial value out of the dynamic object and into the | 1671 copy the initial value out of the dynamic object and into the |
1656 runtime process image. */ | 1672 runtime process image. */ |
1657 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0) | 1673 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0) |
1658 { | 1674 { |
1659 htab->srelbss->size += sizeof (Elf64_External_Rela); | 1675 htab->srelbss->size += sizeof (Elf64_External_Rela); |
1660 h->needs_copy = 1; | 1676 h->needs_copy = 1; |
1661 } | 1677 } |
1662 | 1678 |
1663 s = htab->sdynbss; | 1679 s = htab->sdynbss; |
1664 | 1680 |
1665 return _bfd_elf_adjust_dynamic_copy (h, s); | 1681 return _bfd_elf_adjust_dynamic_copy (h, s); |
1666 } | 1682 } |
1667 | 1683 |
1668 /* Allocate space in .plt, .got and associated reloc sections for | 1684 /* Allocate space in .plt, .got and associated reloc sections for |
1669 dynamic relocs. */ | 1685 dynamic relocs. */ |
1670 | 1686 |
1671 static bfd_boolean | 1687 static bfd_boolean |
1672 allocate_dynrelocs (struct elf_link_hash_entry *h, | 1688 allocate_dynrelocs (struct elf_link_hash_entry *h, |
1673 void * inf) | 1689 void * inf) |
1674 { | 1690 { |
1675 struct bfd_link_info *info; | 1691 struct bfd_link_info *info; |
1676 struct elf_s390_link_hash_table *htab; | 1692 struct elf_s390_link_hash_table *htab; |
1677 struct elf_s390_link_hash_entry *eh; | 1693 struct elf_s390_link_hash_entry *eh = (struct elf_s390_link_hash_entry *)h; |
1678 struct elf_s390_dyn_relocs *p; | 1694 struct elf_dyn_relocs *p; |
1679 | 1695 |
1680 if (h->root.type == bfd_link_hash_indirect) | 1696 if (h->root.type == bfd_link_hash_indirect) |
1681 return TRUE; | 1697 return TRUE; |
1682 | 1698 |
1683 info = (struct bfd_link_info *) inf; | 1699 info = (struct bfd_link_info *) inf; |
1684 htab = elf_s390_hash_table (info); | 1700 htab = elf_s390_hash_table (info); |
1685 if (htab == NULL) | 1701 if (htab == NULL) |
1686 return FALSE; | 1702 return FALSE; |
1687 | 1703 |
1688 if (htab->elf.dynamic_sections_created | 1704 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it |
1689 && h->plt.refcount > 0) | 1705 here if it is defined and referenced in a non-shared object. */ |
| 1706 if (s390_is_ifunc_symbol_p (h) && h->def_regular) |
| 1707 return s390_elf_allocate_ifunc_dyn_relocs (info, h, |
| 1708 » » » » » &eh->dyn_relocs); |
| 1709 else if (htab->elf.dynamic_sections_created |
| 1710 » && h->plt.refcount > 0) |
1690 { | 1711 { |
1691 /* Make sure this symbol is output as a dynamic symbol. | 1712 /* Make sure this symbol is output as a dynamic symbol. |
1692 Undefined weak syms won't yet be marked as dynamic. */ | 1713 Undefined weak syms won't yet be marked as dynamic. */ |
1693 if (h->dynindx == -1 | 1714 if (h->dynindx == -1 |
1694 && !h->forced_local) | 1715 && !h->forced_local) |
1695 { | 1716 { |
1696 if (! bfd_elf_link_record_dynamic_symbol (info, h)) | 1717 if (! bfd_elf_link_record_dynamic_symbol (info, h)) |
1697 return FALSE; | 1718 return FALSE; |
1698 } | 1719 } |
1699 | 1720 |
1700 if (info->shared | 1721 if (info->shared |
1701 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h)) | 1722 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h)) |
1702 { | 1723 { |
1703 » asection *s = htab->splt; | 1724 » asection *s = htab->elf.splt; |
1704 | 1725 |
1705 /* If this is the first .plt entry, make room for the special | 1726 /* If this is the first .plt entry, make room for the special |
1706 first entry. */ | 1727 first entry. */ |
1707 if (s->size == 0) | 1728 if (s->size == 0) |
1708 s->size += PLT_FIRST_ENTRY_SIZE; | 1729 s->size += PLT_FIRST_ENTRY_SIZE; |
1709 | 1730 |
1710 h->plt.offset = s->size; | 1731 h->plt.offset = s->size; |
1711 | 1732 |
1712 /* If this symbol is not defined in a regular file, and we are | 1733 /* If this symbol is not defined in a regular file, and we are |
1713 not generating a shared library, then set the symbol to this | 1734 not generating a shared library, then set the symbol to this |
1714 location in the .plt. This is required to make function | 1735 location in the .plt. This is required to make function |
1715 pointers compare as equal between the normal executable and | 1736 pointers compare as equal between the normal executable and |
1716 the shared library. */ | 1737 the shared library. */ |
1717 if (! info->shared | 1738 if (! info->shared |
1718 && !h->def_regular) | 1739 && !h->def_regular) |
1719 { | 1740 { |
1720 h->root.u.def.section = s; | 1741 h->root.u.def.section = s; |
1721 h->root.u.def.value = h->plt.offset; | 1742 h->root.u.def.value = h->plt.offset; |
1722 } | 1743 } |
1723 | 1744 |
1724 /* Make room for this entry. */ | 1745 /* Make room for this entry. */ |
1725 s->size += PLT_ENTRY_SIZE; | 1746 s->size += PLT_ENTRY_SIZE; |
1726 | 1747 |
1727 /* We also need to make an entry in the .got.plt section, which | 1748 /* We also need to make an entry in the .got.plt section, which |
1728 will be placed in the .got section by the linker script. */ | 1749 will be placed in the .got section by the linker script. */ |
1729 » htab->sgotplt->size += GOT_ENTRY_SIZE; | 1750 » htab->elf.sgotplt->size += GOT_ENTRY_SIZE; |
1730 | 1751 |
1731 /* We also need to make an entry in the .rela.plt section. */ | 1752 /* We also need to make an entry in the .rela.plt section. */ |
1732 » htab->srelplt->size += sizeof (Elf64_External_Rela); | 1753 » htab->elf.srelplt->size += sizeof (Elf64_External_Rela); |
1733 } | 1754 } |
1734 else | 1755 else |
1735 { | 1756 { |
1736 h->plt.offset = (bfd_vma) -1; | 1757 h->plt.offset = (bfd_vma) -1; |
1737 h->needs_plt = 0; | 1758 h->needs_plt = 0; |
1738 elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h); | 1759 elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h); |
1739 } | 1760 } |
1740 } | 1761 } |
1741 else | 1762 else |
1742 { | 1763 { |
1743 h->plt.offset = (bfd_vma) -1; | 1764 h->plt.offset = (bfd_vma) -1; |
1744 h->needs_plt = 0; | 1765 h->needs_plt = 0; |
1745 elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h); | 1766 elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h); |
1746 } | 1767 } |
1747 | 1768 |
1748 /* If R_390_TLS_{IE64,GOTIE64,GOTIE12,IEENT} symbol is now local to | 1769 /* If R_390_TLS_{IE64,GOTIE64,GOTIE12,IEENT} symbol is now local to |
1749 the binary, we can optimize a bit. IE64 and GOTIE64 get converted | 1770 the binary, we can optimize a bit. IE64 and GOTIE64 get converted |
1750 to R_390_TLS_LE64 requiring no TLS entry. For GOTIE12 and IEENT | 1771 to R_390_TLS_LE64 requiring no TLS entry. For GOTIE12 and IEENT |
1751 we can save the dynamic TLS relocation. */ | 1772 we can save the dynamic TLS relocation. */ |
1752 if (h->got.refcount > 0 | 1773 if (h->got.refcount > 0 |
1753 && !info->shared | 1774 && !info->shared |
1754 && h->dynindx == -1 | 1775 && h->dynindx == -1 |
1755 && elf_s390_hash_entry(h)->tls_type >= GOT_TLS_IE) | 1776 && elf_s390_hash_entry(h)->tls_type >= GOT_TLS_IE) |
1756 { | 1777 { |
1757 if (elf_s390_hash_entry(h)->tls_type == GOT_TLS_IE_NLT) | 1778 if (elf_s390_hash_entry(h)->tls_type == GOT_TLS_IE_NLT) |
1758 /* For the GOTIE access without a literal pool entry the offset has | 1779 /* For the GOTIE access without a literal pool entry the offset has |
1759 to be stored somewhere. The immediate value in the instruction | 1780 to be stored somewhere. The immediate value in the instruction |
1760 is not bit enough so the value is stored in the got. */ | 1781 is not bit enough so the value is stored in the got. */ |
1761 { | 1782 { |
1762 » h->got.offset = htab->sgot->size; | 1783 » h->got.offset = htab->elf.sgot->size; |
1763 » htab->sgot->size += GOT_ENTRY_SIZE; | 1784 » htab->elf.sgot->size += GOT_ENTRY_SIZE; |
1764 } | 1785 } |
1765 else | 1786 else |
1766 h->got.offset = (bfd_vma) -1; | 1787 h->got.offset = (bfd_vma) -1; |
1767 } | 1788 } |
1768 else if (h->got.refcount > 0) | 1789 else if (h->got.refcount > 0) |
1769 { | 1790 { |
1770 asection *s; | 1791 asection *s; |
1771 bfd_boolean dyn; | 1792 bfd_boolean dyn; |
1772 int tls_type = elf_s390_hash_entry(h)->tls_type; | 1793 int tls_type = elf_s390_hash_entry(h)->tls_type; |
1773 | 1794 |
1774 /* Make sure this symbol is output as a dynamic symbol. | 1795 /* Make sure this symbol is output as a dynamic symbol. |
1775 Undefined weak syms won't yet be marked as dynamic. */ | 1796 Undefined weak syms won't yet be marked as dynamic. */ |
1776 if (h->dynindx == -1 | 1797 if (h->dynindx == -1 |
1777 && !h->forced_local) | 1798 && !h->forced_local) |
1778 { | 1799 { |
1779 if (! bfd_elf_link_record_dynamic_symbol (info, h)) | 1800 if (! bfd_elf_link_record_dynamic_symbol (info, h)) |
1780 return FALSE; | 1801 return FALSE; |
1781 } | 1802 } |
1782 | 1803 |
1783 s = htab->sgot; | 1804 s = htab->elf.sgot; |
1784 h->got.offset = s->size; | 1805 h->got.offset = s->size; |
1785 s->size += GOT_ENTRY_SIZE; | 1806 s->size += GOT_ENTRY_SIZE; |
1786 /* R_390_TLS_GD64 needs 2 consecutive GOT slots. */ | 1807 /* R_390_TLS_GD64 needs 2 consecutive GOT slots. */ |
1787 if (tls_type == GOT_TLS_GD) | 1808 if (tls_type == GOT_TLS_GD) |
1788 s->size += GOT_ENTRY_SIZE; | 1809 s->size += GOT_ENTRY_SIZE; |
1789 dyn = htab->elf.dynamic_sections_created; | 1810 dyn = htab->elf.dynamic_sections_created; |
1790 /* R_390_TLS_IE64 needs one dynamic relocation, | 1811 /* R_390_TLS_IE64 needs one dynamic relocation, |
1791 R_390_TLS_GD64 needs one if local symbol and two if global. */ | 1812 R_390_TLS_GD64 needs one if local symbol and two if global. */ |
1792 if ((tls_type == GOT_TLS_GD && h->dynindx == -1) | 1813 if ((tls_type == GOT_TLS_GD && h->dynindx == -1) |
1793 || tls_type >= GOT_TLS_IE) | 1814 || tls_type >= GOT_TLS_IE) |
1794 » htab->srelgot->size += sizeof (Elf64_External_Rela); | 1815 » htab->elf.srelgot->size += sizeof (Elf64_External_Rela); |
1795 else if (tls_type == GOT_TLS_GD) | 1816 else if (tls_type == GOT_TLS_GD) |
1796 » htab->srelgot->size += 2 * sizeof (Elf64_External_Rela); | 1817 » htab->elf.srelgot->size += 2 * sizeof (Elf64_External_Rela); |
1797 else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT | 1818 else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT |
1798 || h->root.type != bfd_link_hash_undefweak) | 1819 || h->root.type != bfd_link_hash_undefweak) |
1799 && (info->shared | 1820 && (info->shared |
1800 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))) | 1821 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))) |
1801 » htab->srelgot->size += sizeof (Elf64_External_Rela); | 1822 » htab->elf.srelgot->size += sizeof (Elf64_External_Rela); |
1802 } | 1823 } |
1803 else | 1824 else |
1804 h->got.offset = (bfd_vma) -1; | 1825 h->got.offset = (bfd_vma) -1; |
1805 | 1826 |
1806 eh = (struct elf_s390_link_hash_entry *) h; | |
1807 if (eh->dyn_relocs == NULL) | 1827 if (eh->dyn_relocs == NULL) |
1808 return TRUE; | 1828 return TRUE; |
1809 | 1829 |
1810 /* In the shared -Bsymbolic case, discard space allocated for | 1830 /* In the shared -Bsymbolic case, discard space allocated for |
1811 dynamic pc-relative relocs against symbols which turn out to be | 1831 dynamic pc-relative relocs against symbols which turn out to be |
1812 defined in regular objects. For the normal shared case, discard | 1832 defined in regular objects. For the normal shared case, discard |
1813 space for pc-relative relocs that have become local due to symbol | 1833 space for pc-relative relocs that have become local due to symbol |
1814 visibility changes. */ | 1834 visibility changes. */ |
1815 | 1835 |
1816 if (info->shared) | 1836 if (info->shared) |
1817 { | 1837 { |
1818 if (SYMBOL_CALLS_LOCAL (info, h)) | 1838 if (SYMBOL_CALLS_LOCAL (info, h)) |
1819 { | 1839 { |
1820 » struct elf_s390_dyn_relocs **pp; | 1840 » struct elf_dyn_relocs **pp; |
1821 | 1841 |
1822 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) | 1842 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) |
1823 { | 1843 { |
1824 p->count -= p->pc_count; | 1844 p->count -= p->pc_count; |
1825 p->pc_count = 0; | 1845 p->pc_count = 0; |
1826 if (p->count == 0) | 1846 if (p->count == 0) |
1827 *pp = p->next; | 1847 *pp = p->next; |
1828 else | 1848 else |
1829 pp = &p->next; | 1849 pp = &p->next; |
1830 } | 1850 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1887 asection *sreloc = elf_section_data (p->sec)->sreloc; | 1907 asection *sreloc = elf_section_data (p->sec)->sreloc; |
1888 sreloc->size += p->count * sizeof (Elf64_External_Rela); | 1908 sreloc->size += p->count * sizeof (Elf64_External_Rela); |
1889 } | 1909 } |
1890 | 1910 |
1891 return TRUE; | 1911 return TRUE; |
1892 } | 1912 } |
1893 | 1913 |
1894 /* Find any dynamic relocs that apply to read-only sections. */ | 1914 /* Find any dynamic relocs that apply to read-only sections. */ |
1895 | 1915 |
1896 static bfd_boolean | 1916 static bfd_boolean |
1897 readonly_dynrelocs (h, inf) | 1917 readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf) |
1898 struct elf_link_hash_entry *h; | |
1899 PTR inf; | |
1900 { | 1918 { |
1901 struct elf_s390_link_hash_entry *eh; | 1919 struct elf_s390_link_hash_entry *eh; |
1902 struct elf_s390_dyn_relocs *p; | 1920 struct elf_dyn_relocs *p; |
1903 | 1921 |
1904 eh = (struct elf_s390_link_hash_entry *) h; | 1922 eh = (struct elf_s390_link_hash_entry *) h; |
1905 for (p = eh->dyn_relocs; p != NULL; p = p->next) | 1923 for (p = eh->dyn_relocs; p != NULL; p = p->next) |
1906 { | 1924 { |
1907 asection *s = p->sec->output_section; | 1925 asection *s = p->sec->output_section; |
1908 | 1926 |
1909 if (s != NULL && (s->flags & SEC_READONLY) != 0) | 1927 if (s != NULL && (s->flags & SEC_READONLY) != 0) |
1910 { | 1928 { |
1911 struct bfd_link_info *info = (struct bfd_link_info *) inf; | 1929 struct bfd_link_info *info = (struct bfd_link_info *) inf; |
1912 | 1930 |
(...skipping 24 matching lines...) Expand all Loading... |
1937 | 1955 |
1938 dynobj = htab->elf.dynobj; | 1956 dynobj = htab->elf.dynobj; |
1939 if (dynobj == NULL) | 1957 if (dynobj == NULL) |
1940 abort (); | 1958 abort (); |
1941 | 1959 |
1942 if (htab->elf.dynamic_sections_created) | 1960 if (htab->elf.dynamic_sections_created) |
1943 { | 1961 { |
1944 /* Set the contents of the .interp section to the interpreter. */ | 1962 /* Set the contents of the .interp section to the interpreter. */ |
1945 if (info->executable) | 1963 if (info->executable) |
1946 { | 1964 { |
1947 » s = bfd_get_section_by_name (dynobj, ".interp"); | 1965 » s = bfd_get_linker_section (dynobj, ".interp"); |
1948 if (s == NULL) | 1966 if (s == NULL) |
1949 abort (); | 1967 abort (); |
1950 s->size = sizeof ELF_DYNAMIC_INTERPRETER; | 1968 s->size = sizeof ELF_DYNAMIC_INTERPRETER; |
1951 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; | 1969 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; |
1952 } | 1970 } |
1953 } | 1971 } |
1954 | 1972 |
1955 /* Set up .got offsets for local syms, and space for local dynamic | 1973 /* Set up .got offsets for local syms, and space for local dynamic |
1956 relocs. */ | 1974 relocs. */ |
1957 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) | 1975 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) |
1958 { | 1976 { |
1959 bfd_signed_vma *local_got; | 1977 bfd_signed_vma *local_got; |
1960 bfd_signed_vma *end_local_got; | 1978 bfd_signed_vma *end_local_got; |
1961 char *local_tls_type; | 1979 char *local_tls_type; |
1962 bfd_size_type locsymcount; | 1980 bfd_size_type locsymcount; |
1963 Elf_Internal_Shdr *symtab_hdr; | 1981 Elf_Internal_Shdr *symtab_hdr; |
1964 asection *srela; | 1982 asection *srela; |
| 1983 struct plt_entry *local_plt; |
| 1984 unsigned int i; |
1965 | 1985 |
1966 if (! is_s390_elf (ibfd)) | 1986 if (! is_s390_elf (ibfd)) |
1967 continue; | 1987 continue; |
1968 | 1988 |
1969 for (s = ibfd->sections; s != NULL; s = s->next) | 1989 for (s = ibfd->sections; s != NULL; s = s->next) |
1970 { | 1990 { |
1971 » struct elf_s390_dyn_relocs *p; | 1991 » struct elf_dyn_relocs *p; |
1972 | 1992 |
1973 for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next) | 1993 for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next) |
1974 { | 1994 { |
1975 if (!bfd_is_abs_section (p->sec) | 1995 if (!bfd_is_abs_section (p->sec) |
1976 && bfd_is_abs_section (p->sec->output_section)) | 1996 && bfd_is_abs_section (p->sec->output_section)) |
1977 { | 1997 { |
1978 /* Input section has been discarded, either because | 1998 /* Input section has been discarded, either because |
1979 it is a copy of a linkonce section or due to | 1999 it is a copy of a linkonce section or due to |
1980 linker script /DISCARD/, so we'll be discarding | 2000 linker script /DISCARD/, so we'll be discarding |
1981 the relocs too. */ | 2001 the relocs too. */ |
1982 } | 2002 } |
1983 else if (p->count != 0) | 2003 else if (p->count != 0) |
1984 { | 2004 { |
1985 srela = elf_section_data (p->sec)->sreloc; | 2005 srela = elf_section_data (p->sec)->sreloc; |
1986 srela->size += p->count * sizeof (Elf64_External_Rela); | 2006 srela->size += p->count * sizeof (Elf64_External_Rela); |
1987 if ((p->sec->output_section->flags & SEC_READONLY) != 0) | 2007 if ((p->sec->output_section->flags & SEC_READONLY) != 0) |
1988 info->flags |= DF_TEXTREL; | 2008 info->flags |= DF_TEXTREL; |
1989 } | 2009 } |
1990 } | 2010 } |
1991 } | 2011 } |
1992 | 2012 |
1993 local_got = elf_local_got_refcounts (ibfd); | 2013 local_got = elf_local_got_refcounts (ibfd); |
1994 if (!local_got) | 2014 if (!local_got) |
1995 continue; | 2015 continue; |
1996 | 2016 |
1997 symtab_hdr = &elf_symtab_hdr (ibfd); | 2017 symtab_hdr = &elf_symtab_hdr (ibfd); |
1998 locsymcount = symtab_hdr->sh_info; | 2018 locsymcount = symtab_hdr->sh_info; |
1999 end_local_got = local_got + locsymcount; | 2019 end_local_got = local_got + locsymcount; |
2000 local_tls_type = elf_s390_local_got_tls_type (ibfd); | 2020 local_tls_type = elf_s390_local_got_tls_type (ibfd); |
2001 s = htab->sgot; | 2021 s = htab->elf.sgot; |
2002 srela = htab->srelgot; | 2022 srela = htab->elf.srelgot; |
2003 for (; local_got < end_local_got; ++local_got, ++local_tls_type) | 2023 for (; local_got < end_local_got; ++local_got, ++local_tls_type) |
2004 { | 2024 { |
2005 if (*local_got > 0) | 2025 if (*local_got > 0) |
2006 { | 2026 { |
2007 *local_got = s->size; | 2027 *local_got = s->size; |
2008 s->size += GOT_ENTRY_SIZE; | 2028 s->size += GOT_ENTRY_SIZE; |
2009 if (*local_tls_type == GOT_TLS_GD) | 2029 if (*local_tls_type == GOT_TLS_GD) |
2010 s->size += GOT_ENTRY_SIZE; | 2030 s->size += GOT_ENTRY_SIZE; |
2011 if (info->shared) | 2031 if (info->shared) |
2012 srela->size += sizeof (Elf64_External_Rela); | 2032 srela->size += sizeof (Elf64_External_Rela); |
2013 } | 2033 } |
2014 else | 2034 else |
2015 *local_got = (bfd_vma) -1; | 2035 *local_got = (bfd_vma) -1; |
2016 } | 2036 } |
| 2037 |
| 2038 local_plt = elf_s390_local_plt (ibfd); |
| 2039 for (i = 0; i < symtab_hdr->sh_info; i++) |
| 2040 { |
| 2041 if (local_plt[i].plt.refcount > 0) |
| 2042 { |
| 2043 local_plt[i].plt.offset = htab->elf.iplt->size; |
| 2044 htab->elf.iplt->size += PLT_ENTRY_SIZE; |
| 2045 htab->elf.igotplt->size += GOT_ENTRY_SIZE; |
| 2046 htab->elf.irelplt->size += sizeof (Elf64_External_Rela); |
| 2047 } |
| 2048 else |
| 2049 local_plt[i].plt.offset = (bfd_vma) -1; |
| 2050 } |
2017 } | 2051 } |
2018 | 2052 |
2019 if (htab->tls_ldm_got.refcount > 0) | 2053 if (htab->tls_ldm_got.refcount > 0) |
2020 { | 2054 { |
2021 /* Allocate 2 got entries and 1 dynamic reloc for R_390_TLS_LDM64 | 2055 /* Allocate 2 got entries and 1 dynamic reloc for R_390_TLS_LDM64 |
2022 relocs. */ | 2056 relocs. */ |
2023 htab->tls_ldm_got.offset = htab->sgot->size; | 2057 htab->tls_ldm_got.offset = htab->elf.sgot->size; |
2024 htab->sgot->size += 2 * GOT_ENTRY_SIZE; | 2058 htab->elf.sgot->size += 2 * GOT_ENTRY_SIZE; |
2025 htab->srelgot->size += sizeof (Elf64_External_Rela); | 2059 htab->elf.srelgot->size += sizeof (Elf64_External_Rela); |
2026 } | 2060 } |
2027 else | 2061 else |
2028 htab->tls_ldm_got.offset = -1; | 2062 htab->tls_ldm_got.offset = -1; |
2029 | 2063 |
2030 /* Allocate global sym .plt and .got entries, and space for global | 2064 /* Allocate global sym .plt and .got entries, and space for global |
2031 sym dynamic relocs. */ | 2065 sym dynamic relocs. */ |
2032 elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info); | 2066 elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info); |
2033 | 2067 |
2034 /* We now have determined the sizes of the various dynamic sections. | 2068 /* We now have determined the sizes of the various dynamic sections. |
2035 Allocate memory for them. */ | 2069 Allocate memory for them. */ |
2036 relocs = FALSE; | 2070 relocs = FALSE; |
2037 for (s = dynobj->sections; s != NULL; s = s->next) | 2071 for (s = dynobj->sections; s != NULL; s = s->next) |
2038 { | 2072 { |
2039 if ((s->flags & SEC_LINKER_CREATED) == 0) | 2073 if ((s->flags & SEC_LINKER_CREATED) == 0) |
2040 continue; | 2074 continue; |
2041 | 2075 |
2042 if (s == htab->splt | 2076 if (s == htab->elf.splt |
2043 » || s == htab->sgot | 2077 » || s == htab->elf.sgot |
2044 » || s == htab->sgotplt | 2078 » || s == htab->elf.sgotplt |
2045 » || s == htab->sdynbss) | 2079 » || s == htab->sdynbss |
| 2080 » || s == htab->elf.iplt |
| 2081 » || s == htab->elf.igotplt |
| 2082 » || s == htab->irelifunc) |
2046 { | 2083 { |
2047 /* Strip this section if we don't need it; see the | 2084 /* Strip this section if we don't need it; see the |
2048 comment below. */ | 2085 comment below. */ |
2049 } | 2086 } |
2050 else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela")) | 2087 else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela")) |
2051 { | 2088 { |
2052 » if (s->size != 0 && s != htab->srelplt) | 2089 » if (s->size != 0 && s != htab->elf.srelplt) |
2053 relocs = TRUE; | 2090 relocs = TRUE; |
2054 | 2091 |
2055 /* We use the reloc_count field as a counter if we need | 2092 /* We use the reloc_count field as a counter if we need |
2056 to copy relocs into the output file. */ | 2093 to copy relocs into the output file. */ |
2057 s->reloc_count = 0; | 2094 s->reloc_count = 0; |
2058 } | 2095 } |
2059 else | 2096 else |
2060 { | 2097 { |
2061 /* It's not one of our sections, so don't allocate space. */ | 2098 /* It's not one of our sections, so don't allocate space. */ |
2062 continue; | 2099 continue; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2100 dynamic linker and used by the debugger. */ | 2137 dynamic linker and used by the debugger. */ |
2101 #define add_dynamic_entry(TAG, VAL) \ | 2138 #define add_dynamic_entry(TAG, VAL) \ |
2102 _bfd_elf_add_dynamic_entry (info, TAG, VAL) | 2139 _bfd_elf_add_dynamic_entry (info, TAG, VAL) |
2103 | 2140 |
2104 if (info->executable) | 2141 if (info->executable) |
2105 { | 2142 { |
2106 if (!add_dynamic_entry (DT_DEBUG, 0)) | 2143 if (!add_dynamic_entry (DT_DEBUG, 0)) |
2107 return FALSE; | 2144 return FALSE; |
2108 } | 2145 } |
2109 | 2146 |
2110 if (htab->splt->size != 0) | 2147 if (htab->elf.splt->size != 0) |
2111 { | 2148 { |
2112 if (!add_dynamic_entry (DT_PLTGOT, 0) | 2149 if (!add_dynamic_entry (DT_PLTGOT, 0) |
2113 || !add_dynamic_entry (DT_PLTRELSZ, 0) | 2150 || !add_dynamic_entry (DT_PLTRELSZ, 0) |
2114 || !add_dynamic_entry (DT_PLTREL, DT_RELA) | 2151 || !add_dynamic_entry (DT_PLTREL, DT_RELA) |
2115 || !add_dynamic_entry (DT_JMPREL, 0)) | 2152 || !add_dynamic_entry (DT_JMPREL, 0)) |
2116 return FALSE; | 2153 return FALSE; |
2117 } | 2154 } |
2118 | 2155 |
2119 if (relocs) | 2156 if (relocs) |
2120 { | 2157 { |
2121 if (!add_dynamic_entry (DT_RELA, 0) | 2158 if (!add_dynamic_entry (DT_RELA, 0) |
2122 || !add_dynamic_entry (DT_RELASZ, 0) | 2159 || !add_dynamic_entry (DT_RELASZ, 0) |
2123 || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela))) | 2160 || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela))) |
2124 return FALSE; | 2161 return FALSE; |
2125 | 2162 |
2126 /* If any dynamic relocs apply to a read-only section, | 2163 /* If any dynamic relocs apply to a read-only section, |
2127 then we need a DT_TEXTREL entry. */ | 2164 then we need a DT_TEXTREL entry. */ |
2128 if ((info->flags & DF_TEXTREL) == 0) | 2165 if ((info->flags & DF_TEXTREL) == 0) |
2129 elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, | 2166 elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, |
2130 » » » » (PTR) info); | 2167 » » » » info); |
2131 | 2168 |
2132 if ((info->flags & DF_TEXTREL) != 0) | 2169 if ((info->flags & DF_TEXTREL) != 0) |
2133 { | 2170 { |
2134 if (!add_dynamic_entry (DT_TEXTREL, 0)) | 2171 if (!add_dynamic_entry (DT_TEXTREL, 0)) |
2135 return FALSE; | 2172 return FALSE; |
2136 } | 2173 } |
2137 } | 2174 } |
2138 } | 2175 } |
2139 #undef add_dynamic_entry | 2176 #undef add_dynamic_entry |
2140 | 2177 |
2141 return TRUE; | 2178 return TRUE; |
2142 } | 2179 } |
2143 | 2180 |
2144 /* Return the base VMA address which should be subtracted from real addresses | 2181 /* Return the base VMA address which should be subtracted from real addresses |
2145 when resolving @dtpoff relocation. | 2182 when resolving @dtpoff relocation. |
2146 This is PT_TLS segment p_vaddr. */ | 2183 This is PT_TLS segment p_vaddr. */ |
2147 | 2184 |
2148 static bfd_vma | 2185 static bfd_vma |
2149 dtpoff_base (info) | 2186 dtpoff_base (struct bfd_link_info *info) |
2150 struct bfd_link_info *info; | |
2151 { | 2187 { |
2152 /* If tls_sec is NULL, we should have signalled an error already. */ | 2188 /* If tls_sec is NULL, we should have signalled an error already. */ |
2153 if (elf_hash_table (info)->tls_sec == NULL) | 2189 if (elf_hash_table (info)->tls_sec == NULL) |
2154 return 0; | 2190 return 0; |
2155 return elf_hash_table (info)->tls_sec->vma; | 2191 return elf_hash_table (info)->tls_sec->vma; |
2156 } | 2192 } |
2157 | 2193 |
2158 /* Return the relocation value for @tpoff relocation | 2194 /* Return the relocation value for @tpoff relocation |
2159 if STT_TLS virtual address is ADDRESS. */ | 2195 if STT_TLS virtual address is ADDRESS. */ |
2160 | 2196 |
2161 static bfd_vma | 2197 static bfd_vma |
2162 tpoff (info, address) | 2198 tpoff (struct bfd_link_info *info, bfd_vma address) |
2163 struct bfd_link_info *info; | |
2164 bfd_vma address; | |
2165 { | 2199 { |
2166 struct elf_link_hash_table *htab = elf_hash_table (info); | 2200 struct elf_link_hash_table *htab = elf_hash_table (info); |
2167 | 2201 |
2168 /* If tls_sec is NULL, we should have signalled an error already. */ | 2202 /* If tls_sec is NULL, we should have signalled an error already. */ |
2169 if (htab->tls_sec == NULL) | 2203 if (htab->tls_sec == NULL) |
2170 return 0; | 2204 return 0; |
2171 return htab->tls_size + htab->tls_sec->vma - address; | 2205 return htab->tls_size + htab->tls_sec->vma - address; |
2172 } | 2206 } |
2173 | 2207 |
2174 /* Complain if TLS instruction relocation is against an invalid | 2208 /* Complain if TLS instruction relocation is against an invalid |
2175 instruction. */ | 2209 instruction. */ |
2176 | 2210 |
2177 static void | 2211 static void |
2178 invalid_tls_insn (input_bfd, input_section, rel) | 2212 invalid_tls_insn (bfd *input_bfd, |
2179 bfd *input_bfd; | 2213 » » asection *input_section, |
2180 asection *input_section; | 2214 » » Elf_Internal_Rela *rel) |
2181 Elf_Internal_Rela *rel; | |
2182 { | 2215 { |
2183 reloc_howto_type *howto; | 2216 reloc_howto_type *howto; |
2184 | 2217 |
2185 howto = elf_howto_table + ELF64_R_TYPE (rel->r_info); | 2218 howto = elf_howto_table + ELF64_R_TYPE (rel->r_info); |
2186 (*_bfd_error_handler) | 2219 (*_bfd_error_handler) |
2187 (_("%B(%A+0x%lx): invalid instruction for TLS relocation %s"), | 2220 (_("%B(%A+0x%lx): invalid instruction for TLS relocation %s"), |
2188 input_bfd, | 2221 input_bfd, |
2189 input_section, | 2222 input_section, |
2190 (long) rel->r_offset, | 2223 (long) rel->r_offset, |
2191 howto->name); | 2224 howto->name); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2229 reloc_howto_type *howto; | 2262 reloc_howto_type *howto; |
2230 unsigned long r_symndx; | 2263 unsigned long r_symndx; |
2231 struct elf_link_hash_entry *h; | 2264 struct elf_link_hash_entry *h; |
2232 Elf_Internal_Sym *sym; | 2265 Elf_Internal_Sym *sym; |
2233 asection *sec; | 2266 asection *sec; |
2234 bfd_vma off; | 2267 bfd_vma off; |
2235 bfd_vma relocation; | 2268 bfd_vma relocation; |
2236 bfd_boolean unresolved_reloc; | 2269 bfd_boolean unresolved_reloc; |
2237 bfd_reloc_status_type r; | 2270 bfd_reloc_status_type r; |
2238 int tls_type; | 2271 int tls_type; |
| 2272 asection *base_got = htab->elf.sgot; |
2239 | 2273 |
2240 r_type = ELF64_R_TYPE (rel->r_info); | 2274 r_type = ELF64_R_TYPE (rel->r_info); |
2241 if (r_type == (int) R_390_GNU_VTINHERIT | 2275 if (r_type == (int) R_390_GNU_VTINHERIT |
2242 || r_type == (int) R_390_GNU_VTENTRY) | 2276 || r_type == (int) R_390_GNU_VTENTRY) |
2243 continue; | 2277 continue; |
2244 if (r_type >= (int) R_390_max) | 2278 if (r_type >= (int) R_390_max) |
2245 { | 2279 { |
2246 bfd_set_error (bfd_error_bad_value); | 2280 bfd_set_error (bfd_error_bad_value); |
2247 return FALSE; | 2281 return FALSE; |
2248 } | 2282 } |
2249 | 2283 |
2250 howto = elf_howto_table + r_type; | 2284 howto = elf_howto_table + r_type; |
2251 r_symndx = ELF64_R_SYM (rel->r_info); | 2285 r_symndx = ELF64_R_SYM (rel->r_info); |
2252 | 2286 |
2253 h = NULL; | 2287 h = NULL; |
2254 sym = NULL; | 2288 sym = NULL; |
2255 sec = NULL; | 2289 sec = NULL; |
2256 unresolved_reloc = FALSE; | 2290 unresolved_reloc = FALSE; |
2257 if (r_symndx < symtab_hdr->sh_info) | 2291 if (r_symndx < symtab_hdr->sh_info) |
2258 { | 2292 { |
2259 sym = local_syms + r_symndx; | 2293 sym = local_syms + r_symndx; |
2260 sec = local_sections[r_symndx]; | 2294 sec = local_sections[r_symndx]; |
2261 » relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); | 2295 |
| 2296 » if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC) |
| 2297 » { |
| 2298 » struct plt_entry *local_plt = elf_s390_local_plt (input_bfd); |
| 2299 » if (local_plt == NULL) |
| 2300 » » return FALSE; |
| 2301 |
| 2302 » /* Address of the PLT slot. */ |
| 2303 » relocation = (htab->elf.iplt->output_section->vma |
| 2304 » » » + htab->elf.iplt->output_offset |
| 2305 » » » + local_plt[r_symndx].plt.offset); |
| 2306 |
| 2307 » switch (r_type) |
| 2308 » » { |
| 2309 » » case R_390_GOTPLT12: |
| 2310 » » case R_390_GOTPLT16: |
| 2311 » » case R_390_GOTPLT20: |
| 2312 » » case R_390_GOTPLT32: |
| 2313 » » case R_390_GOTPLT64: |
| 2314 » » case R_390_GOTPLTENT: |
| 2315 » » case R_390_GOT12: |
| 2316 » » case R_390_GOT16: |
| 2317 » » case R_390_GOT20: |
| 2318 » » case R_390_GOT32: |
| 2319 » » case R_390_GOT64: |
| 2320 » » case R_390_GOTENT: |
| 2321 » » { |
| 2322 » » /* Write the PLT slot address into the GOT slot. */ |
| 2323 » » bfd_put_64 (output_bfd, relocation, |
| 2324 » » » » htab->elf.sgot->contents + |
| 2325 » » » » local_got_offsets[r_symndx]); |
| 2326 » » relocation = (local_got_offsets[r_symndx] + |
| 2327 » » » » htab->elf.sgot->output_offset); |
| 2328 |
| 2329 » » if (r_type == R_390_GOTENT || r_type == R_390_GOTPLTENT) |
| 2330 » » relocation += htab->elf.sgot->output_section->vma; |
| 2331 » » break; |
| 2332 » » } |
| 2333 » » default: |
| 2334 » » break; |
| 2335 » » } |
| 2336 » /* The output section is needed later in |
| 2337 » » finish_dynamic_section when creating the dynamic |
| 2338 » » relocation. */ |
| 2339 » local_plt[r_symndx].sec = sec; |
| 2340 » goto do_relocation; |
| 2341 » } |
| 2342 » else |
| 2343 » relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); |
2262 } | 2344 } |
2263 else | 2345 else |
2264 { | 2346 { |
2265 bfd_boolean warned ATTRIBUTE_UNUSED; | 2347 bfd_boolean warned ATTRIBUTE_UNUSED; |
2266 | 2348 |
2267 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, | 2349 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, |
2268 r_symndx, symtab_hdr, sym_hashes, | 2350 r_symndx, symtab_hdr, sym_hashes, |
2269 h, sec, relocation, | 2351 h, sec, relocation, |
2270 unresolved_reloc, warned); | 2352 unresolved_reloc, warned); |
2271 } | 2353 } |
2272 | 2354 |
2273 if (sec != NULL && elf_discarded_section (sec)) | 2355 if (sec != NULL && discarded_section (sec)) |
2274 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, | 2356 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, |
2275 » » » » » rel, relend, howto, contents); | 2357 » » » » » rel, 1, relend, howto, 0, contents); |
2276 | 2358 |
2277 if (info->relocatable) | 2359 if (info->relocatable) |
2278 continue; | 2360 continue; |
2279 | 2361 |
2280 switch (r_type) | 2362 switch (r_type) |
2281 { | 2363 { |
2282 case R_390_GOTPLT12: | 2364 case R_390_GOTPLT12: |
2283 case R_390_GOTPLT16: | 2365 case R_390_GOTPLT16: |
2284 case R_390_GOTPLT20: | 2366 case R_390_GOTPLT20: |
2285 case R_390_GOTPLT32: | 2367 case R_390_GOTPLT32: |
2286 case R_390_GOTPLT64: | 2368 case R_390_GOTPLT64: |
2287 case R_390_GOTPLTENT: | 2369 case R_390_GOTPLTENT: |
2288 /* There are three cases for a GOTPLT relocation. 1) The | 2370 /* There are three cases for a GOTPLT relocation. 1) The |
2289 relocation is against the jump slot entry of a plt that | 2371 relocation is against the jump slot entry of a plt that |
2290 will get emitted to the output file. 2) The relocation | 2372 will get emitted to the output file. 2) The relocation |
2291 is against the jump slot of a plt entry that has been | 2373 is against the jump slot of a plt entry that has been |
2292 removed. elf_s390_adjust_gotplt has created a GOT entry | 2374 removed. elf_s390_adjust_gotplt has created a GOT entry |
2293 as replacement. 3) The relocation is against a local symbol. | 2375 as replacement. 3) The relocation is against a local symbol. |
2294 Cases 2) and 3) are the same as the GOT relocation code | 2376 Cases 2) and 3) are the same as the GOT relocation code |
2295 so we just have to test for case 1 and fall through for | 2377 so we just have to test for case 1 and fall through for |
2296 the other two. */ | 2378 the other two. */ |
2297 if (h != NULL && h->plt.offset != (bfd_vma) -1) | 2379 if (h != NULL && h->plt.offset != (bfd_vma) -1) |
2298 { | 2380 { |
2299 bfd_vma plt_index; | 2381 bfd_vma plt_index; |
2300 | 2382 |
2301 » /* Calc. index no. | 2383 » if (s390_is_ifunc_symbol_p (h)) |
2302 » » Current offset - size first entry / entry size. */ | 2384 » » { |
2303 » plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) / | 2385 » » plt_index = h->plt.offset / PLT_ENTRY_SIZE; |
2304 » » PLT_ENTRY_SIZE; | 2386 » » relocation = (plt_index * GOT_ENTRY_SIZE + |
| 2387 » » » » htab->elf.igotplt->output_offset); |
| 2388 » » if (r_type == R_390_GOTPLTENT) |
| 2389 » » relocation += htab->elf.igotplt->output_section->vma; |
| 2390 » » } |
| 2391 » else |
| 2392 » » { |
| 2393 » » /* Calc. index no. |
| 2394 » » Current offset - size first entry / entry size. */ |
| 2395 » » plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) / |
| 2396 » » PLT_ENTRY_SIZE; |
2305 | 2397 |
2306 » /* Offset in GOT is PLT index plus GOT headers(3) times 4, | 2398 » » /* Offset in GOT is PLT index plus GOT headers(3) |
2307 » » addr & GOT addr. */ | 2399 » » times 4, addr & GOT addr. */ |
2308 » relocation = (plt_index + 3) * GOT_ENTRY_SIZE; | 2400 » » relocation = (plt_index + 3) * GOT_ENTRY_SIZE; |
| 2401 » » if (r_type == R_390_GOTPLTENT) |
| 2402 » » relocation += htab->elf.sgot->output_section->vma; |
| 2403 » » } |
2309 unresolved_reloc = FALSE; | 2404 unresolved_reloc = FALSE; |
2310 | |
2311 if (r_type == R_390_GOTPLTENT) | |
2312 relocation += htab->sgot->output_section->vma; | |
2313 break; | 2405 break; |
2314 } | 2406 } |
2315 /* Fall through. */ | 2407 /* Fall through. */ |
2316 | 2408 |
2317 case R_390_GOT12: | 2409 case R_390_GOT12: |
2318 case R_390_GOT16: | 2410 case R_390_GOT16: |
2319 case R_390_GOT20: | 2411 case R_390_GOT20: |
2320 case R_390_GOT32: | 2412 case R_390_GOT32: |
2321 case R_390_GOT64: | 2413 case R_390_GOT64: |
2322 case R_390_GOTENT: | 2414 case R_390_GOTENT: |
2323 /* Relocation is to the entry for this symbol in the global | 2415 /* Relocation is to the entry for this symbol in the global |
2324 offset table. */ | 2416 offset table. */ |
2325 » if (htab->sgot == NULL) | 2417 » if (base_got == NULL) |
2326 abort (); | 2418 abort (); |
2327 | 2419 |
2328 if (h != NULL) | 2420 if (h != NULL) |
2329 { | 2421 { |
2330 bfd_boolean dyn; | 2422 bfd_boolean dyn; |
2331 | 2423 |
2332 off = h->got.offset; | 2424 off = h->got.offset; |
2333 dyn = htab->elf.dynamic_sections_created; | 2425 dyn = htab->elf.dynamic_sections_created; |
2334 » if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) | 2426 |
2335 » » || (info->shared | 2427 » if (s390_is_ifunc_symbol_p (h)) |
2336 » » && SYMBOL_REFERENCES_LOCAL (info, h)) | 2428 » » { |
2337 » » || (ELF_ST_VISIBILITY (h->other) | 2429 » » BFD_ASSERT (h->plt.offset != (bfd_vma) -1); |
2338 » » && h->root.type == bfd_link_hash_undefweak)) | 2430 » » if (off == (bfd_vma)-1) |
| 2431 » » { |
| 2432 » » /* No explicit GOT usage so redirect to the |
| 2433 » » » got.iplt slot. */ |
| 2434 » » base_got = htab->elf.igotplt; |
| 2435 » » off = h->plt.offset / PLT_ENTRY_SIZE * GOT_ENTRY_SIZE; |
| 2436 » » } |
| 2437 » » else |
| 2438 » » { |
| 2439 » » /* Explicit GOT slots must contain the address |
| 2440 » » » of the PLT slot. This will be handled in |
| 2441 » » » finish_dynamic_symbol. */ |
| 2442 » » } |
| 2443 » » } |
| 2444 » else if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) |
| 2445 » » || (info->shared |
| 2446 » » » && SYMBOL_REFERENCES_LOCAL (info, h)) |
| 2447 » » || (ELF_ST_VISIBILITY (h->other) |
| 2448 » » » && h->root.type == bfd_link_hash_undefweak)) |
2339 { | 2449 { |
2340 /* This is actually a static link, or it is a | 2450 /* This is actually a static link, or it is a |
2341 -Bsymbolic link and the symbol is defined | 2451 -Bsymbolic link and the symbol is defined |
2342 locally, or the symbol was forced to be local | 2452 locally, or the symbol was forced to be local |
2343 because of a version file. We must initialize | 2453 because of a version file. We must initialize |
2344 this entry in the global offset table. Since the | 2454 this entry in the global offset table. Since the |
2345 offset must always be a multiple of 2, we use the | 2455 offset must always be a multiple of 2, we use the |
2346 least significant bit to record whether we have | 2456 least significant bit to record whether we have |
2347 initialized it already. | 2457 initialized it already. |
2348 | 2458 |
2349 When doing a dynamic link, we create a .rel.got | 2459 When doing a dynamic link, we create a .rel.got |
2350 relocation entry to initialize the value. This | 2460 relocation entry to initialize the value. This |
2351 is done in the finish_dynamic_symbol routine. */ | 2461 is done in the finish_dynamic_symbol routine. */ |
2352 if ((off & 1) != 0) | 2462 if ((off & 1) != 0) |
2353 off &= ~1; | 2463 off &= ~1; |
2354 else | 2464 else |
2355 { | 2465 { |
2356 bfd_put_64 (output_bfd, relocation, | 2466 bfd_put_64 (output_bfd, relocation, |
2357 » » » » htab->sgot->contents + off); | 2467 » » » » base_got->contents + off); |
2358 h->got.offset |= 1; | 2468 h->got.offset |= 1; |
2359 } | 2469 } |
2360 } | 2470 } |
2361 else | 2471 else |
2362 unresolved_reloc = FALSE; | 2472 unresolved_reloc = FALSE; |
2363 } | 2473 } |
2364 else | 2474 else |
2365 { | 2475 { |
2366 if (local_got_offsets == NULL) | 2476 if (local_got_offsets == NULL) |
2367 abort (); | 2477 abort (); |
2368 | 2478 |
2369 off = local_got_offsets[r_symndx]; | 2479 off = local_got_offsets[r_symndx]; |
2370 | 2480 |
2371 /* The offset must always be a multiple of 8. We use | 2481 /* The offset must always be a multiple of 8. We use |
2372 the least significant bit to record whether we have | 2482 the least significant bit to record whether we have |
2373 already generated the necessary reloc. */ | 2483 already generated the necessary reloc. */ |
2374 if ((off & 1) != 0) | 2484 if ((off & 1) != 0) |
2375 off &= ~1; | 2485 off &= ~1; |
2376 else | 2486 else |
2377 { | 2487 { |
2378 bfd_put_64 (output_bfd, relocation, | 2488 bfd_put_64 (output_bfd, relocation, |
2379 » » » htab->sgot->contents + off); | 2489 » » » htab->elf.sgot->contents + off); |
2380 | 2490 |
2381 if (info->shared) | 2491 if (info->shared) |
2382 { | 2492 { |
2383 asection *s; | 2493 asection *s; |
2384 Elf_Internal_Rela outrel; | 2494 Elf_Internal_Rela outrel; |
2385 bfd_byte *loc; | 2495 bfd_byte *loc; |
2386 | 2496 |
2387 » » s = htab->srelgot; | 2497 » » s = htab->elf.srelgot; |
2388 if (s == NULL) | 2498 if (s == NULL) |
2389 abort (); | 2499 abort (); |
2390 | 2500 |
2391 » » outrel.r_offset = (htab->sgot->output_section->vma | 2501 » » outrel.r_offset = (htab->elf.sgot->output_section->vma |
2392 » » » » » + htab->sgot->output_offset | 2502 » » » » » + htab->elf.sgot->output_offset |
2393 + off); | 2503 + off); |
2394 outrel.r_info = ELF64_R_INFO (0, R_390_RELATIVE); | 2504 outrel.r_info = ELF64_R_INFO (0, R_390_RELATIVE); |
2395 outrel.r_addend = relocation; | 2505 outrel.r_addend = relocation; |
2396 loc = s->contents; | 2506 loc = s->contents; |
2397 loc += s->reloc_count++ * sizeof (Elf64_External_Rela); | 2507 loc += s->reloc_count++ * sizeof (Elf64_External_Rela); |
2398 bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc); | 2508 bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc); |
2399 } | 2509 } |
2400 | 2510 |
2401 local_got_offsets[r_symndx] |= 1; | 2511 local_got_offsets[r_symndx] |= 1; |
2402 } | 2512 } |
2403 } | 2513 } |
2404 | 2514 |
2405 if (off >= (bfd_vma) -2) | 2515 if (off >= (bfd_vma) -2) |
2406 abort (); | 2516 abort (); |
2407 | 2517 |
2408 » relocation = htab->sgot->output_offset + off; | 2518 » relocation = base_got->output_offset + off; |
2409 | 2519 |
2410 /* For @GOTENT the relocation is against the offset between | 2520 /* For @GOTENT the relocation is against the offset between |
2411 the instruction and the symbols entry in the GOT and not | 2521 the instruction and the symbols entry in the GOT and not |
2412 between the start of the GOT and the symbols entry. We | 2522 between the start of the GOT and the symbols entry. We |
2413 add the vma of the GOT to get the correct value. */ | 2523 add the vma of the GOT to get the correct value. */ |
2414 if ( r_type == R_390_GOTENT | 2524 if ( r_type == R_390_GOTENT |
2415 || r_type == R_390_GOTPLTENT) | 2525 || r_type == R_390_GOTPLTENT) |
2416 » relocation += htab->sgot->output_section->vma; | 2526 » relocation += base_got->output_section->vma; |
2417 | 2527 |
2418 break; | 2528 break; |
2419 | 2529 |
2420 case R_390_GOTOFF16: | 2530 case R_390_GOTOFF16: |
2421 case R_390_GOTOFF32: | 2531 case R_390_GOTOFF32: |
2422 case R_390_GOTOFF64: | 2532 case R_390_GOTOFF64: |
2423 /* Relocation is relative to the start of the global offset | 2533 /* Relocation is relative to the start of the global offset |
2424 table. */ | 2534 table. */ |
2425 | 2535 |
2426 /* Note that sgot->output_offset is not involved in this | 2536 /* Note that sgot->output_offset is not involved in this |
2427 calculation. We always want the start of .got. If we | 2537 calculation. We always want the start of .got. If we |
2428 defined _GLOBAL_OFFSET_TABLE in a different way, as is | 2538 defined _GLOBAL_OFFSET_TABLE in a different way, as is |
2429 permitted by the ABI, we might have to change this | 2539 permitted by the ABI, we might have to change this |
2430 calculation. */ | 2540 calculation. */ |
2431 » relocation -= htab->sgot->output_section->vma; | 2541 » relocation -= htab->elf.sgot->output_section->vma; |
2432 break; | 2542 break; |
2433 | 2543 |
2434 case R_390_GOTPC: | 2544 case R_390_GOTPC: |
2435 case R_390_GOTPCDBL: | 2545 case R_390_GOTPCDBL: |
2436 /* Use global offset table as symbol value. */ | 2546 /* Use global offset table as symbol value. */ |
2437 » relocation = htab->sgot->output_section->vma; | 2547 » relocation = htab->elf.sgot->output_section->vma; |
2438 unresolved_reloc = FALSE; | 2548 unresolved_reloc = FALSE; |
2439 break; | 2549 break; |
2440 | 2550 |
2441 case R_390_PLT16DBL: | 2551 case R_390_PLT16DBL: |
2442 case R_390_PLT32: | 2552 case R_390_PLT32: |
2443 case R_390_PLT32DBL: | 2553 case R_390_PLT32DBL: |
2444 case R_390_PLT64: | 2554 case R_390_PLT64: |
2445 /* Relocation is to the entry for this symbol in the | 2555 /* Relocation is to the entry for this symbol in the |
2446 procedure linkage table. */ | 2556 procedure linkage table. */ |
2447 | 2557 |
2448 /* Resolve a PLT32 reloc against a local symbol directly, | 2558 /* Resolve a PLT32 reloc against a local symbol directly, |
2449 without using the procedure linkage table. */ | 2559 without using the procedure linkage table. */ |
2450 if (h == NULL) | 2560 if (h == NULL) |
2451 break; | 2561 break; |
2452 | 2562 |
2453 if (h->plt.offset == (bfd_vma) -1 | 2563 if (h->plt.offset == (bfd_vma) -1 |
2454 » || htab->splt == NULL) | 2564 » || (htab->elf.splt == NULL && htab->elf.iplt == NULL)) |
2455 { | 2565 { |
2456 /* We didn't make a PLT entry for this symbol. This | 2566 /* We didn't make a PLT entry for this symbol. This |
2457 happens when statically linking PIC code, or when | 2567 happens when statically linking PIC code, or when |
2458 using -Bsymbolic. */ | 2568 using -Bsymbolic. */ |
2459 break; | 2569 break; |
2460 } | 2570 } |
2461 | 2571 » if (s390_is_ifunc_symbol_p (h)) |
2462 » relocation = (htab->splt->output_section->vma | 2572 » relocation = (htab->elf.iplt->output_section->vma |
2463 » » » + htab->splt->output_offset | 2573 » » » + htab->elf.iplt->output_offset |
2464 » » » + h->plt.offset); | 2574 » » » + h->plt.offset); |
| 2575 » else |
| 2576 » relocation = (htab->elf.splt->output_section->vma |
| 2577 » » » + htab->elf.splt->output_offset |
| 2578 » » » + h->plt.offset); |
2465 unresolved_reloc = FALSE; | 2579 unresolved_reloc = FALSE; |
2466 break; | 2580 break; |
2467 | 2581 |
2468 case R_390_PLTOFF16: | 2582 case R_390_PLTOFF16: |
2469 case R_390_PLTOFF32: | 2583 case R_390_PLTOFF32: |
2470 case R_390_PLTOFF64: | 2584 case R_390_PLTOFF64: |
2471 /* Relocation is to the entry for this symbol in the | 2585 /* Relocation is to the entry for this symbol in the |
2472 procedure linkage table relative to the start of the GOT. */ | 2586 procedure linkage table relative to the start of the GOT. */ |
2473 | 2587 |
2474 /* For local symbols or if we didn't make a PLT entry for | 2588 /* For local symbols or if we didn't make a PLT entry for |
2475 this symbol resolve the symbol directly. */ | 2589 this symbol resolve the symbol directly. */ |
2476 if ( h == NULL | 2590 if ( h == NULL |
2477 || h->plt.offset == (bfd_vma) -1 | 2591 || h->plt.offset == (bfd_vma) -1 |
2478 » || htab->splt == NULL) | 2592 » || htab->elf.splt == NULL) |
2479 { | 2593 { |
2480 » relocation -= htab->sgot->output_section->vma; | 2594 » relocation -= htab->elf.sgot->output_section->vma; |
2481 break; | 2595 break; |
2482 } | 2596 } |
2483 | 2597 |
2484 » relocation = (htab->splt->output_section->vma | 2598 » if (s390_is_ifunc_symbol_p (h)) |
2485 » » » + htab->splt->output_offset | 2599 » relocation = (htab->elf.iplt->output_section->vma |
2486 » » » + h->plt.offset | 2600 » » » + htab->elf.iplt->output_offset |
2487 » » » - htab->sgot->output_section->vma); | 2601 » » » + h->plt.offset |
| 2602 » » » - htab->elf.sgot->output_section->vma); |
| 2603 » else |
| 2604 » relocation = (htab->elf.splt->output_section->vma |
| 2605 » » » + htab->elf.splt->output_offset |
| 2606 » » » + h->plt.offset |
| 2607 » » » - htab->elf.sgot->output_section->vma); |
2488 unresolved_reloc = FALSE; | 2608 unresolved_reloc = FALSE; |
2489 break; | 2609 break; |
2490 | 2610 |
2491 case R_390_8: | 2611 case R_390_8: |
2492 case R_390_16: | 2612 case R_390_16: |
2493 case R_390_32: | 2613 case R_390_32: |
2494 case R_390_64: | 2614 case R_390_64: |
2495 case R_390_PC16: | 2615 case R_390_PC16: |
2496 case R_390_PC16DBL: | 2616 case R_390_PC16DBL: |
2497 case R_390_PC32: | 2617 case R_390_PC32: |
2498 case R_390_PC32DBL: | 2618 case R_390_PC32DBL: |
2499 case R_390_PC64: | 2619 case R_390_PC64: |
| 2620 |
| 2621 if (h != NULL |
| 2622 && s390_is_ifunc_symbol_p (h) |
| 2623 && h->def_regular) |
| 2624 { |
| 2625 if (!info->shared || !h->non_got_ref) |
| 2626 { |
| 2627 /* For a non-shared object STT_GNU_IFUNC symbol must |
| 2628 go through PLT. */ |
| 2629 relocation = (htab->elf.iplt->output_section->vma |
| 2630 + htab->elf.iplt->output_offset |
| 2631 + h ->plt.offset); |
| 2632 goto do_relocation; |
| 2633 } |
| 2634 else |
| 2635 { |
| 2636 /* For shared objects a runtime relocation is needed. */ |
| 2637 |
| 2638 Elf_Internal_Rela outrel; |
| 2639 asection *sreloc; |
| 2640 |
| 2641 /* Need a dynamic relocation to get the real function |
| 2642 address. */ |
| 2643 outrel.r_offset = _bfd_elf_section_offset (output_bfd, |
| 2644 info, |
| 2645 input_section, |
| 2646 rel->r_offset); |
| 2647 if (outrel.r_offset == (bfd_vma) -1 |
| 2648 || outrel.r_offset == (bfd_vma) -2) |
| 2649 abort (); |
| 2650 |
| 2651 outrel.r_offset += (input_section->output_section->vma |
| 2652 + input_section->output_offset); |
| 2653 |
| 2654 if (h->dynindx == -1 |
| 2655 || h->forced_local |
| 2656 || info->executable) |
| 2657 { |
| 2658 /* This symbol is resolved locally. */ |
| 2659 outrel.r_info = ELF64_R_INFO (0, R_390_IRELATIVE); |
| 2660 outrel.r_addend = (h->root.u.def.value |
| 2661 + h->root.u.def.section->output_section
->vma |
| 2662 + h->root.u.def.section->output_offset)
; |
| 2663 } |
| 2664 else |
| 2665 { |
| 2666 outrel.r_info = ELF64_R_INFO (h->dynindx, r_type); |
| 2667 outrel.r_addend = 0; |
| 2668 } |
| 2669 |
| 2670 sreloc = htab->elf.irelifunc; |
| 2671 elf_append_rela (output_bfd, sreloc, &outrel); |
| 2672 |
| 2673 /* If this reloc is against an external symbol, we |
| 2674 do not want to fiddle with the addend. Otherwise, |
| 2675 we need to include the symbol value so that it |
| 2676 becomes an addend for the dynamic reloc. For an |
| 2677 internal symbol, we have updated addend. */ |
| 2678 continue; |
| 2679 } |
| 2680 } |
| 2681 |
2500 if ((input_section->flags & SEC_ALLOC) == 0) | 2682 if ((input_section->flags & SEC_ALLOC) == 0) |
2501 break; | 2683 break; |
2502 | 2684 |
2503 if ((info->shared | 2685 if ((info->shared |
2504 && (h == NULL | 2686 && (h == NULL |
2505 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT | 2687 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT |
2506 || h->root.type != bfd_link_hash_undefweak) | 2688 || h->root.type != bfd_link_hash_undefweak) |
2507 && ((r_type != R_390_PC16 | 2689 && ((r_type != R_390_PC16 |
2508 && r_type != R_390_PC16DBL | 2690 && r_type != R_390_PC16DBL |
2509 && r_type != R_390_PC32 | 2691 && r_type != R_390_PC32 |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2660 if (r_type == R_390_TLS_LE64) | 2842 if (r_type == R_390_TLS_LE64) |
2661 { | 2843 { |
2662 /* This relocation gets optimized away by the local exec | 2844 /* This relocation gets optimized away by the local exec |
2663 access optimization. */ | 2845 access optimization. */ |
2664 BFD_ASSERT (! unresolved_reloc); | 2846 BFD_ASSERT (! unresolved_reloc); |
2665 bfd_put_64 (output_bfd, -tpoff (info, relocation), | 2847 bfd_put_64 (output_bfd, -tpoff (info, relocation), |
2666 contents + rel->r_offset); | 2848 contents + rel->r_offset); |
2667 continue; | 2849 continue; |
2668 } | 2850 } |
2669 | 2851 |
2670 » if (htab->sgot == NULL) | 2852 » if (htab->elf.sgot == NULL) |
2671 abort (); | 2853 abort (); |
2672 | 2854 |
2673 if (h != NULL) | 2855 if (h != NULL) |
2674 off = h->got.offset; | 2856 off = h->got.offset; |
2675 else | 2857 else |
2676 { | 2858 { |
2677 if (local_got_offsets == NULL) | 2859 if (local_got_offsets == NULL) |
2678 abort (); | 2860 abort (); |
2679 | 2861 |
2680 off = local_got_offsets[r_symndx]; | 2862 off = local_got_offsets[r_symndx]; |
2681 } | 2863 } |
2682 | 2864 |
2683 emit_tls_relocs: | 2865 emit_tls_relocs: |
2684 | 2866 |
2685 if ((off & 1) != 0) | 2867 if ((off & 1) != 0) |
2686 off &= ~1; | 2868 off &= ~1; |
2687 else | 2869 else |
2688 { | 2870 { |
2689 Elf_Internal_Rela outrel; | 2871 Elf_Internal_Rela outrel; |
2690 bfd_byte *loc; | 2872 bfd_byte *loc; |
2691 int dr_type, indx; | 2873 int dr_type, indx; |
2692 | 2874 |
2693 » if (htab->srelgot == NULL) | 2875 » if (htab->elf.srelgot == NULL) |
2694 abort (); | 2876 abort (); |
2695 | 2877 |
2696 » outrel.r_offset = (htab->sgot->output_section->vma | 2878 » outrel.r_offset = (htab->elf.sgot->output_section->vma |
2697 » » » » + htab->sgot->output_offset + off); | 2879 » » » » + htab->elf.sgot->output_offset + off); |
2698 | 2880 |
2699 indx = h && h->dynindx != -1 ? h->dynindx : 0; | 2881 indx = h && h->dynindx != -1 ? h->dynindx : 0; |
2700 if (r_type == R_390_TLS_GD64) | 2882 if (r_type == R_390_TLS_GD64) |
2701 dr_type = R_390_TLS_DTPMOD; | 2883 dr_type = R_390_TLS_DTPMOD; |
2702 else | 2884 else |
2703 dr_type = R_390_TLS_TPOFF; | 2885 dr_type = R_390_TLS_TPOFF; |
2704 if (dr_type == R_390_TLS_TPOFF && indx == 0) | 2886 if (dr_type == R_390_TLS_TPOFF && indx == 0) |
2705 outrel.r_addend = relocation - dtpoff_base (info); | 2887 outrel.r_addend = relocation - dtpoff_base (info); |
2706 else | 2888 else |
2707 outrel.r_addend = 0; | 2889 outrel.r_addend = 0; |
2708 outrel.r_info = ELF64_R_INFO (indx, dr_type); | 2890 outrel.r_info = ELF64_R_INFO (indx, dr_type); |
2709 » loc = htab->srelgot->contents; | 2891 » loc = htab->elf.srelgot->contents; |
2710 » loc += htab->srelgot->reloc_count++ | 2892 » loc += htab->elf.srelgot->reloc_count++ |
2711 * sizeof (Elf64_External_Rela); | 2893 * sizeof (Elf64_External_Rela); |
2712 bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc); | 2894 bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc); |
2713 | 2895 |
2714 if (r_type == R_390_TLS_GD64) | 2896 if (r_type == R_390_TLS_GD64) |
2715 { | 2897 { |
2716 if (indx == 0) | 2898 if (indx == 0) |
2717 { | 2899 { |
2718 BFD_ASSERT (! unresolved_reloc); | 2900 BFD_ASSERT (! unresolved_reloc); |
2719 bfd_put_64 (output_bfd, | 2901 bfd_put_64 (output_bfd, |
2720 relocation - dtpoff_base (info), | 2902 relocation - dtpoff_base (info), |
2721 » » » » htab->sgot->contents + off + GOT_ENTRY_SIZE); | 2903 » » » » htab->elf.sgot->contents + off + GOT_ENTRY_SIZ
E); |
2722 } | 2904 } |
2723 else | 2905 else |
2724 { | 2906 { |
2725 outrel.r_info = ELF64_R_INFO (indx, R_390_TLS_DTPOFF); | 2907 outrel.r_info = ELF64_R_INFO (indx, R_390_TLS_DTPOFF); |
2726 outrel.r_offset += GOT_ENTRY_SIZE; | 2908 outrel.r_offset += GOT_ENTRY_SIZE; |
2727 outrel.r_addend = 0; | 2909 outrel.r_addend = 0; |
2728 » » htab->srelgot->reloc_count++; | 2910 » » htab->elf.srelgot->reloc_count++; |
2729 loc += sizeof (Elf64_External_Rela); | 2911 loc += sizeof (Elf64_External_Rela); |
2730 bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc); | 2912 bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc); |
2731 } | 2913 } |
2732 } | 2914 } |
2733 | 2915 |
2734 if (h != NULL) | 2916 if (h != NULL) |
2735 h->got.offset |= 1; | 2917 h->got.offset |= 1; |
2736 else | 2918 else |
2737 local_got_offsets[r_symndx] |= 1; | 2919 local_got_offsets[r_symndx] |= 1; |
2738 } | 2920 } |
2739 | 2921 |
2740 if (off >= (bfd_vma) -2) | 2922 if (off >= (bfd_vma) -2) |
2741 abort (); | 2923 abort (); |
2742 if (r_type == ELF64_R_TYPE (rel->r_info)) | 2924 if (r_type == ELF64_R_TYPE (rel->r_info)) |
2743 { | 2925 { |
2744 » relocation = htab->sgot->output_offset + off; | 2926 » relocation = htab->elf.sgot->output_offset + off; |
2745 if (r_type == R_390_TLS_IE64 || r_type == R_390_TLS_IEENT) | 2927 if (r_type == R_390_TLS_IE64 || r_type == R_390_TLS_IEENT) |
2746 » » relocation += htab->sgot->output_section->vma; | 2928 » » relocation += htab->elf.sgot->output_section->vma; |
2747 unresolved_reloc = FALSE; | 2929 unresolved_reloc = FALSE; |
2748 } | 2930 } |
2749 else | 2931 else |
2750 { | 2932 { |
2751 » bfd_put_64 (output_bfd, htab->sgot->output_offset + off, | 2933 » bfd_put_64 (output_bfd, htab->elf.sgot->output_offset + off, |
2752 contents + rel->r_offset); | 2934 contents + rel->r_offset); |
2753 continue; | 2935 continue; |
2754 } | 2936 } |
2755 break; | 2937 break; |
2756 | 2938 |
2757 case R_390_TLS_GOTIE12: | 2939 case R_390_TLS_GOTIE12: |
2758 case R_390_TLS_GOTIE20: | 2940 case R_390_TLS_GOTIE20: |
2759 case R_390_TLS_IEENT: | 2941 case R_390_TLS_IEENT: |
2760 if (h == NULL) | 2942 if (h == NULL) |
2761 { | 2943 { |
2762 if (local_got_offsets == NULL) | 2944 if (local_got_offsets == NULL) |
2763 abort(); | 2945 abort(); |
2764 off = local_got_offsets[r_symndx]; | 2946 off = local_got_offsets[r_symndx]; |
2765 if (info->shared) | 2947 if (info->shared) |
2766 goto emit_tls_relocs; | 2948 goto emit_tls_relocs; |
2767 } | 2949 } |
2768 else | 2950 else |
2769 { | 2951 { |
2770 off = h->got.offset; | 2952 off = h->got.offset; |
2771 tls_type = elf_s390_hash_entry(h)->tls_type; | 2953 tls_type = elf_s390_hash_entry(h)->tls_type; |
2772 if (info->shared || h->dynindx != -1 || tls_type < GOT_TLS_IE) | 2954 if (info->shared || h->dynindx != -1 || tls_type < GOT_TLS_IE) |
2773 goto emit_tls_relocs; | 2955 goto emit_tls_relocs; |
2774 } | 2956 } |
2775 | 2957 |
2776 » if (htab->sgot == NULL) | 2958 » if (htab->elf.sgot == NULL) |
2777 abort (); | 2959 abort (); |
2778 | 2960 |
2779 BFD_ASSERT (! unresolved_reloc); | 2961 BFD_ASSERT (! unresolved_reloc); |
2780 bfd_put_64 (output_bfd, -tpoff (info, relocation), | 2962 bfd_put_64 (output_bfd, -tpoff (info, relocation), |
2781 » » htab->sgot->contents + off); | 2963 » » htab->elf.sgot->contents + off); |
2782 » relocation = htab->sgot->output_offset + off; | 2964 » relocation = htab->elf.sgot->output_offset + off; |
2783 if (r_type == R_390_TLS_IEENT) | 2965 if (r_type == R_390_TLS_IEENT) |
2784 » relocation += htab->sgot->output_section->vma; | 2966 » relocation += htab->elf.sgot->output_section->vma; |
2785 unresolved_reloc = FALSE; | 2967 unresolved_reloc = FALSE; |
2786 break; | 2968 break; |
2787 | 2969 |
2788 case R_390_TLS_LDM64: | 2970 case R_390_TLS_LDM64: |
2789 if (! info->shared) | 2971 if (! info->shared) |
2790 /* The literal pool entry this relocation refers to gets ignored | 2972 /* The literal pool entry this relocation refers to gets ignored |
2791 by the optimized code of the local exec model. Do nothing | 2973 by the optimized code of the local exec model. Do nothing |
2792 and the value will turn out zero. */ | 2974 and the value will turn out zero. */ |
2793 continue; | 2975 continue; |
2794 | 2976 |
2795 » if (htab->sgot == NULL) | 2977 » if (htab->elf.sgot == NULL) |
2796 abort (); | 2978 abort (); |
2797 | 2979 |
2798 off = htab->tls_ldm_got.offset; | 2980 off = htab->tls_ldm_got.offset; |
2799 if (off & 1) | 2981 if (off & 1) |
2800 off &= ~1; | 2982 off &= ~1; |
2801 else | 2983 else |
2802 { | 2984 { |
2803 Elf_Internal_Rela outrel; | 2985 Elf_Internal_Rela outrel; |
2804 bfd_byte *loc; | 2986 bfd_byte *loc; |
2805 | 2987 |
2806 » if (htab->srelgot == NULL) | 2988 » if (htab->elf.srelgot == NULL) |
2807 abort (); | 2989 abort (); |
2808 | 2990 |
2809 » outrel.r_offset = (htab->sgot->output_section->vma | 2991 » outrel.r_offset = (htab->elf.sgot->output_section->vma |
2810 » » » » + htab->sgot->output_offset + off); | 2992 » » » » + htab->elf.sgot->output_offset + off); |
2811 | 2993 |
2812 bfd_put_64 (output_bfd, 0, | 2994 bfd_put_64 (output_bfd, 0, |
2813 » » » htab->sgot->contents + off + GOT_ENTRY_SIZE); | 2995 » » » htab->elf.sgot->contents + off + GOT_ENTRY_SIZE); |
2814 outrel.r_info = ELF64_R_INFO (0, R_390_TLS_DTPMOD); | 2996 outrel.r_info = ELF64_R_INFO (0, R_390_TLS_DTPMOD); |
2815 outrel.r_addend = 0; | 2997 outrel.r_addend = 0; |
2816 » loc = htab->srelgot->contents; | 2998 » loc = htab->elf.srelgot->contents; |
2817 » loc += htab->srelgot->reloc_count++ | 2999 » loc += htab->elf.srelgot->reloc_count++ |
2818 * sizeof (Elf64_External_Rela); | 3000 * sizeof (Elf64_External_Rela); |
2819 bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc); | 3001 bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc); |
2820 htab->tls_ldm_got.offset |= 1; | 3002 htab->tls_ldm_got.offset |= 1; |
2821 } | 3003 } |
2822 » relocation = htab->sgot->output_offset + off; | 3004 » relocation = htab->elf.sgot->output_offset + off; |
2823 unresolved_reloc = FALSE; | 3005 unresolved_reloc = FALSE; |
2824 break; | 3006 break; |
2825 | 3007 |
2826 case R_390_TLS_LE64: | 3008 case R_390_TLS_LE64: |
2827 if (info->shared) | 3009 if (info->shared) |
2828 { | 3010 { |
2829 /* Linking a shared library with non-fpic code requires | 3011 /* Linking a shared library with non-fpic code requires |
2830 a R_390_TLS_TPOFF relocation. */ | 3012 a R_390_TLS_TPOFF relocation. */ |
2831 Elf_Internal_Rela outrel; | 3013 Elf_Internal_Rela outrel; |
2832 asection *sreloc; | 3014 asection *sreloc; |
(...skipping 21 matching lines...) Expand all Loading... |
2854 } | 3036 } |
2855 else | 3037 else |
2856 { | 3038 { |
2857 BFD_ASSERT (! unresolved_reloc); | 3039 BFD_ASSERT (! unresolved_reloc); |
2858 bfd_put_64 (output_bfd, -tpoff (info, relocation), | 3040 bfd_put_64 (output_bfd, -tpoff (info, relocation), |
2859 contents + rel->r_offset); | 3041 contents + rel->r_offset); |
2860 } | 3042 } |
2861 continue; | 3043 continue; |
2862 | 3044 |
2863 case R_390_TLS_LDO64: | 3045 case R_390_TLS_LDO64: |
2864 » if (info->shared) | 3046 » if (info->shared || (input_section->flags & SEC_DEBUGGING)) |
2865 relocation -= dtpoff_base (info); | 3047 relocation -= dtpoff_base (info); |
2866 else | 3048 else |
2867 /* When converting LDO to LE, we must negate. */ | 3049 /* When converting LDO to LE, we must negate. */ |
2868 relocation = -tpoff (info, relocation); | 3050 relocation = -tpoff (info, relocation); |
2869 break; | 3051 break; |
2870 | 3052 |
2871 /* Relocations for tls instructions. */ | 3053 /* Relocations for tls instructions. */ |
2872 case R_390_TLS_LOAD: | 3054 case R_390_TLS_LOAD: |
2873 case R_390_TLS_GDCALL: | 3055 case R_390_TLS_GDCALL: |
2874 case R_390_TLS_LDCALL: | 3056 case R_390_TLS_LDCALL: |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2975 && _bfd_elf_section_offset (output_bfd, info, input_section, | 3157 && _bfd_elf_section_offset (output_bfd, info, input_section, |
2976 rel->r_offset) != (bfd_vma) -1) | 3158 rel->r_offset) != (bfd_vma) -1) |
2977 (*_bfd_error_handler) | 3159 (*_bfd_error_handler) |
2978 (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"), | 3160 (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"), |
2979 input_bfd, | 3161 input_bfd, |
2980 input_section, | 3162 input_section, |
2981 (long) rel->r_offset, | 3163 (long) rel->r_offset, |
2982 howto->name, | 3164 howto->name, |
2983 h->root.root.string); | 3165 h->root.root.string); |
2984 | 3166 |
| 3167 do_relocation: |
| 3168 |
2985 if (r_type == R_390_20 | 3169 if (r_type == R_390_20 |
2986 || r_type == R_390_GOT20 | 3170 || r_type == R_390_GOT20 |
2987 || r_type == R_390_GOTPLT20 | 3171 || r_type == R_390_GOTPLT20 |
2988 || r_type == R_390_TLS_GOTIE20) | 3172 || r_type == R_390_TLS_GOTIE20) |
2989 { | 3173 { |
2990 relocation += rel->r_addend; | 3174 relocation += rel->r_addend; |
2991 relocation = (relocation&0xfff) << 8 | (relocation&0xff000) >> 12; | 3175 relocation = (relocation&0xfff) << 8 | (relocation&0xff000) >> 12; |
2992 r = _bfd_final_link_relocate (howto, input_bfd, input_section, | 3176 r = _bfd_final_link_relocate (howto, input_bfd, input_section, |
2993 contents, rel->r_offset, | 3177 contents, rel->r_offset, |
2994 relocation, 0); | 3178 relocation, 0); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3031 input_bfd, input_section, | 3215 input_bfd, input_section, |
3032 (long) rel->r_offset, name, (int) r); | 3216 (long) rel->r_offset, name, (int) r); |
3033 return FALSE; | 3217 return FALSE; |
3034 } | 3218 } |
3035 } | 3219 } |
3036 } | 3220 } |
3037 | 3221 |
3038 return TRUE; | 3222 return TRUE; |
3039 } | 3223 } |
3040 | 3224 |
| 3225 /* Generate the PLT slots together with the dynamic relocations needed |
| 3226 for IFUNC symbols. */ |
| 3227 |
| 3228 static void |
| 3229 elf_s390_finish_ifunc_symbol (bfd *output_bfd, |
| 3230 struct bfd_link_info *info, |
| 3231 struct elf_link_hash_entry *h, |
| 3232 struct elf_s390_link_hash_table *htab, |
| 3233 bfd_vma plt_offset, |
| 3234 bfd_vma resolver_address) |
| 3235 { |
| 3236 bfd_vma plt_index; |
| 3237 bfd_vma got_offset; |
| 3238 Elf_Internal_Rela rela; |
| 3239 bfd_byte *loc; |
| 3240 asection *plt, *gotplt, *relplt; |
| 3241 |
| 3242 if (htab->elf.iplt == NULL |
| 3243 || htab->elf.igotplt == NULL |
| 3244 || htab->elf.irelplt == NULL) |
| 3245 abort (); |
| 3246 |
| 3247 /* Index of the PLT slot within iplt section. */ |
| 3248 plt_index = plt_offset / PLT_ENTRY_SIZE; |
| 3249 plt = htab->elf.iplt; |
| 3250 /* Offset into the igot.plt section. */ |
| 3251 got_offset = plt_index * GOT_ENTRY_SIZE; |
| 3252 gotplt = htab->elf.igotplt; |
| 3253 relplt = htab->elf.irelplt; |
| 3254 |
| 3255 /* Fill in the blueprint of a PLT. */ |
| 3256 memcpy (plt->contents + plt_offset, elf_s390x_plt_entry, |
| 3257 PLT_ENTRY_SIZE); |
| 3258 |
| 3259 /* Fixup the relative address to the GOT entry */ |
| 3260 bfd_put_32 (output_bfd, |
| 3261 (gotplt->output_section->vma + |
| 3262 gotplt->output_offset + got_offset |
| 3263 - (plt->output_section->vma + |
| 3264 plt->output_offset + |
| 3265 plt_offset))/2, |
| 3266 plt->contents + plt_offset + 2); |
| 3267 /* Fixup the relative branch to PLT 0 */ |
| 3268 bfd_put_32 (output_bfd, - (plt->output_offset + |
| 3269 (PLT_ENTRY_SIZE * plt_index) + 22)/2, |
| 3270 plt->contents + plt_offset + 24); |
| 3271 /* Fixup offset into .rela.plt section. */ |
| 3272 bfd_put_32 (output_bfd, relplt->output_offset + |
| 3273 plt_index * sizeof (Elf64_External_Rela), |
| 3274 plt->contents + plt_offset + 28); |
| 3275 |
| 3276 /* Fill in the entry in the global offset table. |
| 3277 Points to instruction after GOT offset. */ |
| 3278 bfd_put_64 (output_bfd, |
| 3279 (plt->output_section->vma |
| 3280 + plt->output_offset |
| 3281 + plt_offset |
| 3282 + 14), |
| 3283 gotplt->contents + got_offset); |
| 3284 |
| 3285 /* Fill in the entry in the .rela.plt section. */ |
| 3286 rela.r_offset = (gotplt->output_section->vma |
| 3287 + gotplt->output_offset |
| 3288 + got_offset); |
| 3289 |
| 3290 if (!h |
| 3291 || h->dynindx == -1 |
| 3292 || ((info->executable |
| 3293 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) |
| 3294 && h->def_regular)) |
| 3295 { |
| 3296 /* The symbol can be locally resolved. */ |
| 3297 rela.r_info = ELF64_R_INFO (0, R_390_IRELATIVE); |
| 3298 rela.r_addend = resolver_address; |
| 3299 } |
| 3300 else |
| 3301 { |
| 3302 rela.r_info = ELF64_R_INFO (h->dynindx, R_390_JMP_SLOT); |
| 3303 rela.r_addend = 0; |
| 3304 } |
| 3305 |
| 3306 loc = relplt->contents + plt_index * sizeof (Elf64_External_Rela); |
| 3307 bfd_elf64_swap_reloca_out (output_bfd, &rela, loc); |
| 3308 } |
| 3309 |
| 3310 |
3041 /* Finish up dynamic symbol handling. We set the contents of various | 3311 /* Finish up dynamic symbol handling. We set the contents of various |
3042 dynamic sections here. */ | 3312 dynamic sections here. */ |
3043 | 3313 |
3044 static bfd_boolean | 3314 static bfd_boolean |
3045 elf_s390_finish_dynamic_symbol (bfd *output_bfd, | 3315 elf_s390_finish_dynamic_symbol (bfd *output_bfd, |
3046 struct bfd_link_info *info, | 3316 struct bfd_link_info *info, |
3047 struct elf_link_hash_entry *h, | 3317 struct elf_link_hash_entry *h, |
3048 Elf_Internal_Sym *sym) | 3318 Elf_Internal_Sym *sym) |
3049 { | 3319 { |
3050 struct elf_s390_link_hash_table *htab; | 3320 struct elf_s390_link_hash_table *htab; |
| 3321 struct elf_s390_link_hash_entry *eh = (struct elf_s390_link_hash_entry*)h; |
3051 | 3322 |
3052 htab = elf_s390_hash_table (info); | 3323 htab = elf_s390_hash_table (info); |
3053 if (htab == NULL) | 3324 if (htab == NULL) |
3054 return FALSE; | 3325 return FALSE; |
3055 | 3326 |
3056 if (h->plt.offset != (bfd_vma) -1) | 3327 if (h->plt.offset != (bfd_vma) -1) |
3057 { | 3328 { |
3058 bfd_vma plt_index; | 3329 bfd_vma plt_index; |
3059 bfd_vma got_offset; | 3330 bfd_vma got_offset; |
3060 Elf_Internal_Rela rela; | 3331 Elf_Internal_Rela rela; |
3061 bfd_byte *loc; | 3332 bfd_byte *loc; |
3062 | 3333 |
3063 /* This symbol has an entry in the procedure linkage table. Set | 3334 /* This symbol has an entry in the procedure linkage table. Set |
3064 it up. */ | 3335 it up. */ |
| 3336 if (s390_is_ifunc_symbol_p (h)) |
| 3337 { |
| 3338 /* If we can resolve the IFUNC symbol locally we generate an |
| 3339 IRELATIVE reloc. */ |
| 3340 elf_s390_finish_ifunc_symbol (output_bfd, info, h, htab, h->plt.offset
, |
| 3341 eh->ifunc_resolver_address + |
| 3342 eh->ifunc_resolver_section->output_offse
t + |
| 3343 eh->ifunc_resolver_section->output_secti
on->vma); |
| 3344 ; |
| 3345 /* Fallthrough. Handling of explicit GOT slots of IFUNC |
| 3346 symbols is below. */ |
| 3347 } |
| 3348 else |
| 3349 { |
| 3350 if (h->dynindx == -1 |
| 3351 || htab->elf.splt == NULL |
| 3352 || htab->elf.sgotplt == NULL |
| 3353 || htab->elf.srelplt == NULL) |
| 3354 abort (); |
3065 | 3355 |
3066 if (h->dynindx == -1 | 3356 » /* Calc. index no. |
3067 » || htab->splt == NULL | 3357 » Current offset - size first entry / entry size. */ |
3068 » || htab->sgotplt == NULL | 3358 » plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) / PLT_ENTRY_SIZE; |
3069 » || htab->srelplt == NULL) | |
3070 » abort (); | |
3071 | 3359 |
3072 /* Calc. index no. | 3360 » /* Offset in GOT is PLT index plus GOT headers(3) times 8, |
3073 » Current offset - size first entry / entry size. */ | 3361 » addr & GOT addr. */ |
3074 plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) / PLT_ENTRY_SIZE; | 3362 » got_offset = (plt_index + 3) * GOT_ENTRY_SIZE; |
3075 | 3363 |
3076 /* Offset in GOT is PLT index plus GOT headers(3) times 8, | 3364 » /* Fill in the blueprint of a PLT. */ |
3077 » addr & GOT addr. */ | 3365 » memcpy (htab->elf.splt->contents + h->plt.offset, elf_s390x_plt_entry, |
3078 got_offset = (plt_index + 3) * GOT_ENTRY_SIZE; | 3366 » » PLT_ENTRY_SIZE); |
3079 | 3367 |
3080 /* Fill in the blueprint of a PLT. */ | 3368 » /* Fixup the relative address to the GOT entry */ |
3081 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD0, | 3369 » bfd_put_32 (output_bfd, |
3082 » » htab->splt->contents + h->plt.offset); | 3370 » » (htab->elf.sgotplt->output_section->vma + |
3083 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD1, | 3371 » » htab->elf.sgotplt->output_offset + got_offset |
3084 » » htab->splt->contents + h->plt.offset + 4); | 3372 » » - (htab->elf.splt->output_section->vma + |
3085 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD2, | 3373 » » » htab->elf.splt->output_offset + |
3086 » » htab->splt->contents + h->plt.offset + 8); | 3374 » » » h->plt.offset))/2, |
3087 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD3, | 3375 » » htab->elf.splt->contents + h->plt.offset + 2); |
3088 » » htab->splt->contents + h->plt.offset + 12); | 3376 » /* Fixup the relative branch to PLT 0 */ |
3089 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD4, | 3377 » bfd_put_32 (output_bfd, - (PLT_FIRST_ENTRY_SIZE + |
3090 » » htab->splt->contents + h->plt.offset + 16); | 3378 » » » » (PLT_ENTRY_SIZE * plt_index) + 22)/2, |
3091 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD5, | 3379 » » htab->elf.splt->contents + h->plt.offset + 24); |
3092 » » htab->splt->contents + h->plt.offset + 20); | 3380 » /* Fixup offset into .rela.plt section. */ |
3093 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD6, | 3381 » bfd_put_32 (output_bfd, plt_index * sizeof (Elf64_External_Rela), |
3094 » » htab->splt->contents + h->plt.offset + 24); | 3382 » » htab->elf.splt->contents + h->plt.offset + 28); |
3095 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD7, | |
3096 » » htab->splt->contents + h->plt.offset + 28); | |
3097 /* Fixup the relative address to the GOT entry */ | |
3098 bfd_put_32 (output_bfd, | |
3099 » » (htab->sgotplt->output_section->vma + | |
3100 » » htab->sgotplt->output_offset + got_offset | |
3101 » » - (htab->splt->output_section->vma + h->plt.offset))/2, | |
3102 » » htab->splt->contents + h->plt.offset + 2); | |
3103 /* Fixup the relative branch to PLT 0 */ | |
3104 bfd_put_32 (output_bfd, - (PLT_FIRST_ENTRY_SIZE + | |
3105 » » » » (PLT_ENTRY_SIZE * plt_index) + 22)/2, | |
3106 » » htab->splt->contents + h->plt.offset + 24); | |
3107 /* Fixup offset into symbol table */ | |
3108 bfd_put_32 (output_bfd, plt_index * sizeof (Elf64_External_Rela), | |
3109 » » htab->splt->contents + h->plt.offset + 28); | |
3110 | 3383 |
3111 /* Fill in the entry in the global offset table. | 3384 » /* Fill in the entry in the global offset table. |
3112 » Points to instruction after GOT offset. */ | 3385 » Points to instruction after GOT offset. */ |
3113 bfd_put_64 (output_bfd, | 3386 » bfd_put_64 (output_bfd, |
3114 » » (htab->splt->output_section->vma | 3387 » » (htab->elf.splt->output_section->vma |
3115 » » + htab->splt->output_offset | 3388 » » + htab->elf.splt->output_offset |
3116 » » + h->plt.offset | 3389 » » + h->plt.offset |
3117 » » + 14), | 3390 » » + 14), |
3118 » » htab->sgotplt->contents + got_offset); | 3391 » » htab->elf.sgotplt->contents + got_offset); |
3119 | 3392 |
3120 /* Fill in the entry in the .rela.plt section. */ | 3393 » /* Fill in the entry in the .rela.plt section. */ |
3121 rela.r_offset = (htab->sgotplt->output_section->vma | 3394 » rela.r_offset = (htab->elf.sgotplt->output_section->vma |
3122 » » + htab->sgotplt->output_offset | 3395 » » » + htab->elf.sgotplt->output_offset |
3123 » » + got_offset); | 3396 » » » + got_offset); |
3124 rela.r_info = ELF64_R_INFO (h->dynindx, R_390_JMP_SLOT); | 3397 » rela.r_info = ELF64_R_INFO (h->dynindx, R_390_JMP_SLOT); |
3125 rela.r_addend = 0; | 3398 » rela.r_addend = 0; |
3126 loc = htab->srelplt->contents + plt_index * sizeof (Elf64_External_Rela); | 3399 » loc = htab->elf.srelplt->contents + plt_index * |
3127 bfd_elf64_swap_reloca_out (output_bfd, &rela, loc); | 3400 » sizeof (Elf64_External_Rela); |
| 3401 » bfd_elf64_swap_reloca_out (output_bfd, &rela, loc); |
3128 | 3402 |
3129 if (!h->def_regular) | 3403 » if (!h->def_regular) |
3130 » { | 3404 » { |
3131 » /* Mark the symbol as undefined, rather than as defined in | 3405 » /* Mark the symbol as undefined, rather than as defined in |
3132 » the .plt section. Leave the value alone. This is a clue | 3406 » » the .plt section. Leave the value alone. This is a clue |
3133 » for the dynamic linker, to make function pointer | 3407 » » for the dynamic linker, to make function pointer |
3134 » comparisons work between an application and shared | 3408 » » comparisons work between an application and shared |
3135 » library. */ | 3409 » » library. */ |
3136 » sym->st_shndx = SHN_UNDEF; | 3410 » sym->st_shndx = SHN_UNDEF; |
| 3411 » } |
3137 } | 3412 } |
3138 } | 3413 } |
3139 | 3414 |
3140 if (h->got.offset != (bfd_vma) -1 | 3415 if (h->got.offset != (bfd_vma) -1 |
3141 && elf_s390_hash_entry(h)->tls_type != GOT_TLS_GD | 3416 && elf_s390_hash_entry(h)->tls_type != GOT_TLS_GD |
3142 && elf_s390_hash_entry(h)->tls_type != GOT_TLS_IE | 3417 && elf_s390_hash_entry(h)->tls_type != GOT_TLS_IE |
3143 && elf_s390_hash_entry(h)->tls_type != GOT_TLS_IE_NLT) | 3418 && elf_s390_hash_entry(h)->tls_type != GOT_TLS_IE_NLT) |
3144 { | 3419 { |
3145 Elf_Internal_Rela rela; | 3420 Elf_Internal_Rela rela; |
3146 bfd_byte *loc; | 3421 bfd_byte *loc; |
3147 | 3422 |
3148 /* This symbol has an entry in the global offset table. Set it | 3423 /* This symbol has an entry in the global offset table. Set it |
3149 up. */ | 3424 up. */ |
3150 if (htab->sgot == NULL || htab->srelgot == NULL) | 3425 if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL) |
3151 abort (); | 3426 abort (); |
3152 | 3427 |
3153 rela.r_offset = (htab->sgot->output_section->vma | 3428 rela.r_offset = (htab->elf.sgot->output_section->vma |
3154 » » + htab->sgot->output_offset | 3429 » » + htab->elf.sgot->output_offset |
3155 + (h->got.offset &~ (bfd_vma) 1)); | 3430 + (h->got.offset &~ (bfd_vma) 1)); |
3156 | 3431 |
3157 /* If this is a static link, or it is a -Bsymbolic link and the | 3432 if (h->def_regular && s390_is_ifunc_symbol_p (h)) |
3158 » symbol is defined locally or was forced to be local because | 3433 » { |
3159 » of a version file, we just want to emit a RELATIVE reloc. | 3434 » if (info->shared) |
3160 » The entry in the global offset table will already have been | 3435 » { |
3161 » initialized in the relocate_section function. */ | 3436 » /* An explicit GOT slot usage needs GLOB_DAT. If the |
3162 if (info->shared | 3437 » » symbol references local the implicit got.iplt slot |
| 3438 » » will be used and the IRELATIVE reloc has been created |
| 3439 » » above. */ |
| 3440 » goto do_glob_dat; |
| 3441 » } |
| 3442 » else |
| 3443 » { |
| 3444 » /* For non-shared objects explicit GOT slots must be |
| 3445 » » filled with the PLT slot address for pointer |
| 3446 » » equality reasons. */ |
| 3447 » bfd_put_64 (output_bfd, (htab->elf.iplt->output_section->vma |
| 3448 » » » » + htab->elf.iplt->output_offset |
| 3449 » » » » + h->plt.offset), |
| 3450 » » » htab->elf.sgot->contents + h->got.offset); |
| 3451 » return TRUE; |
| 3452 » } |
| 3453 » } |
| 3454 else if (info->shared |
3163 && SYMBOL_REFERENCES_LOCAL (info, h)) | 3455 && SYMBOL_REFERENCES_LOCAL (info, h)) |
3164 { | 3456 { |
| 3457 /* If this is a static link, or it is a -Bsymbolic link and |
| 3458 the symbol is defined locally or was forced to be local |
| 3459 because of a version file, we just want to emit a |
| 3460 RELATIVE reloc. The entry in the global offset table |
| 3461 will already have been initialized in the |
| 3462 relocate_section function. */ |
3165 if (!h->def_regular) | 3463 if (!h->def_regular) |
3166 return FALSE; | 3464 return FALSE; |
3167 BFD_ASSERT((h->got.offset & 1) != 0); | 3465 BFD_ASSERT((h->got.offset & 1) != 0); |
3168 rela.r_info = ELF64_R_INFO (0, R_390_RELATIVE); | 3466 rela.r_info = ELF64_R_INFO (0, R_390_RELATIVE); |
3169 rela.r_addend = (h->root.u.def.value | 3467 rela.r_addend = (h->root.u.def.value |
3170 + h->root.u.def.section->output_section->vma | 3468 + h->root.u.def.section->output_section->vma |
3171 + h->root.u.def.section->output_offset); | 3469 + h->root.u.def.section->output_offset); |
3172 } | 3470 } |
3173 else | 3471 else |
3174 { | 3472 { |
3175 BFD_ASSERT((h->got.offset & 1) == 0); | 3473 BFD_ASSERT((h->got.offset & 1) == 0); |
3176 » bfd_put_64 (output_bfd, (bfd_vma) 0, htab->sgot->contents + h->got.off
set); | 3474 do_glob_dat: |
| 3475 » bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgot->contents + h->got
.offset); |
3177 rela.r_info = ELF64_R_INFO (h->dynindx, R_390_GLOB_DAT); | 3476 rela.r_info = ELF64_R_INFO (h->dynindx, R_390_GLOB_DAT); |
3178 rela.r_addend = 0; | 3477 rela.r_addend = 0; |
3179 } | 3478 } |
3180 | 3479 |
3181 loc = htab->srelgot->contents; | 3480 loc = htab->elf.srelgot->contents; |
3182 loc += htab->srelgot->reloc_count++ * sizeof (Elf64_External_Rela); | 3481 loc += htab->elf.srelgot->reloc_count++ * sizeof (Elf64_External_Rela); |
3183 bfd_elf64_swap_reloca_out (output_bfd, &rela, loc); | 3482 bfd_elf64_swap_reloca_out (output_bfd, &rela, loc); |
3184 } | 3483 } |
3185 | 3484 |
3186 if (h->needs_copy) | 3485 if (h->needs_copy) |
3187 { | 3486 { |
3188 Elf_Internal_Rela rela; | 3487 Elf_Internal_Rela rela; |
3189 bfd_byte *loc; | 3488 bfd_byte *loc; |
3190 | 3489 |
3191 /* This symbols needs a copy reloc. Set it up. */ | 3490 /* This symbols needs a copy reloc. Set it up. */ |
3192 | 3491 |
(...skipping 19 matching lines...) Expand all Loading... |
3212 || h == htab->elf.hplt) | 3511 || h == htab->elf.hplt) |
3213 sym->st_shndx = SHN_ABS; | 3512 sym->st_shndx = SHN_ABS; |
3214 | 3513 |
3215 return TRUE; | 3514 return TRUE; |
3216 } | 3515 } |
3217 | 3516 |
3218 /* Used to decide how to sort relocs in an optimal manner for the | 3517 /* Used to decide how to sort relocs in an optimal manner for the |
3219 dynamic linker, before writing them out. */ | 3518 dynamic linker, before writing them out. */ |
3220 | 3519 |
3221 static enum elf_reloc_type_class | 3520 static enum elf_reloc_type_class |
3222 elf_s390_reloc_type_class (rela) | 3521 elf_s390_reloc_type_class (const Elf_Internal_Rela *rela) |
3223 const Elf_Internal_Rela *rela; | |
3224 { | 3522 { |
3225 switch ((int) ELF64_R_TYPE (rela->r_info)) | 3523 switch ((int) ELF64_R_TYPE (rela->r_info)) |
3226 { | 3524 { |
3227 case R_390_RELATIVE: | 3525 case R_390_RELATIVE: |
3228 return reloc_class_relative; | 3526 return reloc_class_relative; |
3229 case R_390_JMP_SLOT: | 3527 case R_390_JMP_SLOT: |
3230 return reloc_class_plt; | 3528 return reloc_class_plt; |
3231 case R_390_COPY: | 3529 case R_390_COPY: |
3232 return reloc_class_copy; | 3530 return reloc_class_copy; |
3233 default: | 3531 default: |
3234 return reloc_class_normal; | 3532 return reloc_class_normal; |
3235 } | 3533 } |
3236 } | 3534 } |
3237 | 3535 |
3238 /* Finish up the dynamic sections. */ | 3536 /* Finish up the dynamic sections. */ |
3239 | 3537 |
3240 static bfd_boolean | 3538 static bfd_boolean |
3241 elf_s390_finish_dynamic_sections (bfd *output_bfd, | 3539 elf_s390_finish_dynamic_sections (bfd *output_bfd, |
3242 struct bfd_link_info *info) | 3540 struct bfd_link_info *info) |
3243 { | 3541 { |
3244 struct elf_s390_link_hash_table *htab; | 3542 struct elf_s390_link_hash_table *htab; |
3245 bfd *dynobj; | 3543 bfd *dynobj; |
3246 asection *sdyn; | 3544 asection *sdyn; |
| 3545 bfd *ibfd; |
| 3546 unsigned int i; |
3247 | 3547 |
3248 htab = elf_s390_hash_table (info); | 3548 htab = elf_s390_hash_table (info); |
3249 if (htab == NULL) | 3549 if (htab == NULL) |
3250 return FALSE; | 3550 return FALSE; |
3251 | 3551 |
3252 dynobj = htab->elf.dynobj; | 3552 dynobj = htab->elf.dynobj; |
3253 sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); | 3553 sdyn = bfd_get_linker_section (dynobj, ".dynamic"); |
3254 | 3554 |
3255 if (htab->elf.dynamic_sections_created) | 3555 if (htab->elf.dynamic_sections_created) |
3256 { | 3556 { |
3257 Elf64_External_Dyn *dyncon, *dynconend; | 3557 Elf64_External_Dyn *dyncon, *dynconend; |
3258 | 3558 |
3259 if (sdyn == NULL || htab->sgot == NULL) | 3559 if (sdyn == NULL || htab->elf.sgot == NULL) |
3260 abort (); | 3560 abort (); |
3261 | 3561 |
3262 dyncon = (Elf64_External_Dyn *) sdyn->contents; | 3562 dyncon = (Elf64_External_Dyn *) sdyn->contents; |
3263 dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size); | 3563 dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size); |
3264 for (; dyncon < dynconend; dyncon++) | 3564 for (; dyncon < dynconend; dyncon++) |
3265 { | 3565 { |
3266 Elf_Internal_Dyn dyn; | 3566 Elf_Internal_Dyn dyn; |
3267 asection *s; | 3567 asection *s; |
3268 | 3568 |
3269 bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn); | 3569 bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn); |
3270 | 3570 |
3271 switch (dyn.d_tag) | 3571 switch (dyn.d_tag) |
3272 { | 3572 { |
3273 default: | 3573 default: |
3274 continue; | 3574 continue; |
3275 | 3575 |
3276 case DT_PLTGOT: | 3576 case DT_PLTGOT: |
3277 » dyn.d_un.d_ptr = htab->sgot->output_section->vma; | 3577 » dyn.d_un.d_ptr = htab->elf.sgot->output_section->vma; |
3278 break; | 3578 break; |
3279 | 3579 |
3280 case DT_JMPREL: | 3580 case DT_JMPREL: |
3281 » dyn.d_un.d_ptr = htab->srelplt->output_section->vma; | 3581 » dyn.d_un.d_ptr = htab->elf.srelplt->output_section->vma; |
3282 break; | 3582 break; |
3283 | 3583 |
3284 case DT_PLTRELSZ: | 3584 case DT_PLTRELSZ: |
3285 » s = htab->srelplt->output_section; | 3585 » s = htab->elf.srelplt->output_section; |
3286 dyn.d_un.d_val = s->size; | 3586 dyn.d_un.d_val = s->size; |
3287 break; | 3587 break; |
3288 | 3588 |
3289 case DT_RELASZ: | 3589 case DT_RELASZ: |
3290 /* The procedure linkage table relocs (DT_JMPREL) should | 3590 /* The procedure linkage table relocs (DT_JMPREL) should |
3291 not be included in the overall relocs (DT_RELA). | 3591 not be included in the overall relocs (DT_RELA). |
3292 Therefore, we override the DT_RELASZ entry here to | 3592 Therefore, we override the DT_RELASZ entry here to |
3293 make it not include the JMPREL relocs. Since the | 3593 make it not include the JMPREL relocs. Since the |
3294 linker script arranges for .rela.plt to follow all | 3594 linker script arranges for .rela.plt to follow all |
3295 other relocation sections, we don't have to worry | 3595 other relocation sections, we don't have to worry |
3296 about changing the DT_RELA entry. */ | 3596 about changing the DT_RELA entry. */ |
3297 » s = htab->srelplt->output_section; | 3597 » s = htab->elf.srelplt->output_section; |
3298 dyn.d_un.d_val -= s->size; | 3598 dyn.d_un.d_val -= s->size; |
3299 break; | 3599 break; |
3300 } | 3600 } |
3301 | 3601 |
3302 bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon); | 3602 bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon); |
3303 } | 3603 } |
3304 | 3604 |
3305 /* Fill in the special first entry in the procedure linkage table. */ | 3605 /* Fill in the special first entry in the procedure linkage table. */ |
3306 if (htab->splt && htab->splt->size > 0) | 3606 if (htab->elf.splt && htab->elf.splt->size > 0) |
3307 { | 3607 { |
3308 /* fill in blueprint for plt 0 entry */ | 3608 /* fill in blueprint for plt 0 entry */ |
3309 » bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD0, | 3609 » memcpy (htab->elf.splt->contents, elf_s390x_first_plt_entry, |
3310 » » htab->splt->contents ); | 3610 » » PLT_FIRST_ENTRY_SIZE); |
3311 » bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD1, | |
3312 » » htab->splt->contents +4 ); | |
3313 » bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD3, | |
3314 » » htab->splt->contents +12 ); | |
3315 » bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD4, | |
3316 » » htab->splt->contents +16 ); | |
3317 » bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD5, | |
3318 » » htab->splt->contents +20 ); | |
3319 » bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD6, | |
3320 » » htab->splt->contents + 24); | |
3321 » bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD7, | |
3322 » » htab->splt->contents + 28 ); | |
3323 /* Fixup relative address to start of GOT */ | 3611 /* Fixup relative address to start of GOT */ |
3324 bfd_put_32 (output_bfd, | 3612 bfd_put_32 (output_bfd, |
3325 » » (htab->sgotplt->output_section->vma + | 3613 » » (htab->elf.sgotplt->output_section->vma + |
3326 » » htab->sgotplt->output_offset | 3614 » » htab->elf.sgotplt->output_offset |
3327 » » - htab->splt->output_section->vma - 6)/2, | 3615 » » - htab->elf.splt->output_section->vma - 6)/2, |
3328 » » htab->splt->contents + 8); | 3616 » » htab->elf.splt->contents + 8); |
3329 } | 3617 } |
3330 elf_section_data (htab->splt->output_section) | 3618 elf_section_data (htab->elf.splt->output_section) |
3331 ->this_hdr.sh_entsize = PLT_ENTRY_SIZE; | 3619 ->this_hdr.sh_entsize = PLT_ENTRY_SIZE; |
3332 } | 3620 } |
3333 | 3621 |
3334 if (htab->sgotplt) | 3622 if (htab->elf.sgotplt) |
3335 { | 3623 { |
3336 /* Fill in the first three entries in the global offset table. */ | 3624 /* Fill in the first three entries in the global offset table. */ |
3337 if (htab->sgotplt->size > 0) | 3625 if (htab->elf.sgotplt->size > 0) |
3338 { | 3626 { |
3339 bfd_put_64 (output_bfd, | 3627 bfd_put_64 (output_bfd, |
3340 (sdyn == NULL ? (bfd_vma) 0 | 3628 (sdyn == NULL ? (bfd_vma) 0 |
3341 : sdyn->output_section->vma + sdyn->output_offset), | 3629 : sdyn->output_section->vma + sdyn->output_offset), |
3342 » » htab->sgotplt->contents); | 3630 » » htab->elf.sgotplt->contents); |
3343 /* One entry for shared object struct ptr. */ | 3631 /* One entry for shared object struct ptr. */ |
3344 » bfd_put_64 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 8); | 3632 » bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + 8); |
3345 /* One entry for _dl_runtime_resolve. */ | 3633 /* One entry for _dl_runtime_resolve. */ |
3346 » bfd_put_64 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 12); | 3634 » bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + 12)
; |
3347 } | 3635 } |
3348 | 3636 |
3349 elf_section_data (htab->sgot->output_section) | 3637 elf_section_data (htab->elf.sgot->output_section) |
3350 ->this_hdr.sh_entsize = 8; | 3638 ->this_hdr.sh_entsize = 8; |
3351 } | 3639 } |
| 3640 |
| 3641 /* Finish dynamic symbol for local IFUNC symbols. */ |
| 3642 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) |
| 3643 { |
| 3644 struct plt_entry *local_plt; |
| 3645 Elf_Internal_Sym *isym; |
| 3646 Elf_Internal_Shdr *symtab_hdr; |
| 3647 |
| 3648 symtab_hdr = &elf_symtab_hdr (ibfd); |
| 3649 |
| 3650 local_plt = elf_s390_local_plt (ibfd); |
| 3651 if (local_plt != NULL) |
| 3652 for (i = 0; i < symtab_hdr->sh_info; i++) |
| 3653 { |
| 3654 if (local_plt[i].plt.offset != (bfd_vma) -1) |
| 3655 { |
| 3656 asection *sec = local_plt[i].sec; |
| 3657 isym = bfd_sym_from_r_symndx (&htab->sym_cache, ibfd, i); |
| 3658 if (isym == NULL) |
| 3659 return FALSE; |
| 3660 |
| 3661 if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC) |
| 3662 elf_s390_finish_ifunc_symbol (output_bfd, info, NULL, htab, |
| 3663 local_plt[i].plt.offset, |
| 3664 isym->st_value |
| 3665 + sec->output_section->vma |
| 3666 + sec->output_offset); |
| 3667 |
| 3668 } |
| 3669 } |
| 3670 } |
| 3671 |
3352 return TRUE; | 3672 return TRUE; |
3353 } | 3673 } |
3354 | 3674 |
3355 /* Return address for Ith PLT stub in section PLT, for relocation REL | 3675 /* Return address for Ith PLT stub in section PLT, for relocation REL |
3356 or (bfd_vma) -1 if it should not be included. */ | 3676 or (bfd_vma) -1 if it should not be included. */ |
3357 | 3677 |
3358 static bfd_vma | 3678 static bfd_vma |
3359 elf_s390_plt_sym_val (bfd_vma i, const asection *plt, | 3679 elf_s390_plt_sym_val (bfd_vma i, const asection *plt, |
3360 const arelent *rel ATTRIBUTE_UNUSED) | 3680 const arelent *rel ATTRIBUTE_UNUSED) |
3361 { | 3681 { |
3362 return plt->vma + PLT_FIRST_ENTRY_SIZE + i * PLT_ENTRY_SIZE; | 3682 return plt->vma + PLT_FIRST_ENTRY_SIZE + i * PLT_ENTRY_SIZE; |
3363 } | 3683 } |
3364 | 3684 |
3365 | |
3366 /* Why was the hash table entry size definition changed from | 3685 /* Why was the hash table entry size definition changed from |
3367 ARCH_SIZE/8 to 4? This breaks the 64 bit dynamic linker and | 3686 ARCH_SIZE/8 to 4? This breaks the 64 bit dynamic linker and |
3368 this is the only reason for the s390_elf64_size_info structure. */ | 3687 this is the only reason for the s390_elf64_size_info structure. */ |
3369 | 3688 |
3370 const struct elf_size_info s390_elf64_size_info = | 3689 const struct elf_size_info s390_elf64_size_info = |
3371 { | 3690 { |
3372 sizeof (Elf64_External_Ehdr), | 3691 sizeof (Elf64_External_Ehdr), |
3373 sizeof (Elf64_External_Phdr), | 3692 sizeof (Elf64_External_Phdr), |
3374 sizeof (Elf64_External_Shdr), | 3693 sizeof (Elf64_External_Shdr), |
3375 sizeof (Elf64_External_Rel), | 3694 sizeof (Elf64_External_Rel), |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3430 #define elf_backend_finish_dynamic_sections elf_s390_finish_dynamic_sections | 3749 #define elf_backend_finish_dynamic_sections elf_s390_finish_dynamic_sections |
3431 #define elf_backend_finish_dynamic_symbol elf_s390_finish_dynamic_symbol | 3750 #define elf_backend_finish_dynamic_symbol elf_s390_finish_dynamic_symbol |
3432 #define elf_backend_gc_mark_hook elf_s390_gc_mark_hook | 3751 #define elf_backend_gc_mark_hook elf_s390_gc_mark_hook |
3433 #define elf_backend_gc_sweep_hook elf_s390_gc_sweep_hook | 3752 #define elf_backend_gc_sweep_hook elf_s390_gc_sweep_hook |
3434 #define elf_backend_reloc_type_class elf_s390_reloc_type_class | 3753 #define elf_backend_reloc_type_class elf_s390_reloc_type_class |
3435 #define elf_backend_relocate_section elf_s390_relocate_section | 3754 #define elf_backend_relocate_section elf_s390_relocate_section |
3436 #define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections | 3755 #define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections |
3437 #define elf_backend_init_index_section _bfd_elf_init_1_index_section | 3756 #define elf_backend_init_index_section _bfd_elf_init_1_index_section |
3438 #define elf_backend_reloc_type_class elf_s390_reloc_type_class | 3757 #define elf_backend_reloc_type_class elf_s390_reloc_type_class |
3439 #define elf_backend_plt_sym_val elf_s390_plt_sym_val | 3758 #define elf_backend_plt_sym_val elf_s390_plt_sym_val |
| 3759 #define elf_backend_add_symbol_hook elf_s390_add_symbol_hook |
3440 | 3760 |
3441 #define bfd_elf64_mkobject elf_s390_mkobject | 3761 #define bfd_elf64_mkobject elf_s390_mkobject |
3442 #define elf_backend_object_p elf_s390_object_p | 3762 #define elf_backend_object_p elf_s390_object_p |
3443 | 3763 |
| 3764 /* Enable ELF64 archive functions. */ |
| 3765 #define bfd_elf64_archive_functions |
| 3766 extern bfd_boolean bfd_elf64_archive_slurp_armap (bfd *); |
| 3767 extern bfd_boolean bfd_elf64_archive_write_armap (bfd *, unsigned int, struct or
l *, unsigned int, int); |
| 3768 |
| 3769 #define bfd_elf64_archive_slurp_extended_name_table _bfd_archive_coff_slurp_
extended_name_table |
| 3770 #define bfd_elf64_archive_construct_extended_name_table _bfd_archive_coff_constr
uct_extended_name_table |
| 3771 #define bfd_elf64_archive_truncate_arname _bfd_archive_coff_trunca
te_arname |
| 3772 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_a
r_hdr |
| 3773 #define bfd_elf64_archive_write_ar_hdr _bfd_archive_coff_write_
ar_hdr |
| 3774 #define bfd_elf64_archive_openr_next_archived_file _bfd_archive_coff_openr_
next_archived_file |
| 3775 #define bfd_elf64_archive_get_elt_at_index _bfd_archive_coff_get_el
t_at_index |
| 3776 #define bfd_elf64_archive_generic_stat_arch_elt _bfd_archive_coff_generi
c_stat_arch_elt |
| 3777 #define bfd_elf64_archive_update_armap_timestamp _bfd_archive_coff_update
_armap_timestamp |
| 3778 |
3444 #include "elf64-target.h" | 3779 #include "elf64-target.h" |
OLD | NEW |