From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8638 invoked by alias); 4 Nov 2004 19:39:50 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 8598 invoked from network); 4 Nov 2004 19:39:43 -0000 Received: from unknown (HELO galaxy.systems.pipex.net) (62.241.162.31) by sourceware.org with SMTP; 4 Nov 2004 19:39:43 -0000 Received: from nowt.org (81-178-254-30.dsl.pipex.com [81.178.254.30]) by galaxy.systems.pipex.net (Postfix) with ESMTP id 3A51BE000198 for ; Thu, 4 Nov 2004 19:39:41 +0000 (GMT) Received: from wren.home (wren.home [192.168.1.7]) by nowt.org (Postfix) with ESMTP id 80657AC92 for ; Thu, 4 Nov 2004 19:39:40 +0000 (GMT) From: Paul Brook Organization: CodeSourcery To: binutils@sources.redhat.com Subject: [patch] Default versions for imported symbols Date: Thu, 04 Nov 2004 19:39:00 -0000 User-Agent: KMail/1.7 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200411041939.39143.paul@codesourcery.com> X-SW-Source: 2004-11/txt/msg00092.txt.bz2 The new Arm Base Platform ABI says[1] that unversioned symbols imported from a shared object should be given a symbol version based on the soname of the dso they are imported from. This is to allow target specific post-linkers to perform static binding. The patch below implements this. Build --enable-targets=all, and tested on i686-linux. Also manual tests with cross to arm-none-symbianelf. Ok? This patch requires my previous patch for non-consecutive version numbers. Paul [1] The ABI says this behaviour is optional, however it is a requirement for the arm-symbianelf target. 2004-11-04 Paul Brook bfd/ * elf-bfd.h (_bfd_elf_slurp_version_tables): Update prototype. * elf.c (_bfd_elf_print_private_bfd_data): Pass extra argument. (_bfd_elf_slurp_version_tables): Add extra argument. Create extra default version definition for unversioned symbols. * elfcode.h (elf_slurp_symbol_table): Pass extra argument. * elflink.c (elf_link_add_object_symbols): Pass extra argument to _bfd_elf_slurp_version_tables. Set default version for unversioned imported symbols. include/ * bfdlink.h (bfd_link_info): Add default_imported_symver. ld/ * ld.texinfo: Document --default-imported-symver. * ldmain.c (main): Set link_info.default_imported_symver. * lexsup.c (option_values): Add OPTION_DEFAULT_IMPORTED_SYMVER. (ld_options): Add --default-imported-symver. (parse_args): Handle OPTION_DEFAULT_IMPORTED_SYMVER. Index: bfd/elf-bfd.h =================================================================== RCS file: /cvs/src/src/bfd/elf-bfd.h,v retrieving revision 1.162 diff -c -p -r1.162 elf-bfd.h *** bfd/elf-bfd.h 14 Oct 2004 23:38:08 -0000 1.162 --- bfd/elf-bfd.h 4 Nov 2004 18:49:33 -0000 *************** extern bfd_boolean _bfd_elf_link_hash_ta *** 1419,1425 **** struct bfd_hash_entry *(*) (struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); extern bfd_boolean _bfd_elf_slurp_version_tables ! (bfd *); extern bfd_boolean _bfd_elf_merge_sections (bfd *, struct bfd_link_info *); extern bfd_boolean bfd_elf_is_group_section --- 1419,1425 ---- struct bfd_hash_entry *(*) (struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); extern bfd_boolean _bfd_elf_slurp_version_tables ! (bfd *, bfd_boolean); extern bfd_boolean _bfd_elf_merge_sections (bfd *, struct bfd_link_info *); extern bfd_boolean bfd_elf_is_group_section Index: bfd/elf.c =================================================================== RCS file: /cvs/src/src/bfd/elf.c,v retrieving revision 1.252 diff -c -p -r1.252 elf.c *** bfd/elf.c 4 Nov 2004 00:44:23 -0000 1.252 --- bfd/elf.c 4 Nov 2004 18:49:35 -0000 *************** _bfd_elf_print_private_bfd_data (bfd *ab *** 1192,1198 **** if ((elf_dynverdef (abfd) != 0 && elf_tdata (abfd)->verdef == NULL) || (elf_dynverref (abfd) != 0 && elf_tdata (abfd)->verref == NULL)) { ! if (! _bfd_elf_slurp_version_tables (abfd)) return FALSE; } --- 1192,1198 ---- if ((elf_dynverdef (abfd) != 0 && elf_tdata (abfd)->verdef == NULL) || (elf_dynverref (abfd) != 0 && elf_tdata (abfd)->verref == NULL)) { ! if (! _bfd_elf_slurp_version_tables (abfd, FALSE)) return FALSE; } *************** _bfd_elf_canonicalize_dynamic_reloc (bfd *** 6027,6036 **** /* Read in the version information. */ bfd_boolean ! _bfd_elf_slurp_version_tables (bfd *abfd) { bfd_byte *contents = NULL; bfd_size_type amt; if (elf_dynverdef (abfd) != 0) { --- 6027,6120 ---- /* Read in the version information. */ bfd_boolean ! _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver) { bfd_byte *contents = NULL; bfd_size_type amt; + unsigned int freeidx = 0; + + if (elf_dynverref (abfd) != 0) + { + Elf_Internal_Shdr *hdr; + Elf_External_Verneed *everneed; + Elf_Internal_Verneed *iverneed; + unsigned int i; + + hdr = &elf_tdata (abfd)->dynverref_hdr; + + amt = (bfd_size_type) hdr->sh_info * sizeof (Elf_Internal_Verneed); + elf_tdata (abfd)->verref = bfd_zalloc (abfd, amt); + if (elf_tdata (abfd)->verref == NULL) + goto error_return; + + elf_tdata (abfd)->cverrefs = hdr->sh_info; + + contents = bfd_malloc (hdr->sh_size); + if (contents == NULL) + goto error_return; + if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0 + || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size) + goto error_return; + + everneed = (Elf_External_Verneed *) contents; + iverneed = elf_tdata (abfd)->verref; + for (i = 0; i < hdr->sh_info; i++, iverneed++) + { + Elf_External_Vernaux *evernaux; + Elf_Internal_Vernaux *ivernaux; + unsigned int j; + + _bfd_elf_swap_verneed_in (abfd, everneed, iverneed); + + iverneed->vn_bfd = abfd; + + iverneed->vn_filename = + bfd_elf_string_from_elf_section (abfd, hdr->sh_link, + iverneed->vn_file); + if (iverneed->vn_filename == NULL) + goto error_return; + + amt = iverneed->vn_cnt; + amt *= sizeof (Elf_Internal_Vernaux); + iverneed->vn_auxptr = bfd_alloc (abfd, amt); + + evernaux = ((Elf_External_Vernaux *) + ((bfd_byte *) everneed + iverneed->vn_aux)); + ivernaux = iverneed->vn_auxptr; + for (j = 0; j < iverneed->vn_cnt; j++, ivernaux++) + { + _bfd_elf_swap_vernaux_in (abfd, evernaux, ivernaux); + + ivernaux->vna_nodename = + bfd_elf_string_from_elf_section (abfd, hdr->sh_link, + ivernaux->vna_name); + if (ivernaux->vna_nodename == NULL) + goto error_return; + + if (j + 1 < iverneed->vn_cnt) + ivernaux->vna_nextptr = ivernaux + 1; + else + ivernaux->vna_nextptr = NULL; + + evernaux = ((Elf_External_Vernaux *) + ((bfd_byte *) evernaux + ivernaux->vna_next)); + + if (ivernaux->vna_other > freeidx) + freeidx = ivernaux->vna_other; + } + + if (i + 1 < hdr->sh_info) + iverneed->vn_nextref = iverneed + 1; + else + iverneed->vn_nextref = NULL; + + everneed = ((Elf_External_Verneed *) + ((bfd_byte *) everneed + iverneed->vn_next)); + } + + free (contents); + contents = NULL; + } if (elf_dynverdef (abfd) != 0) { *************** _bfd_elf_slurp_version_tables (bfd *abfd *** 6067,6072 **** --- 6151,6163 ---- ((bfd_byte *) everdef + iverdefmem.vd_next)); } + if (default_imported_symver) + { + if (freeidx > maxidx) + maxidx = ++freeidx; + else + freeidx = ++maxidx; + } amt = (bfd_size_type) maxidx * sizeof (Elf_Internal_Verdef); elf_tdata (abfd)->verdef = bfd_zalloc (abfd, amt); if (elf_tdata (abfd)->verdef == NULL) *************** _bfd_elf_slurp_version_tables (bfd *abfd *** 6130,6214 **** free (contents); contents = NULL; } ! ! if (elf_dynverref (abfd) != 0) { ! Elf_Internal_Shdr *hdr; ! Elf_External_Verneed *everneed; ! Elf_Internal_Verneed *iverneed; ! unsigned int i; ! ! hdr = &elf_tdata (abfd)->dynverref_hdr; ! ! amt = (bfd_size_type) hdr->sh_info * sizeof (Elf_Internal_Verneed); ! elf_tdata (abfd)->verref = bfd_zalloc (abfd, amt); ! if (elf_tdata (abfd)->verref == NULL) ! goto error_return; ! ! elf_tdata (abfd)->cverrefs = hdr->sh_info; ! contents = bfd_malloc (hdr->sh_size); ! if (contents == NULL) ! goto error_return; ! if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0 ! || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size) goto error_return; ! everneed = (Elf_External_Verneed *) contents; ! iverneed = elf_tdata (abfd)->verref; ! for (i = 0; i < hdr->sh_info; i++, iverneed++) ! { ! Elf_External_Vernaux *evernaux; ! Elf_Internal_Vernaux *ivernaux; ! unsigned int j; ! ! _bfd_elf_swap_verneed_in (abfd, everneed, iverneed); ! ! iverneed->vn_bfd = abfd; ! ! iverneed->vn_filename = ! bfd_elf_string_from_elf_section (abfd, hdr->sh_link, ! iverneed->vn_file); ! if (iverneed->vn_filename == NULL) ! goto error_return; ! ! amt = iverneed->vn_cnt; ! amt *= sizeof (Elf_Internal_Vernaux); ! iverneed->vn_auxptr = bfd_alloc (abfd, amt); ! ! evernaux = ((Elf_External_Vernaux *) ! ((bfd_byte *) everneed + iverneed->vn_aux)); ! ivernaux = iverneed->vn_auxptr; ! for (j = 0; j < iverneed->vn_cnt; j++, ivernaux++) ! { ! _bfd_elf_swap_vernaux_in (abfd, evernaux, ivernaux); ! ! ivernaux->vna_nodename = ! bfd_elf_string_from_elf_section (abfd, hdr->sh_link, ! ivernaux->vna_name); ! if (ivernaux->vna_nodename == NULL) ! goto error_return; ! if (j + 1 < iverneed->vn_cnt) ! ivernaux->vna_nextptr = ivernaux + 1; ! else ! ivernaux->vna_nextptr = NULL; ! evernaux = ((Elf_External_Vernaux *) ! ((bfd_byte *) evernaux + ivernaux->vna_next)); ! } ! if (i + 1 < hdr->sh_info) ! iverneed->vn_nextref = iverneed + 1; ! else ! iverneed->vn_nextref = NULL; ! everneed = ((Elf_External_Verneed *) ! ((bfd_byte *) everneed + iverneed->vn_next)); ! } ! free (contents); ! contents = NULL; } return TRUE; --- 6221,6266 ---- free (contents); contents = NULL; } ! else if (default_imported_symver) { ! if (freeidx < 3) ! freeidx = 3; ! else ! freeidx++; ! amt = (bfd_size_type) freeidx * sizeof (Elf_Internal_Verdef); ! elf_tdata (abfd)->verdef = bfd_zalloc (abfd, amt); ! if (elf_tdata (abfd)->verdef == NULL) goto error_return; ! elf_tdata (abfd)->cverdefs = freeidx; ! } ! /* Create a default version based on the soname. */ ! if (default_imported_symver) ! { ! Elf_Internal_Verdef *iverdef; ! Elf_Internal_Verdaux *iverdaux; ! iverdef = &elf_tdata (abfd)->verdef[freeidx - 1];; ! iverdef->vd_version = VER_DEF_CURRENT; ! iverdef->vd_flags = 0; ! iverdef->vd_ndx = freeidx; ! iverdef->vd_cnt = 1; ! iverdef->vd_bfd = abfd; ! iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd); ! if (iverdef->vd_nodename == NULL) ! goto error_return; ! iverdef->vd_nextdef = NULL; ! amt = (bfd_size_type) sizeof (Elf_Internal_Verdaux); ! iverdef->vd_auxptr = bfd_alloc (abfd, amt); ! ! iverdaux = iverdef->vd_auxptr; ! iverdaux->vda_nodename = iverdef->vd_nodename; ! iverdaux->vda_nextptr = NULL; } return TRUE; Index: bfd/elfcode.h =================================================================== RCS file: /cvs/src/src/bfd/elfcode.h,v retrieving revision 1.57 diff -c -p -r1.57 elfcode.h *** bfd/elfcode.h 27 Jul 2004 14:20:47 -0000 1.57 --- bfd/elfcode.h 4 Nov 2004 18:49:36 -0000 *************** elf_slurp_symbol_table (bfd *abfd, asymb *** 1026,1032 **** || (elf_tdata (abfd)->dynverref_section != 0 && elf_tdata (abfd)->verref == NULL)) { ! if (! _bfd_elf_slurp_version_tables (abfd)) return -1; } } --- 1026,1032 ---- || (elf_tdata (abfd)->dynverref_section != 0 && elf_tdata (abfd)->verref == NULL)) { ! if (!_bfd_elf_slurp_version_tables (abfd, FALSE)) return -1; } } Index: bfd/elflink.c =================================================================== RCS file: /cvs/src/src/bfd/elflink.c,v retrieving revision 1.116 diff -c -p -r1.116 elflink.c *** bfd/elflink.c 2 Nov 2004 05:44:34 -0000 1.116 --- bfd/elflink.c 4 Nov 2004 18:49:39 -0000 *************** elf_link_add_object_symbols (bfd *abfd, *** 3347,3353 **** if (dynamic) { /* Read in any version definitions. */ ! if (! _bfd_elf_slurp_version_tables (abfd)) goto error_free_sym; /* Read in the symbol versions, but don't bother to convert them --- 3347,3354 ---- if (dynamic) { /* Read in any version definitions. */ ! if (!_bfd_elf_slurp_version_tables (abfd, ! info->default_imported_symver)) goto error_free_sym; /* Read in the symbol versions, but don't bother to convert them *************** elf_link_add_object_symbols (bfd *abfd, *** 3499,3600 **** unsigned int vernum = 0; bfd_boolean skip; ! if (ever != NULL) { ! _bfd_elf_swap_versym_in (abfd, ever, &iver); ! vernum = iver.vs_vers & VERSYM_VERSION; ! /* If this is a hidden symbol, or if it is not version ! 1, we append the version name to the symbol name. ! However, we do not modify a non-hidden absolute ! symbol, because it might be the version symbol ! itself. FIXME: What if it isn't? */ ! if ((iver.vs_vers & VERSYM_HIDDEN) != 0 ! || (vernum > 1 && ! bfd_is_abs_section (sec))) { ! const char *verstr; ! size_t namelen, verlen, newlen; ! char *newname, *p; ! if (isym->st_shndx != SHN_UNDEF) { ! if (vernum > elf_tdata (abfd)->cverdefs) ! verstr = NULL; ! else if (vernum > 1) ! verstr = ! elf_tdata (abfd)->verdef[vernum - 1].vd_nodename; ! else ! verstr = ""; ! ! if (verstr == NULL) ! { ! (*_bfd_error_handler) ! (_("%B: %s: invalid version %u (max %d)"), ! abfd, name, vernum, ! elf_tdata (abfd)->cverdefs); ! bfd_set_error (bfd_error_bad_value); ! goto error_free_vers; ! } } ! else { ! /* We cannot simply test for the number of ! entries in the VERNEED section since the ! numbers for the needed versions do not start ! at 0. */ ! Elf_Internal_Verneed *t; ! ! verstr = NULL; ! for (t = elf_tdata (abfd)->verref; ! t != NULL; ! t = t->vn_nextref) ! { ! Elf_Internal_Vernaux *a; ! for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) { ! if (a->vna_other == vernum) ! { ! verstr = a->vna_nodename; ! break; ! } } - if (a != NULL) - break; - } - if (verstr == NULL) - { - (*_bfd_error_handler) - (_("%B: %s: invalid needed version %d"), - abfd, name, vernum); - bfd_set_error (bfd_error_bad_value); - goto error_free_vers; } } ! namelen = strlen (name); ! verlen = strlen (verstr); ! newlen = namelen + verlen + 2; ! if ((iver.vs_vers & VERSYM_HIDDEN) == 0 ! && isym->st_shndx != SHN_UNDEF) ! ++newlen; ! newname = bfd_alloc (abfd, newlen); ! if (newname == NULL) ! goto error_free_vers; ! memcpy (newname, name, namelen); ! p = newname + namelen; ! *p++ = ELF_VER_CHR; ! /* If this is a defined non-hidden version symbol, ! we add another @ to the name. This indicates the ! default version of the symbol. */ ! if ((iver.vs_vers & VERSYM_HIDDEN) == 0 ! && isym->st_shndx != SHN_UNDEF) ! *p++ = ELF_VER_CHR; ! memcpy (p, verstr, verlen + 1); ! name = newname; ! } } if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec, &value, --- 3500,3608 ---- unsigned int vernum = 0; bfd_boolean skip; ! if (ever == NULL) { ! if (info->default_imported_symver) ! /* Use the default symbol version created earlier. */ ! iver.vs_vers = elf_tdata (abfd)->cverdefs; ! else ! iver.vs_vers = 0; ! } ! else ! _bfd_elf_swap_versym_in (abfd, ever, &iver); ! vernum = iver.vs_vers & VERSYM_VERSION; ! ! /* If this is a hidden symbol, or if it is not version ! 1, we append the version name to the symbol name. ! However, we do not modify a non-hidden absolute ! symbol, because it might be the version symbol ! itself. FIXME: What if it isn't? */ ! if ((iver.vs_vers & VERSYM_HIDDEN) != 0 ! || (vernum > 1 && ! bfd_is_abs_section (sec))) ! { ! const char *verstr; ! size_t namelen, verlen, newlen; ! char *newname, *p; ! ! if (isym->st_shndx != SHN_UNDEF) { ! if (vernum > elf_tdata (abfd)->cverdefs) ! verstr = NULL; ! else if (vernum > 1) ! verstr = ! elf_tdata (abfd)->verdef[vernum - 1].vd_nodename; ! else ! verstr = ""; ! if (verstr == NULL) { ! (*_bfd_error_handler) ! (_("%B: %s: invalid version %u (max %d)"), ! abfd, name, vernum, ! elf_tdata (abfd)->cverdefs); ! bfd_set_error (bfd_error_bad_value); ! goto error_free_vers; } ! } ! else ! { ! /* We cannot simply test for the number of ! entries in the VERNEED section since the ! numbers for the needed versions do not start ! at 0. */ ! Elf_Internal_Verneed *t; ! ! verstr = NULL; ! for (t = elf_tdata (abfd)->verref; ! t != NULL; ! t = t->vn_nextref) { ! Elf_Internal_Vernaux *a; ! for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) ! { ! if (a->vna_other == vernum) { ! verstr = a->vna_nodename; ! break; } } + if (a != NULL) + break; } + if (verstr == NULL) + { + (*_bfd_error_handler) + (_("%B: %s: invalid needed version %d"), + abfd, name, vernum); + bfd_set_error (bfd_error_bad_value); + goto error_free_vers; + } + } ! namelen = strlen (name); ! verlen = strlen (verstr); ! newlen = namelen + verlen + 2; ! if ((iver.vs_vers & VERSYM_HIDDEN) == 0 ! && isym->st_shndx != SHN_UNDEF) ! ++newlen; ! newname = bfd_alloc (abfd, newlen); ! if (newname == NULL) ! goto error_free_vers; ! memcpy (newname, name, namelen); ! p = newname + namelen; ! *p++ = ELF_VER_CHR; ! /* If this is a defined non-hidden version symbol, ! we add another @ to the name. This indicates the ! default version of the symbol. */ ! if ((iver.vs_vers & VERSYM_HIDDEN) == 0 ! && isym->st_shndx != SHN_UNDEF) ! *p++ = ELF_VER_CHR; ! memcpy (p, verstr, verlen + 1); ! name = newname; } if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec, &value, Index: include/bfdlink.h =================================================================== RCS file: /cvs/src/src/include/bfdlink.h,v retrieving revision 1.49 diff -c -p -r1.49 bfdlink.h *** include/bfdlink.h 26 Oct 2004 13:46:02 -0000 1.49 --- include/bfdlink.h 4 Nov 2004 18:49:41 -0000 *************** struct bfd_link_info *** 262,270 **** /* 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; --- 262,275 ---- /* TRUE if ok to have version with no definition. */ unsigned int allow_undefined_version: 1; ! /* TRUE if a default symbol version should be created and used for ! exported symbols. */ unsigned int create_default_symver: 1; + /* TRUE if a default symbol version should be created and used for + imported symbols. */ + unsigned int default_imported_symver: 1; + /* TRUE if symbols should be retained in memory, FALSE if they should be freed and reread. */ unsigned int keep_memory: 1; Index: ld/ld.texinfo =================================================================== RCS file: /cvs/src/src/ld/ld.texinfo,v retrieving revision 1.129 diff -c -p -r1.129 ld.texinfo *** ld/ld.texinfo 26 Oct 2004 18:41:51 -0000 1.129 --- ld/ld.texinfo 4 Nov 2004 18:49:48 -0000 *************** will be issued instead. *** 1237,1243 **** @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 --- 1237,1248 ---- @kindex --default-symver @item --default-symver Create and use a default symbol version (the soname) for unversioned ! exported symbols. ! ! @kindex --default-imported-symver ! @item --default-imported-symver ! Create and use a default symbol version (the soname) for unversioned ! imported symbols. @kindex --no-warn-mismatch @item --no-warn-mismatch Index: ld/ldmain.c =================================================================== RCS file: /cvs/src/src/ld/ldmain.c,v retrieving revision 1.88 diff -c -p -r1.88 ldmain.c *** ld/ldmain.c 26 Oct 2004 13:46:04 -0000 1.88 --- ld/ldmain.c 4 Nov 2004 18:49:48 -0000 *************** main (int argc, char **argv) *** 307,312 **** --- 307,313 ---- link_info.allow_multiple_definition = FALSE; link_info.allow_undefined_version = TRUE; link_info.create_default_symver = FALSE; + link_info.default_imported_symver = FALSE; link_info.keep_memory = TRUE; link_info.notice_all = FALSE; link_info.nocopyreloc = FALSE; Index: ld/lexsup.c =================================================================== RCS file: /cvs/src/src/ld/lexsup.c,v retrieving revision 1.80 diff -c -p -r1.80 lexsup.c *** ld/lexsup.c 26 Oct 2004 18:41:51 -0000 1.80 --- ld/lexsup.c 4 Nov 2004 18:49:48 -0000 *************** enum option_values *** 136,141 **** --- 136,142 ---- OPTION_ALLOW_MULTIPLE_DEFINITION, OPTION_NO_UNDEFINED_VERSION, OPTION_DEFAULT_SYMVER, + OPTION_DEFAULT_IMPORTED_SYMVER, OPTION_DISCARD_NONE, OPTION_SPARE_DYNAMIC_TAGS, OPTION_NO_DEFINE_COMMON, *************** static const struct ld_option ld_options *** 397,402 **** --- 398,407 ---- '\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 }, + { {"default-imported-symver", no_argument, NULL, + OPTION_DEFAULT_IMPORTED_SYMVER}, + '\0', NULL, N_("Create default symbol version for imported symbols"), + 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}, *************** parse_args (unsigned argc, char **argv) *** 909,914 **** --- 914,922 ---- case OPTION_DEFAULT_SYMVER: link_info.create_default_symver = TRUE; break; + case OPTION_DEFAULT_IMPORTED_SYMVER: + link_info.default_imported_symver = TRUE; + break; case OPTION_NO_WARN_MISMATCH: command_line.warn_mismatch = FALSE; break;