This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH: Report local symbol name on error for x86
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: binutils at sources dot redhat dot com
- Date: Fri, 19 Jun 2009 08:58:39 -0700
- Subject: PATCH: Report local symbol name on error for x86
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
Hi,
I am checking this patch to report local symbol name on error for x86.
H.J.
---
bfd/
2009-06-19 H.J. Lu <hongjiu.lu@intel.com>
* 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 <hongjiu.lu@intel.com>
* ld-i386/i386.exp: Run tlsgd2.
* ld-i386/tlsgd2.d: New.
* ld-i386/tlsgd2.s: Likewise.
* ld-x86-64/tlsgd3.d: Updated.
diff -x REVISION -x .svn -x CVS -uprN -x ChangeLog.ifunc \
../binutils/src binutils
diff -x REVISION -x .svn -x CVS -uprN -x ChangeLog.ifunc ../binutils/src/bfd/elf32-i386.c binutils/bfd/elf32-i386.c
--- ../binutils/src/bfd/elf32-i386.c 2009-06-18 08:49:50.000000000 -0700
+++ binutils/bfd/elf32-i386.c 2009-06-19 07:35:37.000000000 -0700
@@ -1149,7 +1149,8 @@ elf_i386_tls_transition (struct bfd_link
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
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 : "<local>");
+ 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_b
{
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_b
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_b
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_b
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 -x REVISION -x .svn -x CVS -uprN -x ChangeLog.ifunc ../binutils/src/bfd/elf64-x86-64.c binutils/bfd/elf64-x86-64.c
--- ../binutils/src/bfd/elf64-x86-64.c 2009-06-18 08:49:50.000000000 -0700
+++ binutils/bfd/elf64-x86-64.c 2009-06-19 07:35:22.000000000 -0700
@@ -937,7 +937,8 @@ elf64_x86_64_tls_transition (struct bfd_
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_
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, st
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, st
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, st
}
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, st
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, st
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, st
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, st
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 : "<local>");
+ abfd, name);
return FALSE;
}
}
@@ -1376,11 +1402,13 @@ elf64_x86_64_check_relocs (bfd *abfd, st
&& (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, s
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 *outp
{
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 *outp
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 *outp
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 *outp
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 *outp
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 -x REVISION -x .svn -x CVS -uprN -x ChangeLog.ifunc ../binutils/src/ld/testsuite/ld-i386/i386.exp binutils/ld/testsuite/ld-i386/i386.exp
--- ../binutils/src/ld/testsuite/ld-i386/i386.exp 2009-05-05 10:55:54.000000000 -0700
+++ binutils/ld/testsuite/ld-i386/i386.exp 2009-06-19 08:48:30.000000000 -0700
@@ -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 -x REVISION -x .svn -x CVS -uprN -x ChangeLog.ifunc ../binutils/src/ld/testsuite/ld-i386/tlsgd2.d binutils/ld/testsuite/ld-i386/tlsgd2.d
--- ../binutils/src/ld/testsuite/ld-i386/tlsgd2.d 1969-12-31 16:00:00.000000000 -0800
+++ binutils/ld/testsuite/ld-i386/tlsgd2.d 2009-06-19 08:50:18.000000000 -0700
@@ -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 -x REVISION -x .svn -x CVS -uprN -x ChangeLog.ifunc ../binutils/src/ld/testsuite/ld-i386/tlsgd2.s binutils/ld/testsuite/ld-i386/tlsgd2.s
--- ../binutils/src/ld/testsuite/ld-i386/tlsgd2.s 1969-12-31 16:00:00.000000000 -0800
+++ binutils/ld/testsuite/ld-i386/tlsgd2.s 2009-06-19 08:45:39.000000000 -0700
@@ -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 -x REVISION -x .svn -x CVS -uprN -x ChangeLog.ifunc ../binutils/src/ld/testsuite/ld-x86-64/tlsgd3.d binutils/ld/testsuite/ld-x86-64/tlsgd3.d
--- ../binutils/src/ld/testsuite/ld-x86-64/tlsgd3.d 2009-05-05 10:55:57.000000000 -0700
+++ binutils/ld/testsuite/ld-x86-64/tlsgd3.d 2009-06-19 07:39:55.000000000 -0700
@@ -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.*