diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 2c7e0f79b9..12db6d7c4f 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2004-10-26 Paul Brook + + * elflink.c (elf_finalize_dynstr): Skip shared aux structure. + (bfd_elf_size_dynamic_sections): Create default version definition. + (elf_link_output_extsym): Adjust for default symbol version. + 2004-10-24 Hans-Peter Nilsson * mmo.c: Adjust to ISO C. diff --git a/bfd/elflink.c b/bfd/elflink.c index 4180042893..3fc2ddd168 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -2895,6 +2895,8 @@ elf_finalize_dynstr (bfd *output_bfd, struct bfd_link_info *info) _bfd_elf_swap_verdef_in (output_bfd, (Elf_External_Verdef *) p, &def); p += sizeof (Elf_External_Verdef); + if (def.vd_aux != sizeof (Elf_External_Verdef)) + continue; for (i = 0; i < def.vd_cnt; ++i) { _bfd_elf_swap_verdaux_in (output_bfd, @@ -5089,7 +5091,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, if (verdefs != NULL && verdefs->vernum == 0) verdefs = verdefs->next; - if (verdefs == NULL) + if (verdefs == NULL && !info->create_default_symver) _bfd_strip_section_from_output (info, s); else { @@ -5099,6 +5101,9 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, bfd_byte *p; Elf_Internal_Verdef def; Elf_Internal_Verdaux defaux; + struct bfd_link_hash_entry *bh; + struct elf_link_hash_entry *h; + const char *name; cdefs = 0; size = 0; @@ -5108,6 +5113,13 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, size += sizeof (Elf_External_Verdaux); ++cdefs; + /* Make space for the default version. */ + if (info->create_default_symver) + { + size += sizeof (Elf_External_Verdef); + ++cdefs; + } + for (t = verdefs; t != NULL; t = t->next) { struct bfd_elf_version_deps *n; @@ -5133,9 +5145,17 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, def.vd_flags = VER_FLG_BASE; def.vd_ndx = 1; def.vd_cnt = 1; - def.vd_aux = sizeof (Elf_External_Verdef); - def.vd_next = (sizeof (Elf_External_Verdef) - + sizeof (Elf_External_Verdaux)); + if (info->create_default_symver) + { + def.vd_aux = 2 * sizeof (Elf_External_Verdef); + def.vd_next = sizeof (Elf_External_Verdef); + } + else + { + def.vd_aux = sizeof (Elf_External_Verdef); + def.vd_next = (sizeof (Elf_External_Verdef) + + sizeof (Elf_External_Verdaux)); + } if (soname_indx != (bfd_size_type) -1) { @@ -5143,10 +5163,10 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, soname_indx); def.vd_hash = bfd_elf_hash (soname); defaux.vda_name = soname_indx; + name = soname; } else { - const char *name; bfd_size_type indx; name = basename (output_bfd->filename); @@ -5162,6 +5182,38 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, _bfd_elf_swap_verdef_out (output_bfd, &def, (Elf_External_Verdef *) p); p += sizeof (Elf_External_Verdef); + if (info->create_default_symver) + { + /* Add a symbol representing this version. */ + bh = NULL; + if (! (_bfd_generic_link_add_one_symbol + (info, dynobj, name, BSF_GLOBAL, bfd_abs_section_ptr, + 0, NULL, FALSE, + get_elf_backend_data (dynobj)->collect, &bh))) + return FALSE; + h = (struct elf_link_hash_entry *) bh; + h->non_elf = 0; + h->def_regular = 1; + h->type = STT_OBJECT; + h->verinfo.vertree = NULL; + + if (! bfd_elf_link_record_dynamic_symbol (info, h)) + return FALSE; + + /* Create a duplicate of the base version with the same + aux block, but different flags. */ + def.vd_flags = 0; + def.vd_ndx = 2; + def.vd_aux = sizeof (Elf_External_Verdef); + if (verdefs) + def.vd_next = (sizeof (Elf_External_Verdef) + + sizeof (Elf_External_Verdaux)); + else + def.vd_next = 0; + _bfd_elf_swap_verdef_out (output_bfd, &def, + (Elf_External_Verdef *) p); + p += sizeof (Elf_External_Verdef); + } _bfd_elf_swap_verdaux_out (output_bfd, &defaux, (Elf_External_Verdaux *) p); p += sizeof (Elf_External_Verdaux); @@ -5170,8 +5222,6 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, { unsigned int cdeps; struct bfd_elf_version_deps *n; - struct elf_link_hash_entry *h; - struct bfd_link_hash_entry *bh; cdeps = 0; for (n = t->deps; n != NULL; n = n->next) @@ -5199,7 +5249,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, && t->locals.list == NULL && ! t->used) def.vd_flags |= VER_FLG_WEAK; - def.vd_ndx = t->vernum + 1; + def.vd_ndx = t->vernum + (info->create_default_symver ? 2 : 1); def.vd_cnt = cdeps + 1; def.vd_hash = bfd_elf_hash (t->name); def.vd_aux = sizeof (Elf_External_Verdef); @@ -5396,7 +5446,8 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, s = bfd_get_section_by_name (dynobj, ".gnu.version"); BFD_ASSERT (s != NULL); if (dynsymcount == 0 - || (verdefs == NULL && elf_tdata (output_bfd)->verref == NULL)) + || (verdefs == NULL && elf_tdata (output_bfd)->verref == NULL + && !info->create_default_symver)) { _bfd_strip_section_from_output (info, s); /* The DYNSYMCOUNT might have changed if we were going to @@ -6334,6 +6385,8 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data) iversym.vs_vers = 1; else iversym.vs_vers = h->verinfo.vertree->vernum + 1; + if (finfo->info->create_default_symver) + iversym.vs_vers++; } if (h->hidden) diff --git a/include/ChangeLog b/include/ChangeLog index 48398d7b7e..7a501a4e5e 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2004-10-26 Paul Brook + + * bfdlink.h (struct bfd_link_info): Add create_default_symver. + 2004-10-21 Tomer Levi * opcode/crx.h (operand_type): Remove redundant types i3, i4, diff --git a/include/bfdlink.h b/include/bfdlink.h index b5673421fe..ab59b7c781 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -262,6 +262,9 @@ struct bfd_link_info /* TRUE if ok to have version with no definition. */ unsigned int allow_undefined_version: 1; + /* TRUE id a fedault symbol version should be created and used. */ + unsigned int create_default_symver: 1; + /* TRUE if symbols should be retained in memory, FALSE if they should be freed and reread. */ unsigned int keep_memory: 1; diff --git a/ld/ChangeLog b/ld/ChangeLog index c8f0caa52e..864135902d 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,11 @@ +2004-10-26 Paul Brook + + * ld.texinfo: Document --default-symver. + * ldmain.c (main): Set link_info.create_default_symver. + * lexsup.c (enum option_values): Add OPTION_DEFAULT_SYMVER. + (ld_options): Add default-symver. + (parse_args): Handle OPTION_DEFAULT_SYMVER. + 2004-10-24 Danny Smith * pe-dll.c (process_def_file): Don't export all symbols by default if diff --git a/ld/ld.texinfo b/ld/ld.texinfo index 5a494c236f..5944f4494f 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -1234,6 +1234,11 @@ Normally when a symbol has an undefined version, the linker will ignore it. This option disallows symbols with undefined version and a fatal error will be issued instead. +@kindex --default-symver +@item --default-symver +Create and use a default symbol version (the soname) for unversioned +symbols. + @kindex --no-warn-mismatch @item --no-warn-mismatch Normally @command{ld} will give an error if you try to link together input diff --git a/ld/ldmain.c b/ld/ldmain.c index 7344da2098..6eb3774123 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -306,6 +306,7 @@ main (int argc, char **argv) link_info.unresolved_syms_in_shared_libs = RM_NOT_YET_SET; link_info.allow_multiple_definition = FALSE; link_info.allow_undefined_version = TRUE; + link_info.create_default_symver = FALSE; link_info.keep_memory = TRUE; link_info.notice_all = FALSE; link_info.nocopyreloc = FALSE; diff --git a/ld/lexsup.c b/ld/lexsup.c index e40cf6226f..be7c0a9126 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -134,6 +134,7 @@ enum option_values OPTION_NO_ALLOW_SHLIB_UNDEFINED, OPTION_ALLOW_MULTIPLE_DEFINITION, OPTION_NO_UNDEFINED_VERSION, + OPTION_DEFAULT_SYMVER, OPTION_DISCARD_NONE, OPTION_SPARE_DYNAMIC_TAGS, OPTION_NO_DEFINE_COMMON, @@ -393,6 +394,8 @@ static const struct ld_option ld_options[] = '\0', NULL, N_("Allow multiple definitions"), TWO_DASHES }, { {"no-undefined-version", no_argument, NULL, OPTION_NO_UNDEFINED_VERSION}, '\0', NULL, N_("Disallow undefined version"), TWO_DASHES }, + { {"default-symver", no_argument, NULL, OPTION_DEFAULT_SYMVER}, + '\0', NULL, N_("Create default symbol version"), TWO_DASHES }, { {"no-warn-mismatch", no_argument, NULL, OPTION_NO_WARN_MISMATCH}, '\0', NULL, N_("Don't warn about mismatched input files"), TWO_DASHES}, { {"no-whole-archive", no_argument, NULL, OPTION_NO_WHOLE_ARCHIVE}, @@ -902,6 +905,9 @@ parse_args (unsigned argc, char **argv) case OPTION_NO_UNDEFINED_VERSION: link_info.allow_undefined_version = FALSE; break; + case OPTION_DEFAULT_SYMVER: + link_info.create_default_symver = TRUE; + break; case OPTION_NO_WARN_MISMATCH: command_line.warn_mismatch = FALSE; break; diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 880ce85a83..d41972dd1b 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2004-10-26 Paul Brook + + * ld-elfvers/vers.exp (build_binary): Add ldargs parameter. + (build_vers_lib_pic_flags): New function. + Add vers29 test. + * ld-elfvers/vers29.c: New file. + * ld-elfvers/vers29.dsym: New file. + * ld-elfvers/vers29.ver: New file. + 2004-10-24 Hans-Peter Nilsson * ld-mmix/sec-8m.d: Adjust test for dump using correct section diff --git a/ld/testsuite/ld-elfvers/vers.exp b/ld/testsuite/ld-elfvers/vers.exp index 3ee42e868a..9662a6b2b9 100644 --- a/ld/testsuite/ld-elfvers/vers.exp +++ b/ld/testsuite/ld-elfvers/vers.exp @@ -498,7 +498,7 @@ proc objdump_versionstuff { objdump object expectfile } { } } -proc build_binary { shared pic test source libname other mapfile verexp versymexp symexp } { +proc build_binary { shared pic test source libname other mapfile verexp versymexp symexp ldargs } { global ld global srcdir global subdir @@ -534,7 +534,7 @@ proc build_binary { shared pic test source libname other mapfile verexp versymex set script_arg "$script $srcdir/$subdir/$mapfile" } - if {![ld_simple_link $ld $tmpdir/$libname.so "$shared $tmpdir/$libname.o $other_lib $script_arg"]} { + if {![ld_simple_link $ld $tmpdir/$libname.so "$shared $tmpdir/$libname.o $other_lib $script_arg $ldargs"]} { fail "$test" return } @@ -566,18 +566,24 @@ proc build_binary { shared pic test source libname other mapfile verexp versymex } proc build_executable { test source libname other mapfile verexp versymexp symexp } { - build_binary "" "" $test $source $libname $other $mapfile $verexp $versymexp $symexp + build_binary "" "" $test $source $libname $other $mapfile $verexp $versymexp $symexp "" } proc build_vers_lib_no_pic { test source libname other mapfile verexp versymexp symexp } { global shared - build_binary $shared "" $test $source $libname $other $mapfile $verexp $versymexp $symexp + build_binary $shared "" $test $source $libname $other $mapfile $verexp $versymexp $symexp "" } proc build_vers_lib_pic { test source libname other mapfile verexp versymexp symexp } { global picflag global shared - build_binary $shared $picflag $test $source $libname $other $mapfile $verexp $versymexp $symexp + build_binary $shared $picflag $test $source $libname $other $mapfile $verexp $versymexp $symexp "" +} + +proc build_vers_lib_pic_flags { test source libname other mapfile verexp versymexp symexp ldargs } { + global picflag + global shared + build_binary $shared $picflag $test $source $libname $other $mapfile $verexp $versymexp $symexp $ldargs } proc test_ldfail { test flag source execname other mapfile whyfail } { @@ -944,3 +950,4 @@ build_executable "vers27d5" vers27d3.c vers27d5 "vers27d4.so vers27b.o vers27a.s build_vers_lib_pic "vers28a" vers28a.c vers28a "" "" vers28a.ver vers28a.dsym "" build_vers_lib_pic "vers28b" vers28b.c vers28b "" vers28b.map vers28b.ver vers28b.dsym "" build_vers_lib_pic "vers28c" vers28c.c vers28c "vers28b.so vers28a.so" "" vers28c.ver vers28c.dsym "" +build_vers_lib_pic_flags "vers29" vers29.c vers29 "" "" vers29.ver vers29.dsym "" "--default-symver"