From a5479e5ff4c29dcf93acde1424b69d4909fd3044 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 21 Dec 2012 18:15:22 +0000 Subject: [PATCH] Properly adjust h->plt.refcount bfd/ PR ld/14980 * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Properly adjust h->plt.refcount. * elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol): Likewise. ld/testsuite/ PR ld/14980 * ld-ifunc/ifunc-14c.s: New file. * ld-ifunc/ifunc-14e-i386.d: Likewise. * ld-ifunc/ifunc-14e-x86-64.d: Likewise. * ld-ifunc/ifunc-14f-i386.d: Likewise. * ld-ifunc/ifunc-14f-x86-64.d: Likewise. --- bfd/ChangeLog | 7 +++++++ bfd/elf32-i386.c | 5 ++++- bfd/elf64-x86-64.c | 5 ++++- ld/testsuite/ChangeLog | 9 +++++++++ ld/testsuite/ld-ifunc/ifunc-14c.s | 7 +++++++ ld/testsuite/ld-ifunc/ifunc-14e-i386.d | 12 ++++++++++++ ld/testsuite/ld-ifunc/ifunc-14e-x86-64.d | 12 ++++++++++++ ld/testsuite/ld-ifunc/ifunc-14f-i386.d | 12 ++++++++++++ ld/testsuite/ld-ifunc/ifunc-14f-x86-64.d | 12 ++++++++++++ 9 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 ld/testsuite/ld-ifunc/ifunc-14c.s create mode 100644 ld/testsuite/ld-ifunc/ifunc-14e-i386.d create mode 100644 ld/testsuite/ld-ifunc/ifunc-14e-x86-64.d create mode 100644 ld/testsuite/ld-ifunc/ifunc-14f-i386.d create mode 100644 ld/testsuite/ld-ifunc/ifunc-14f-x86-64.d diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 2ceee8dc1e..48f94dad22 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2012-12-21 H.J. Lu + + PR ld/14980 + * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Properly + adjust h->plt.refcount. + * elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol): Likewise. + 2012-12-19 H.J. Lu * elf32-i386.c (elf_i386_relocate_section): Replace diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index fce70b95cf..f76c7a7f40 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -2031,8 +2031,11 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info, if (pc_count || count) { h->needs_plt = 1; - h->plt.refcount += 1; h->non_got_ref = 1; + if (h->plt.refcount <= 0) + h->plt.refcount = 1; + else + h->plt.refcount += 1; } } diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index a37f793e23..11ec917e69 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -2090,8 +2090,11 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info, if (pc_count || count) { h->needs_plt = 1; - h->plt.refcount += 1; h->non_got_ref = 1; + if (h->plt.refcount <= 0) + h->plt.refcount = 1; + else + h->plt.refcount += 1; } } diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index a97bd4214a..16bffd8936 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2012-12-21 H.J. Lu + + PR ld/14980 + * ld-ifunc/ifunc-14c.s: New file. + * ld-ifunc/ifunc-14e-i386.d: Likewise. + * ld-ifunc/ifunc-14e-x86-64.d: Likewise. + * ld-ifunc/ifunc-14f-i386.d: Likewise. + * ld-ifunc/ifunc-14f-x86-64.d: Likewise. + 2012-12-19 Alan Modra PR ld/14962 diff --git a/ld/testsuite/ld-ifunc/ifunc-14c.s b/ld/testsuite/ld-ifunc/ifunc-14c.s new file mode 100644 index 0000000000..3cde56e89a --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-14c.s @@ -0,0 +1,7 @@ + .text + .globl xxx + .type xxx, @function +xxx: + jmp foo + .size xxx, .-xxx + .hidden foo diff --git a/ld/testsuite/ld-ifunc/ifunc-14e-i386.d b/ld/testsuite/ld-ifunc/ifunc-14e-i386.d new file mode 100644 index 0000000000..53809870cc --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-14e-i386.d @@ -0,0 +1,12 @@ +#source: ifunc-14a.s +#source: ifunc-14c.s +#source: ifunc-14b.s +#ld: -shared -m elf_i386 -z nocombreloc +#as: --32 +#readelf: -r --wide +#target: x86_64-*-* i?86-*-* + +#failif +#... +.* +R_386_NONE +.* +#... diff --git a/ld/testsuite/ld-ifunc/ifunc-14e-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-14e-x86-64.d new file mode 100644 index 0000000000..0955c92f13 --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-14e-x86-64.d @@ -0,0 +1,12 @@ +#source: ifunc-14a.s +#source: ifunc-14c.s +#source: ifunc-14b.s +#ld: -shared -m elf_x86_64 -z nocombreloc +#as: --64 +#readelf: -r --wide +#target: x86_64-*-* + +#failif +#... +.* +R_X86_64_NONE +.* +#... diff --git a/ld/testsuite/ld-ifunc/ifunc-14f-i386.d b/ld/testsuite/ld-ifunc/ifunc-14f-i386.d new file mode 100644 index 0000000000..ed3dc539d0 --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-14f-i386.d @@ -0,0 +1,12 @@ +#source: ifunc-14a.s +#source: ifunc-14b.s +#source: ifunc-14c.s +#ld: -shared -m elf_i386 -z nocombreloc +#as: --32 +#readelf: -r --wide +#target: x86_64-*-* i?86-*-* + +#failif +#... +.* +R_386_NONE +.* +#... diff --git a/ld/testsuite/ld-ifunc/ifunc-14f-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-14f-x86-64.d new file mode 100644 index 0000000000..12fb2257a8 --- /dev/null +++ b/ld/testsuite/ld-ifunc/ifunc-14f-x86-64.d @@ -0,0 +1,12 @@ +#source: ifunc-14a.s +#source: ifunc-14b.s +#source: ifunc-14c.s +#ld: -shared -m elf_x86_64 -z nocombreloc +#as: --64 +#readelf: -r --wide +#target: x86_64-*-* + +#failif +#... +.* +R_X86_64_NONE +.* +#...