From 4c5448074d6fce6d6c0bbaba75c4bba3f16db786 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 19 Jun 2009 16:00:33 +0000 Subject: [PATCH] bfd/ 2009-06-19 H.J. Lu * elf32-i386.c (elf_i386_tls_transition): Add a parameter, r_symndx. Report local symbol name on error. (elf_i386_check_relocs): Updated. Report local symbol name on error. (elf_i386_gc_sweep_hook): Updated. (elf_i386_relocate_section): Likewise. * elf64-x86-64.c (elf64_x86_64_tls_transition): Add a parameter, r_symndx. Report local symbol name on error. (elf64_x86_64_check_relocs): Updated. Report local symbol name on error. (elf64_x86_64_gc_sweep_hook): Updated. (elf64_x86_64_relocate_section): Likewise. ld/testsuite/ 2009-06-19 H.J. Lu * ld-i386/i386.exp: Run tlsgd2. * ld-i386/tlsgd2.d: New. * ld-i386/tlsgd2.s: Likewise. * ld-x86-64/tlsgd3.d: Updated. --- bfd/ChangeLog | 16 +++++++ bfd/elf32-i386.c | 59 ++++++++++++++++------- bfd/elf64-x86-64.c | 83 +++++++++++++++++++++++---------- ld/testsuite/ChangeLog | 9 ++++ ld/testsuite/ld-i386/i386.exp | 1 + ld/testsuite/ld-i386/tlsgd2.d | 4 ++ ld/testsuite/ld-i386/tlsgd2.s | 11 +++++ ld/testsuite/ld-x86-64/tlsgd3.d | 2 +- 8 files changed, 143 insertions(+), 42 deletions(-) create mode 100644 ld/testsuite/ld-i386/tlsgd2.d create mode 100644 ld/testsuite/ld-i386/tlsgd2.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 1120111a8b1..32a21bee7af 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,19 @@ +2009-06-19 H.J. Lu + + * elf32-i386.c (elf_i386_tls_transition): Add a parameter, + r_symndx. Report local symbol name on error. + (elf_i386_check_relocs): Updated. Report local symbol name on + error. + (elf_i386_gc_sweep_hook): Updated. + (elf_i386_relocate_section): Likewise. + + * elf64-x86-64.c (elf64_x86_64_tls_transition): Add a parameter, + r_symndx. Report local symbol name on error. + (elf64_x86_64_check_relocs): Updated. Report local symbol name + on error. + (elf64_x86_64_gc_sweep_hook): Updated. + (elf64_x86_64_relocate_section): Likewise. + 2009-06-19 Tristan Gingold * mach-o.c (bfd_mach_o_print_private_header): Fix format character. diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 36672fe7904..bac80e327eb 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -1149,7 +1149,8 @@ elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd, unsigned int *r_type, int tls_type, const Elf_Internal_Rela *rel, const Elf_Internal_Rela *relend, - struct elf_link_hash_entry *h) + struct elf_link_hash_entry *h, + unsigned long r_symndx) { unsigned int from_type = *r_type; unsigned int to_type = from_type; @@ -1224,15 +1225,27 @@ elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd, from_type, rel, relend)) { reloc_howto_type *from, *to; + const char *name; from = elf_i386_rtype_to_howto (abfd, from_type); to = elf_i386_rtype_to_howto (abfd, to_type); + if (h) + name = h->root.root.string; + else + { + Elf_Internal_Sym *isym; + struct elf_i386_link_hash_table *htab; + htab = elf_i386_hash_table (info); + isym = bfd_sym_from_r_symndx (&htab->sym_cache, + abfd, r_symndx); + name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); + } + (*_bfd_error_handler) (_("%B: TLS transition from %s to %s against `%s' at 0x%lx " "in section `%A' failed"), - abfd, sec, from->name, to->name, - h ? h->root.root.string : "a local symbol", + abfd, sec, from->name, to->name, name, (unsigned long) rel->r_offset); bfd_set_error (bfd_error_bad_value); return FALSE; @@ -1276,6 +1289,8 @@ elf_i386_check_relocs (bfd *abfd, unsigned int r_type; unsigned long r_symndx; struct elf_link_hash_entry *h; + Elf_Internal_Sym *isym; + const char *name; r_symndx = ELF32_R_SYM (rel->r_info); r_type = ELF32_R_TYPE (rel->r_info); @@ -1291,8 +1306,6 @@ elf_i386_check_relocs (bfd *abfd, if (r_symndx < symtab_hdr->sh_info) { /* A local symbol. */ - Elf_Internal_Sym *isym; - isym = bfd_sym_from_r_symndx (&htab->sym_cache, abfd, r_symndx); if (isym == NULL) @@ -1318,6 +1331,7 @@ elf_i386_check_relocs (bfd *abfd, } else { + isym = NULL; h = sym_hashes[r_symndx - symtab_hdr->sh_info]; while (h->root.type == bfd_link_hash_indirect || h->root.type == bfd_link_hash_warning) @@ -1363,13 +1377,16 @@ elf_i386_check_relocs (bfd *abfd, switch (r_type) { default: + if (h->root.root.string) + name = h->root.root.string; + else + name = bfd_elf_sym_name (abfd, symtab_hdr, isym, + NULL); (*_bfd_error_handler) (_("%B: relocation %s against STT_GNU_IFUNC " "symbol `%s' isn't handled by %s"), abfd, elf_howto_table[r_type].name, - (h->root.root.string - ? h->root.root.string : "a local symbol"), - __FUNCTION__); + name, __FUNCTION__); bfd_set_error (bfd_error_bad_value); return FALSE; @@ -1413,7 +1430,7 @@ elf_i386_check_relocs (bfd *abfd, if (! elf_i386_tls_transition (info, abfd, sec, NULL, symtab_hdr, sym_hashes, &r_type, GOT_UNKNOWN, - rel, rel_end, h)) + rel, rel_end, h, r_symndx)) return FALSE; switch (r_type) @@ -1521,11 +1538,15 @@ elf_i386_check_relocs (bfd *abfd, tls_type |= old_tls_type; else { + if (h->root.root.string) + name = h->root.root.string; + else + name = bfd_elf_sym_name (abfd, symtab_hdr, isym, + NULL); (*_bfd_error_handler) (_("%B: `%s' accessed both as normal and " "thread local symbol"), - abfd, - h ? h->root.root.string : ""); + abfd, name); return FALSE; } } @@ -1781,7 +1802,7 @@ elf_i386_gc_sweep_hook (bfd *abfd, if (! elf_i386_tls_transition (info, abfd, sec, NULL, symtab_hdr, sym_hashes, &r_type, GOT_UNKNOWN, - rel, relend, h)) + rel, relend, h, r_symndx)) return FALSE; switch (r_type) @@ -2914,6 +2935,7 @@ elf_i386_relocate_section (bfd *output_bfd, { asection *plt, *gotplt, *base_got; bfd_vma plt_index; + const char *name; if ((input_section->flags & SEC_ALLOC) == 0 || h->plt.offset == (bfd_vma) -1) @@ -2937,13 +2959,16 @@ elf_i386_relocate_section (bfd *output_bfd, switch (r_type) { default: + if (h->root.root.string) + name = h->root.root.string; + else + name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, + NULL); (*_bfd_error_handler) (_("%B: relocation %s against STT_GNU_IFUNC " "symbol `%s' isn't handled by %s"), input_bfd, elf_howto_table[r_type].name, - (h->root.root.string - ? h->root.root.string : "a local symbol"), - __FUNCTION__); + name, __FUNCTION__); bfd_set_error (bfd_error_bad_value); return FALSE; @@ -3375,7 +3400,7 @@ elf_i386_relocate_section (bfd *output_bfd, input_section, contents, symtab_hdr, sym_hashes, &r_type, tls_type, rel, - relend, h)) + relend, h, r_symndx)) return FALSE; if (r_type == R_386_TLS_LE_32) @@ -3844,7 +3869,7 @@ elf_i386_relocate_section (bfd *output_bfd, input_section, contents, symtab_hdr, sym_hashes, &r_type, GOT_UNKNOWN, rel, - relend, h)) + relend, h, r_symndx)) return FALSE; if (r_type != R_386_TLS_LDM) diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 061f785641a..44149c5bf7d 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -937,7 +937,8 @@ elf64_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd, unsigned int *r_type, int tls_type, const Elf_Internal_Rela *rel, const Elf_Internal_Rela *relend, - struct elf_link_hash_entry *h) + struct elf_link_hash_entry *h, + unsigned long r_symndx) { unsigned int from_type = *r_type; unsigned int to_type = from_type; @@ -1007,15 +1008,27 @@ elf64_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd, from_type, rel, relend)) { reloc_howto_type *from, *to; + const char *name; from = elf64_x86_64_rtype_to_howto (abfd, from_type); to = elf64_x86_64_rtype_to_howto (abfd, to_type); + if (h) + name = h->root.root.string; + else + { + Elf_Internal_Sym *isym; + struct elf64_x86_64_link_hash_table *htab; + htab = elf64_x86_64_hash_table (info); + isym = bfd_sym_from_r_symndx (&htab->sym_cache, + abfd, r_symndx); + name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); + } + (*_bfd_error_handler) (_("%B: TLS transition from %s to %s against `%s' at 0x%lx " "in section `%A' failed"), - abfd, sec, from->name, to->name, - h ? h->root.root.string : "a local symbol", + abfd, sec, from->name, to->name, name, (unsigned long) rel->r_offset); bfd_set_error (bfd_error_bad_value); return FALSE; @@ -1058,6 +1071,8 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, unsigned int r_type; unsigned long r_symndx; struct elf_link_hash_entry *h; + Elf_Internal_Sym *isym; + const char *name; r_symndx = ELF64_R_SYM (rel->r_info); r_type = ELF64_R_TYPE (rel->r_info); @@ -1072,8 +1087,6 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, if (r_symndx < symtab_hdr->sh_info) { /* A local symbol. */ - Elf_Internal_Sym *isym; - isym = bfd_sym_from_r_symndx (&htab->sym_cache, abfd, r_symndx); if (isym == NULL) @@ -1099,6 +1112,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, } else { + isym = NULL; h = sym_hashes[r_symndx - symtab_hdr->sh_info]; while (h->root.type == bfd_link_hash_indirect || h->root.type == bfd_link_hash_warning) @@ -1147,13 +1161,16 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, switch (r_type) { default: + if (h->root.root.string) + name = h->root.root.string; + else + name = bfd_elf_sym_name (abfd, symtab_hdr, isym, + NULL); (*_bfd_error_handler) (_("%B: relocation %s against STT_GNU_IFUNC " "symbol `%s' isn't handled by %s"), abfd, x86_64_elf_howto_table[r_type].name, - (h->root.root.string - ? h->root.root.string : "a local symbol"), - __FUNCTION__); + name, __FUNCTION__); bfd_set_error (bfd_error_bad_value); return FALSE; @@ -1203,7 +1220,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, if (! elf64_x86_64_tls_transition (info, abfd, sec, NULL, symtab_hdr, sym_hashes, &r_type, GOT_UNKNOWN, - rel, rel_end, h)) + rel, rel_end, h, r_symndx)) return FALSE; switch (r_type) @@ -1215,11 +1232,15 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_X86_64_TPOFF32: if (info->shared) { + if (h->root.root.string) + name = h->root.root.string; + else + name = bfd_elf_sym_name (abfd, symtab_hdr, isym, + NULL); (*_bfd_error_handler) (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"), abfd, - x86_64_elf_howto_table[r_type].name, - (h) ? h->root.root.string : "a local symbol"); + x86_64_elf_howto_table[r_type].name, name); bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -1306,9 +1327,14 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, tls_type |= old_tls_type; else { + if (h->root.root.string) + name = h->root.root.string; + else + name = bfd_elf_sym_name (abfd, symtab_hdr, + isym, NULL); (*_bfd_error_handler) (_("%B: '%s' accessed both as normal and thread local symbol"), - abfd, h ? h->root.root.string : ""); + abfd, name); return FALSE; } } @@ -1376,11 +1402,13 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, && (sec->flags & SEC_ALLOC) != 0 && (sec->flags & SEC_READONLY) != 0) { + if (h->root.root.string) + name = h->root.root.string; + else + name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); (*_bfd_error_handler) (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"), - abfd, - x86_64_elf_howto_table[r_type].name, - (h) ? h->root.root.string : "a local symbol"); + abfd, x86_64_elf_howto_table[r_type].name, name); bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -1612,7 +1640,7 @@ elf64_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info, if (! elf64_x86_64_tls_transition (info, abfd, sec, NULL, symtab_hdr, sym_hashes, &r_type, GOT_UNKNOWN, - rel, relend, h)) + rel, relend, h, r_symndx)) return FALSE; switch (r_type) @@ -2627,6 +2655,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { asection *plt; bfd_vma plt_index; + const char *name; if ((input_section->flags & SEC_ALLOC) == 0 || h->plt.offset == (bfd_vma) -1) @@ -2640,13 +2669,16 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info, switch (r_type) { default: + if (h->root.root.string) + name = h->root.root.string; + else + name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, + NULL); (*_bfd_error_handler) (_("%B: relocation %s against STT_GNU_IFUNC " "symbol `%s' isn't handled by %s"), input_bfd, x86_64_elf_howto_table[r_type].name, - (h->root.root.string - ? h->root.root.string : "a local symbol"), - __FUNCTION__); + name, __FUNCTION__); bfd_set_error (bfd_error_bad_value); return FALSE; @@ -2658,13 +2690,16 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info, case R_X86_64_64: if (rel->r_addend != 0) { + if (h->root.root.string) + name = h->root.root.string; + else + name = bfd_elf_sym_name (input_bfd, symtab_hdr, + sym, NULL); (*_bfd_error_handler) (_("%B: relocation %s against STT_GNU_IFUNC " "symbol `%s' has non-zero addend: %d"), input_bfd, x86_64_elf_howto_table[r_type].name, - (h->root.root.string - ? h->root.root.string : "a local symbol"), - rel->r_addend); + name, rel->r_addend); bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -3209,7 +3244,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info, input_section, contents, symtab_hdr, sym_hashes, &r_type, tls_type, rel, - relend, h)) + relend, h, r_symndx)) return FALSE; if (r_type == R_X86_64_TPOFF32) @@ -3543,7 +3578,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info, input_section, contents, symtab_hdr, sym_hashes, &r_type, GOT_UNKNOWN, - rel, relend, h)) + rel, relend, h, r_symndx)) return FALSE; if (r_type != R_X86_64_TLSLD) diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index fbd1ff4fe9b..c7f7adb8db8 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2009-06-19 H.J. Lu + + * ld-i386/i386.exp: Run tlsgd2. + + * ld-i386/tlsgd2.d: New. + * ld-i386/tlsgd2.s: Likewise. + + * ld-x86-64/tlsgd3.d: Updated. + 2009-06-18 Dave Korn * ld-pe/pe-run.exp (proc test_direct_link_dll): Always pass diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp index 6f75f3ae375..18e8d808bdd 100644 --- a/ld/testsuite/ld-i386/i386.exp +++ b/ld/testsuite/ld-i386/i386.exp @@ -128,6 +128,7 @@ run_dump_test "pcrel16" run_dump_test "pcrel16abs" run_dump_test "alloc" run_dump_test "warn1" +run_dump_test "tlsgd2" run_dump_test "tlsie2" run_dump_test "tlsie3" run_dump_test "tlsie4" diff --git a/ld/testsuite/ld-i386/tlsgd2.d b/ld/testsuite/ld-i386/tlsgd2.d new file mode 100644 index 00000000000..136a8fa8650 --- /dev/null +++ b/ld/testsuite/ld-i386/tlsgd2.d @@ -0,0 +1,4 @@ +#name: TLS GD->LE transition check +#as: --32 +#ld: -melf_i386 +#error: .*TLS transition from R_386_TLS_GD to R_386_TLS_LE_32 against `foo'.*failed.* diff --git a/ld/testsuite/ld-i386/tlsgd2.s b/ld/testsuite/ld-i386/tlsgd2.s new file mode 100644 index 00000000000..29d933932ab --- /dev/null +++ b/ld/testsuite/ld-i386/tlsgd2.s @@ -0,0 +1,11 @@ + .text + .globl _start +_start: + leal foo@TLSGD(%ebx), %eax + call ___tls_get_addr + .section .tdata,"awT",@progbits + .align 4 + .type foo, @object + .size foo, 4 +foo: + .long 100 diff --git a/ld/testsuite/ld-x86-64/tlsgd3.d b/ld/testsuite/ld-x86-64/tlsgd3.d index 40f8e3d2277..a8830e97911 100644 --- a/ld/testsuite/ld-x86-64/tlsgd3.d +++ b/ld/testsuite/ld-x86-64/tlsgd3.d @@ -1,4 +1,4 @@ #name: TLS GD->LE transition check #as: --64 #ld: -melf_x86_64 -#error: .*TLS transition from R_X86_64_TLSGD to R_X86_64_TPOFF32 against `a local symbol'.*failed.* +#error: .*TLS transition from R_X86_64_TLSGD to R_X86_64_TPOFF32 against `foo'.*failed.* -- 2.30.2