| 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 |