diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2014-01-21 15:42:43 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2014-01-21 15:42:51 -0800 |
commit | 4584ec12076e088cf36965b88ef8710ca85491f9 (patch) | |
tree | 9b22f0bbf45bb9e59e1f3516cfb773d556d2a567 | |
parent | efec45729843f9b1864b2a9b491adff85304525a (diff) | |
download | gdb-4584ec12076e088cf36965b88ef8710ca85491f9.zip gdb-4584ec12076e088cf36965b88ef8710ca85491f9.tar.gz gdb-4584ec12076e088cf36965b88ef8710ca85491f9.tar.bz2 |
Check incompatible existing default symbol definition
After resolving a versioned reference, foo@VER1, to a default versioned
definition, foo@@VER1, from a shared object, we also merge it with
the existing regular default symbol definition, foo. When foo is IFUNC
and foo@@VER1 aren't, we will merge 2 incompatible definitions. This
patch avoids merging foo@@VER1 definition with foo definition if
one is IFUNC and the other isn't.
-rw-r--r-- | bfd/ChangeLog | 8 | ||||
-rw-r--r-- | bfd/elflink.c | 13 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 14 | ||||
-rw-r--r-- | ld/testsuite/ld-ifunc/dummy.c | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-ifunc/ifunc.exp | 45 | ||||
-rw-r--r-- | ld/testsuite/ld-ifunc/pr16467.out | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-ifunc/pr16467a.c | 5 | ||||
-rw-r--r-- | ld/testsuite/ld-ifunc/pr16467a.map | 4 | ||||
-rw-r--r-- | ld/testsuite/ld-ifunc/pr16467b.c | 7 | ||||
-rw-r--r-- | ld/testsuite/ld-ifunc/pr16467b.map | 4 | ||||
-rw-r--r-- | ld/testsuite/ld-ifunc/pr16467c.c | 9 |
11 files changed, 106 insertions, 5 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5923bc3..c70a7db 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,13 @@ 2014-01-21 H.J. Lu <hongjiu.lu@intel.com> + PR ld/16467 + * elflink.c (_bfd_elf_merge_symbol): When types of the existing + regular default symbol definition and the versioned dynamic + symbol definition mismatch, skip the default symbol definition + if one of them is IFUNC. + +2014-01-21 H.J. Lu <hongjiu.lu@intel.com> + PR ld/2404 * elflink.c (_bfd_elf_merge_symbol): Don't check info->shared, info->export_dynamic nor h->ref_dynamic for type mismatch when diff --git a/bfd/elflink.c b/bfd/elflink.c index d0006da..792e14e 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -1092,11 +1092,14 @@ _bfd_elf_merge_symbol (bfd *abfd, && newdyn && newdef && !olddyn - && (olddef || h->root.type == bfd_link_hash_common) - && ELF_ST_TYPE (sym->st_info) != h->type - && ELF_ST_TYPE (sym->st_info) != STT_NOTYPE - && h->type != STT_NOTYPE - && !(newfunc && oldfunc)) + && (((olddef || h->root.type == bfd_link_hash_common) + && ELF_ST_TYPE (sym->st_info) != h->type + && ELF_ST_TYPE (sym->st_info) != STT_NOTYPE + && h->type != STT_NOTYPE + && !(newfunc && oldfunc)) + || (olddef + && ((h->type == STT_GNU_IFUNC) + != (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC))))) { *skip = TRUE; return TRUE; diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index ac65a3a..a092428 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,5 +1,19 @@ 2014-01-21 H.J. Lu <hongjiu.lu@intel.com> + PR ld/16467 + * ld-ifunc/dummy.c: New file. + * ld-ifunc/pr16467.out: Likewise. + * ld-ifunc/pr16467a.c: Likewise. + * ld-ifunc/pr16467a.map: Likewise. + * ld-ifunc/pr16467b.c: Likewise. + * ld-ifunc/pr16467b.map: Likewise. + * ld-ifunc/pr16467c.c: Likewise. + + * ld-ifunc/ifunc.exp (run_cc_link_tests): New. + (run_ld_link_exec_tests): Run pr16467. + +2014-01-21 H.J. Lu <hongjiu.lu@intel.com> + PR ld/2404 * ld-elf/shared.exp: Add a PIE test for PR ld/2404. diff --git a/ld/testsuite/ld-ifunc/dummy.c b/ld/testsuite/ld-ifunc/dummy.c new file mode 100644 index 0000000..5c03287 --- /dev/null +++ b/ld/testsuite/ld-ifunc/dummy.c @@ -0,0 +1 @@ +/* An empty file. */ diff --git a/ld/testsuite/ld-ifunc/ifunc.exp b/ld/testsuite/ld-ifunc/ifunc.exp index fb106c6..d7ff445 100644 --- a/ld/testsuite/ld-ifunc/ifunc.exp +++ b/ld/testsuite/ld-ifunc/ifunc.exp @@ -349,6 +349,42 @@ if { $verbose < 1 } { remote_file host delete "tmpdir/static_nonifunc_prog" } +run_cc_link_tests [list \ + [list \ + "Build libpr16467a.so" \ + "-shared -Wl,--version-script=pr16467a.map" \ + "-fPIC" \ + { pr16467a.c } \ + {} \ + "libpr16467a.so" \ + ] \ + [list \ + "Build libpr16467b.a" \ + "" \ + "-fPIC" \ + { pr16467b.c } \ + {} \ + "libpr16467b.a" \ + ] \ + [list \ + "Build libpr16467b.so" \ + "-shared tmpdir/pr16467b.o tmpdir/libpr16467a.so \ + -Wl,--version-script=pr16467b.map" \ + "-fPIC" \ + { dummy.c } \ + {} \ + "libpr16467b.so" \ + ] \ + [list \ + "Build libpr16467c.a" \ + "" \ + "" \ + { pr16467c.c } \ + {} \ + "libpr16467c.a" \ + ] \ +] + run_ld_link_exec_tests [] [list \ [list \ "Common symbol override ifunc test 1a" \ @@ -368,6 +404,15 @@ run_ld_link_exec_tests [] [list \ "ifunc-common-1.out" \ "-g" \ ] \ + [list \ + "Run pr16467" \ + "tmpdir/pr16467c.o tmpdir/libpr16467b.so tmpdir/libpr16467a.so" \ + "" \ + { dummy.c } \ + "pr16467" \ + "pr16467.out" \ + "" \ + ] \ ] set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]] diff --git a/ld/testsuite/ld-ifunc/pr16467.out b/ld/testsuite/ld-ifunc/pr16467.out new file mode 100644 index 0000000..d86bac9 --- /dev/null +++ b/ld/testsuite/ld-ifunc/pr16467.out @@ -0,0 +1 @@ +OK diff --git a/ld/testsuite/ld-ifunc/pr16467a.c b/ld/testsuite/ld-ifunc/pr16467a.c new file mode 100644 index 0000000..ae3f084 --- /dev/null +++ b/ld/testsuite/ld-ifunc/pr16467a.c @@ -0,0 +1,5 @@ +const char * +sd_get_seats(void) +{ + return "OK"; +} diff --git a/ld/testsuite/ld-ifunc/pr16467a.map b/ld/testsuite/ld-ifunc/pr16467a.map new file mode 100644 index 0000000..d677f37 --- /dev/null +++ b/ld/testsuite/ld-ifunc/pr16467a.map @@ -0,0 +1,4 @@ +LIBSYSTEMD_209 { +global: + sd_get_seats; +}; diff --git a/ld/testsuite/ld-ifunc/pr16467b.c b/ld/testsuite/ld-ifunc/pr16467b.c new file mode 100644 index 0000000..264f6cf --- /dev/null +++ b/ld/testsuite/ld-ifunc/pr16467b.c @@ -0,0 +1,7 @@ +void new_sd_get_seats(void); +__asm__(".symver new_sd_get_seats,sd_get_seats@LIBSYSTEMD_209"); +void (*resolve_sd_get_seats(void)) (void) __asm__ ("sd_get_seats"); +void (*resolve_sd_get_seats(void)) (void) { + return new_sd_get_seats; +} +__asm__(".type sd_get_seats, %gnu_indirect_function"); diff --git a/ld/testsuite/ld-ifunc/pr16467b.map b/ld/testsuite/ld-ifunc/pr16467b.map new file mode 100644 index 0000000..1f263de --- /dev/null +++ b/ld/testsuite/ld-ifunc/pr16467b.map @@ -0,0 +1,4 @@ +LIBSYSTEMD_208 { +global: + sd_get_seats; +}; diff --git a/ld/testsuite/ld-ifunc/pr16467c.c b/ld/testsuite/ld-ifunc/pr16467c.c new file mode 100644 index 0000000..e2a901c --- /dev/null +++ b/ld/testsuite/ld-ifunc/pr16467c.c @@ -0,0 +1,9 @@ +#include <stdio.h> +const char* sd_get_seats(void); + +int +main (int argc, char **argv) +{ + printf("%s\n", sd_get_seats()); + return 0; +} |