diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 9 | ||||
-rw-r--r-- | bfd/elfnn-aarch64.c | 83 | ||||
-rw-r--r-- | bfd/elfxx-aarch64.c | 15 | ||||
-rw-r--r-- | bfd/elfxx-aarch64.h | 4 |
4 files changed, 88 insertions, 23 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a725504..ef9eee4 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2019-08-22 Tamar Christina <tamar.christina@arm.com> + + PR ld/24601 + * elfnn-aarch64.c (aarch64_relocate): Handle weak TLS and undefined TLS. + Also Pass input_bfd to _bfd_aarch64_elf_resolve_relocation. + * elfxx-aarch64.c (_bfd_aarch64_elf_resolve_relocation): Use it. + * elfxx-aarch64.h (_bfd_aarch64_elf_resolve_relocation): Emit warning + for weak TLS. + 2019-08-22 Alan Modra <amodra@gmail.com> * elf32-arm.c (cmse_scan): Don't use ARM_GET_SYM_CMSE_SPCL, diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 4e6cbc9..fd44505 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -3004,7 +3004,8 @@ aarch64_relocate (unsigned int r_type, bfd *input_bfd, asection *input_section, + offset); r_type = elfNN_aarch64_bfd_reloc_from_type (input_bfd, r_type); - value = _bfd_aarch64_elf_resolve_relocation (r_type, place, value, 0, FALSE); + value = _bfd_aarch64_elf_resolve_relocation (input_bfd, r_type, place, + value, 0, FALSE); return _bfd_aarch64_elf_put_addend (input_bfd, input_section->contents + offset, r_type, howto, value) == bfd_reloc_ok; @@ -5585,7 +5586,8 @@ bad_ifunc_reloc: /* FALLTHROUGH */ case BFD_RELOC_AARCH64_CALL26: case BFD_RELOC_AARCH64_JUMP26: - value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value, + value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type, + place, value, signed_addend, weak_undef_p); return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type, @@ -5662,7 +5664,8 @@ bad_ifunc_reloc: addend = (globals->root.sgot->output_section->vma + globals->root.sgot->output_offset); - value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value, + value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type, + place, value, addend, weak_undef_p); return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type, howto, value); case BFD_RELOC_AARCH64_ADD_LO12: @@ -5840,7 +5843,8 @@ bad_ifunc_reloc: signed_addend = 0; } } - value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value, + value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type, + place, value, signed_addend, weak_undef_p); *unresolved_reloc_p = FALSE; break; @@ -5900,7 +5904,8 @@ bad_ifunc_reloc: case BFD_RELOC_AARCH64_MOVW_G2_S: case BFD_RELOC_AARCH64_MOVW_G3: case BFD_RELOC_AARCH64_TSTBR14: - value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value, + value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type, + place, value, signed_addend, weak_undef_p); break; @@ -5945,7 +5950,8 @@ bad_ifunc_reloc: if (aarch64_relocation_aginst_gp_p (bfd_r_type)) addend = (globals->root.sgot->output_section->vma + globals->root.sgot->output_offset); - value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value, + value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type, + place, value, addend, weak_undef_p); } else @@ -5992,7 +5998,8 @@ bad_ifunc_reloc: if (aarch64_relocation_aginst_gp_p (bfd_r_type)) addend = base_got->output_section->vma + base_got->output_offset; - value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value, + value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type, + place, value, addend, weak_undef_p); } @@ -6029,7 +6036,8 @@ bad_ifunc_reloc: + globals->root.sgot->output_section->vma + globals->root.sgot->output_offset); - value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value, + value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type, + place, value, 0, weak_undef_p); *unresolved_reloc_p = FALSE; break; @@ -6042,7 +6050,8 @@ bad_ifunc_reloc: return bfd_reloc_notsupported; value = symbol_got_offset (input_bfd, h, r_symndx); - value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value, + value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type, + place, value, 0, weak_undef_p); *unresolved_reloc_p = FALSE; break; @@ -6063,10 +6072,26 @@ bad_ifunc_reloc: case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1: case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC: case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2: - value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value, - signed_addend - dtpoff_base (info), - weak_undef_p); - break; + { + if (!(weak_undef_p || elf_hash_table (info)->tls_sec)) + { + int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START; + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB: TLS relocation %s against undefined symbol `%s'"), + input_bfd, elfNN_aarch64_howto_table[howto_index].name, + h->root.root.string); + bfd_set_error (bfd_error_bad_value); + return bfd_reloc_notsupported; + } + + bfd_vma def_value + = weak_undef_p ? 0 : signed_addend - dtpoff_base (info); + value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type, + place, value, + def_value, weak_undef_p); + break; + } case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12: case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12: @@ -6084,11 +6109,27 @@ bad_ifunc_reloc: case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1: case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC: case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2: - value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value, - signed_addend - tpoff_base (info), - weak_undef_p); - *unresolved_reloc_p = FALSE; - break; + { + if (!(weak_undef_p || elf_hash_table (info)->tls_sec)) + { + int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START; + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB: TLS relocation %s against undefined symbol `%s'"), + input_bfd, elfNN_aarch64_howto_table[howto_index].name, + h->root.root.string); + bfd_set_error (bfd_error_bad_value); + return bfd_reloc_notsupported; + } + + bfd_vma def_value + = weak_undef_p ? 0 : signed_addend - tpoff_base (info); + value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type, + place, value, + def_value, weak_undef_p); + *unresolved_reloc_p = FALSE; + break; + } case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12: case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21: @@ -6103,7 +6144,8 @@ bad_ifunc_reloc: + globals->root.sgotplt->output_offset + globals->sgotplt_jump_table_size); - value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value, + value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type, + place, value, 0, weak_undef_p); *unresolved_reloc_p = FALSE; break; @@ -6121,7 +6163,8 @@ bad_ifunc_reloc: value -= (globals->root.sgot->output_section->vma + globals->root.sgot->output_offset); - value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value, + value = _bfd_aarch64_elf_resolve_relocation (input_bfd, bfd_r_type, + place, value, 0, weak_undef_p); *unresolved_reloc_p = FALSE; break; diff --git a/bfd/elfxx-aarch64.c b/bfd/elfxx-aarch64.c index 33af6c2..1f69280 100644 --- a/bfd/elfxx-aarch64.c +++ b/bfd/elfxx-aarch64.c @@ -395,10 +395,12 @@ _bfd_aarch64_elf_put_addend (bfd *abfd, } bfd_vma -_bfd_aarch64_elf_resolve_relocation (bfd_reloc_code_real_type r_type, +_bfd_aarch64_elf_resolve_relocation (bfd *input_bfd, + bfd_reloc_code_real_type r_type, bfd_vma place, bfd_vma value, bfd_vma addend, bfd_boolean weak_undef_p) { + bfd_boolean tls_reloc = TRUE; switch (r_type) { case BFD_RELOC_AARCH64_NONE: @@ -446,6 +448,8 @@ _bfd_aarch64_elf_resolve_relocation (bfd_reloc_code_real_type r_type, case BFD_RELOC_AARCH64_MOVW_G2_NC: case BFD_RELOC_AARCH64_MOVW_G2_S: case BFD_RELOC_AARCH64_MOVW_G3: + tls_reloc = FALSE; + /* fall-through. */ case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC: case BFD_RELOC_AARCH64_TLSDESC_OFF_G1: case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC: @@ -466,6 +470,15 @@ _bfd_aarch64_elf_resolve_relocation (bfd_reloc_code_real_type r_type, case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12: case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12: case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12: + /* Weak Symbols and TLS relocations are implementation defined. For this + case we choose to emit 0. */ + if (weak_undef_p && tls_reloc) + { + _bfd_error_handler (_("%pB: warning: Weak TLS is implementation " + "defined and may not work as expected"), + input_bfd); + value = place; + } value = value + addend; break; diff --git a/bfd/elfxx-aarch64.h b/bfd/elfxx-aarch64.h index 9ab13bb..f598852 100644 --- a/bfd/elfxx-aarch64.h +++ b/bfd/elfxx-aarch64.h @@ -40,8 +40,8 @@ _bfd_aarch64_elf_put_addend (bfd *, bfd_byte *, bfd_reloc_code_real_type, reloc_howto_type *, bfd_signed_vma); extern bfd_vma -_bfd_aarch64_elf_resolve_relocation (bfd_reloc_code_real_type, bfd_vma, bfd_vma, - bfd_vma, bfd_boolean); +_bfd_aarch64_elf_resolve_relocation (bfd *, bfd_reloc_code_real_type, bfd_vma, + bfd_vma, bfd_vma, bfd_boolean); extern bfd_boolean _bfd_aarch64_elf_grok_prstatus (bfd *, Elf_Internal_Note *); |