From c424e0e973d0cee8125e328fa2716473961afad4 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 5 May 2003 03:33:09 +0000 Subject: [PATCH] bfd/ 2003-05-04 H.J. Lu * elflink.h (elf_merge_symbol): Correctly handle weak definiton. ld/testsuite/ 2003-05-04 H.J. Lu * ld-elfvers/vers18.dsym: Updated for weak definiton change. * ld-elfvers/vers18.ver: Likewise. * ld-elfvers/vers19.ver: Likewise. * ld-elfweak/elfweak.exp: Remove xfail. --- bfd/ChangeLog | 4 ++ bfd/elflink.h | 77 +++++++++++++++++++++------ ld/testsuite/ChangeLog | 8 +++ ld/testsuite/ld-elfvers/vers18.dsym | 2 +- ld/testsuite/ld-elfvers/vers18.ver | 7 +-- ld/testsuite/ld-elfvers/vers19.ver | 2 +- ld/testsuite/ld-elfweak/dsowdata.dsym | 2 +- ld/testsuite/ld-elfweak/elfweak.exp | 12 ----- ld/testsuite/ld-elfweak/weakdata.dsym | 2 +- 9 files changed, 79 insertions(+), 37 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7950b0a673..dfbc26d863 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,7 @@ +2003-05-04 H.J. Lu + + * elflink.h (elf_merge_symbol): Correctly handle weak definiton. + 2003-05-04 H.J. Lu * elflink.h (elf_merge_symbol): Don't record a hidden/internal diff --git a/bfd/elflink.h b/bfd/elflink.h index 3aec4e06f0..dfcce7d256 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -484,6 +484,7 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip, int bind; bfd *oldbfd; bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon; + bfd_boolean newweakdef, oldweakdef, newweakundef, oldweakundef; *skip = FALSE; *override = FALSE; @@ -670,6 +671,49 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip, return TRUE; } + /* We need to treat weak definiton right, depending on if there is a + definition from a dynamic object. */ + if (bind == STB_WEAK) + { + if (olddef) + { + newweakdef = TRUE; + newweakundef = FALSE; + } + else + { + newweakdef = FALSE; + newweakundef = TRUE; + } + } + else + newweakdef = newweakundef = FALSE; + + /* If the new weak definition comes from a relocatable file and the + old symbol comes from a dynamic object, we treat the new one as + strong. */ + if (newweakdef && !newdyn && olddyn) + newweakdef = FALSE; + + if (h->root.type == bfd_link_hash_defweak) + { + oldweakdef = TRUE; + oldweakundef = FALSE; + } + else if (h->root.type == bfd_link_hash_undefweak) + { + oldweakdef = FALSE; + oldweakundef = TRUE; + } + else + oldweakdef = oldweakundef = FALSE; + + /* If the old weak definition comes from a relocatable file and the + new symbol comes from a dynamic object, we treat the old one as + strong. */ + if (oldweakdef && !olddyn && newdyn) + oldweakdef = FALSE; + /* NEWDYNCOMMON and OLDDYNCOMMON indicate whether the new or old symbol, respectively, appears to be a common symbol in a dynamic object. If a symbol appears in an uninitialized section, and is @@ -698,7 +742,8 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip, && (sec->flags & SEC_ALLOC) != 0 && (sec->flags & SEC_LOAD) == 0 && sym->st_size > 0 - && bind != STB_WEAK + && !newweakdef + && !newweakundef && ELF_ST_TYPE (sym->st_info) != STT_FUNC) newdyncommon = TRUE; else @@ -721,9 +766,10 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip, a shared object, in which case, the DT_NEEDED entry may not be required at the run time. */ - if ((! dt_needed && h->root.type == bfd_link_hash_defweak) - || h->root.type == bfd_link_hash_undefweak - || bind == STB_WEAK) + if ((! dt_needed && oldweakdef) + || oldweakundef + || newweakdef + || newweakundef) *type_change_ok = TRUE; /* It's OK to change the size if either the existing symbol or the @@ -781,11 +827,13 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip, && newdef && (olddef || (h->root.type == bfd_link_hash_common - && (bind == STB_WEAK + && (newweakdef + || newweakundef || ELF_ST_TYPE (sym->st_info) == STT_FUNC))) - && (h->root.type != bfd_link_hash_defweak + && (!oldweakdef || dt_needed - || bind == STB_WEAK)) + || newweakdef + || newweakundef)) { *override = TRUE; newdef = FALSE; @@ -838,13 +886,11 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip, if (! newdyn && (newdef || (bfd_is_com_section (sec) - && (h->root.type == bfd_link_hash_defweak - || h->type == STT_FUNC))) + && (oldweakdef || h->type == STT_FUNC))) && olddyn && olddef && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - && (bind != STB_WEAK - || h->root.type == bfd_link_hash_defweak)) + && ((!newweakdef && !newweakundef) || oldweakdef)) { /* Change the hash table entry to undefined, and let _bfd_generic_link_add_one_symbol do the right thing with the @@ -940,10 +986,11 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip, the DT_NEEDED entry may not be required at the run time. */ if (olddef && ! dt_needed - && h->root.type == bfd_link_hash_defweak + && oldweakdef && newdef && newdyn - && bind != STB_WEAK) + && !newweakdef + && !newweakundef) { /* To make this work we have to frob the flags so that the rest of the code does not think we are using the regular @@ -969,10 +1016,10 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip, as a definition. */ if (olddef && olddyn - && h->root.type != bfd_link_hash_defweak + && !oldweakdef && newdef && ! newdyn - && bind == STB_WEAK) + && (newweakdef || newweakundef)) *override = TRUE; return TRUE; diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 9a2bb79fc2..372b812f39 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2003-05-04 H.J. Lu + + * ld-elfvers/vers18.dsym: Updated for weak definiton change. + * ld-elfvers/vers18.ver: Likewise. + * ld-elfvers/vers19.ver: Likewise. + + * ld-elfweak/elfweak.exp: Remove xfail. + 2003-05-04 Alexandre Oliva * ld-mips-elf/multi-got-1.d: Force into big-endian mode. diff --git a/ld/testsuite/ld-elfvers/vers18.dsym b/ld/testsuite/ld-elfvers/vers18.dsym index dc3ad7b4c1..c60237a310 100644 --- a/ld/testsuite/ld-elfvers/vers18.dsym +++ b/ld/testsuite/ld-elfvers/vers18.dsym @@ -1,7 +1,7 @@ -[0-9a-f]* w DF (\*UND\*) [0-9a-f]* VERS_2.0 (0x[0-9a-f][0-9a-f] )?show_foo [0]* g DO \*ABS\* [0]* VERS_1.1 VERS_1.1 [0]* g DO \*ABS\* [0]* VERS_1.2 VERS_1.2 [0]* g DO \*ABS\* [0]* VERS_2.0 VERS_2.0 [0-9a-f]* w DF (.text|\*ABS\*) [0-9a-f]* \(Base\) (0x[0-9a-f][0-9a-f] )?show_foo [0-9a-f]* w DF (.text|\*ABS\*) [0-9a-f]* \(VERS_1.1\) (0x[0-9a-f][0-9a-f] )?show_foo [0-9a-f]* w DF (.text|\*ABS\*) [0-9a-f]* \(VERS_1.2\) (0x[0-9a-f][0-9a-f] )?show_foo +[0-9a-f]* w DF (.text|\*ABS\*) [0-9a-f]* VERS_2.0 (0x[0-9a-f][0-9a-f] )?show_foo diff --git a/ld/testsuite/ld-elfvers/vers18.ver b/ld/testsuite/ld-elfvers/vers18.ver index 5df92c8f4c..c6b14e8f9a 100644 --- a/ld/testsuite/ld-elfvers/vers18.ver +++ b/ld/testsuite/ld-elfvers/vers18.ver @@ -3,10 +3,5 @@ Version definitions: 2 0x00 0x0a7927b1 VERS_1.1 3 0x00 0x0a7927b2 VERS_1.2 VERS_1.1 -4 0x02 0x0a7922b0 VERS_2.0 +4 0x00 0x0a7922b0 VERS_2.0 VERS_1.2 - -Version References: - required from tmpdir/vers17.so: - 0x0a7922b0 0x00 05 VERS_2.0 - diff --git a/ld/testsuite/ld-elfvers/vers19.ver b/ld/testsuite/ld-elfvers/vers19.ver index 5969797e23..28a52c4829 100644 --- a/ld/testsuite/ld-elfvers/vers19.ver +++ b/ld/testsuite/ld-elfvers/vers19.ver @@ -1,3 +1,3 @@ Version References: - required from vers17.so: + required from tmpdir/vers18.so: 0x0a7922b0 0x00 0[23] VERS_2.0 diff --git a/ld/testsuite/ld-elfweak/dsowdata.dsym b/ld/testsuite/ld-elfweak/dsowdata.dsym index 0b5cca3a15..e0f579ae12 100644 --- a/ld/testsuite/ld-elfweak/dsowdata.dsym +++ b/ld/testsuite/ld-elfweak/dsowdata.dsym @@ -1 +1 @@ -[0-9a-f]*[ ]+w[ ]+DO[ ]+.data[ ]+[0-9a-f]*[ ]+(Base[ ]+|[ ]*)deallocate_foo +[0-9a-f]*[ ]+w[ ]+DO[ ]+.(s|)data[ ]+[0-9a-f]*[ ]+(Base[ ]+|[ ]*)deallocate_foo diff --git a/ld/testsuite/ld-elfweak/elfweak.exp b/ld/testsuite/ld-elfweak/elfweak.exp index 11dd323780..d67538d6be 100644 --- a/ld/testsuite/ld-elfweak/elfweak.exp +++ b/ld/testsuite/ld-elfweak/elfweak.exp @@ -443,36 +443,24 @@ if {![ld_link $ld $tmpdir/libbar1a.so "$shared $tmpdir/bar1a.o $tmpdir/libfoo1a. build_lib "ELF DSO weak func first" libfoo "foo.o bar.o" dso.dsym build_lib "ELF DSO weak func last" libfoo "bar.o foo.o" dso.dsym -setup_xfail "*-*-*" build_lib "ELF DSO weak func first DSO" libfoo "foo.o libbar.so" dsow.dsym -setup_xfail "*-*-*" build_lib "ELF DSO weak func last DSO" libfoo "libbar.so foo.o" dsow.dsym build_exec "ELF weak func first" foo "main.o bar.o" "" strong "" strong.sym build_exec "ELF weak func last" foo "bar.o main.o" "" strong "" strong.sym -setup_xfail "*-*-*" build_exec "ELF weak func first DSO" foo "main.o libbar.so" "-rpath ." weak weak.dsym "" -setup_xfail "*-*-*" build_exec "ELF weak func last DSO" foo "libbar.so main.o" "-rpath ." weak weak.dsym "" build_lib "ELF DSO weak data first" libfoo "bar1a.o foo1a.o" dsodata.dsym build_lib "ELF DSO weak data last" libfoo "foo1a.o bar1a.o" dsodata.dsym -setup_xfail "*-*-*" build_lib "ELF DSO weak data first DSO" libfoo "main1.o libfoo1a.so" dsowdata.dsym -setup_xfail "*-*-*" build_lib "ELF DSO weak data last DSO" libfoo "libfoo1a.so main1.o" dsowdata.dsym -setup_xfail "*-*-*" build_lib "ELF DSO weak data first DSO common" libfoo "main1.o libfoo1b.so" dsowdata.dsym -setup_xfail "*-*-*" build_lib "ELF DSO weak data last DSO common" libfoo "libfoo1b.so main1.o" dsowdata.dsym build_exec "ELF weak data first" foo "main1.o bar1a.o foo1a.o" "" strongdata "" strongdata.sym build_exec "ELF weak data last" foo "foo1a.o main1.o bar1a.o" "" strongdata "" strongdata.sym build_exec "ELF weak data first common" foo "main1.o bar1a.o foo1b.o" "" strongdata "" strongcomm.sym build_exec "ELF weak data last common" foo "foo1b.o main1.o bar1a.o" "" strongdata "" strongcomm.sym -setup_xfail "*-*-*" build_exec "ELF weak data first DSO" foo "main1.o libbar1a.so libfoo1a.so" "-rpath ." weakdata weakdata.dsym "" -setup_xfail "*-*-*" build_exec "ELF weak data last DSO" foo "libfoo1a.so main1.o libbar1a.so" "-rpath ." weakdata weakdata.dsym "" -setup_xfail "*-*-*" build_exec "ELF weak data first DSO common" foo "main1.o libbar1a.so libfoo1b.so" "-rpath ." weakdata weakdata.dsym "" -setup_xfail "*-*-*" build_exec "ELF weak data last DSO common" foo "libfoo1b.so main1.o libbar1a.so" "-rpath ." weakdata weakdata.dsym "" diff --git a/ld/testsuite/ld-elfweak/weakdata.dsym b/ld/testsuite/ld-elfweak/weakdata.dsym index 0b5cca3a15..e0f579ae12 100644 --- a/ld/testsuite/ld-elfweak/weakdata.dsym +++ b/ld/testsuite/ld-elfweak/weakdata.dsym @@ -1 +1 @@ -[0-9a-f]*[ ]+w[ ]+DO[ ]+.data[ ]+[0-9a-f]*[ ]+(Base[ ]+|[ ]*)deallocate_foo +[0-9a-f]*[ ]+w[ ]+DO[ ]+.(s|)data[ ]+[0-9a-f]*[ ]+(Base[ ]+|[ ]*)deallocate_foo -- 2.34.1