From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24992 invoked by alias); 16 Feb 2014 21:03:18 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Received: (qmail 24982 invoked by uid 89); 16 Feb 2014 21:03:17 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.2 required=5.0 tests=BAYES_05,RCVD_IN_DNSWL_LOW,SPF_PASS,UNPARSEABLE_RELAY autolearn=ham version=3.3.2 X-HELO: mail1.bemta3.messagelabs.com Received: from mail1.bemta3.messagelabs.com (HELO mail1.bemta3.messagelabs.com) (195.245.230.165) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Sun, 16 Feb 2014 21:03:15 +0000 Received: from [85.158.137.99:31806] by server-5.bemta-3.messagelabs.com id D0/89-04712-E8721035; Sun, 16 Feb 2014 21:03:10 +0000 X-Env-Sender: romain.geissler@amadeus.com X-Msg-Ref: server-11.tower-217.messagelabs.com!1392584575!17843223!2 X-StarScan-Received: X-StarScan-Version: 6.9.16; banners=-,-,- X-VirusChecked: Checked Received: (qmail 5212 invoked from network); 16 Feb 2014 21:03:10 -0000 Received: from mucsmtp2.amadeus.net (HELO mucsmtp2.amadeus.net) (193.23.186.180) by server-11.tower-217.messagelabs.com with RC4-SHA encrypted SMTP; 16 Feb 2014 21:03:10 -0000 Received: from [172.26.214.107] ([172.26.214.107]) by mucsmtp2.amadeus.net (Lotus Domino Release 8.5.3FP2 HF23) with ESMTP id 2014021621030213-154004 ; Sun, 16 Feb 2014 21:03:02 +0000 From: Romain Geissler Subject: [PATCH] Fix DT_NEEDED when using -l:namespec Date: Sun, 16 Feb 2014 21:03:00 -0000 Message-Id: Cc: lenaic.huard@laposte.net To: binutils@sourceware.org Mime-Version: 1.0 (Mac OS X Mail 7.1 \(1827\)) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=windows-1252 X-SW-Source: 2014-02/txt/msg00097.txt.bz2 Hi, There is a behavior difference between ld (elf 64) and gold when specifying= a lib with -l:mylib.so that is not the current working directory. If y have a lib without DT_SONAME at path lib/liblib.so and if y try to lin= k with both linkers using this command: g++ -o test test.cpp -Ilib -Llib -l= :liblib.so - with ld.bfd: readelf -d test|grep "liblib\.so" 0x0000000000000001 (NEEDED) Shared library: [lib/liblib.so]=20= =20 - with ld.gold: readelf -d test|grep "liblib\.so"=20=20 0x0000000000000001 (NEEDED) Shared library: [liblib.so]=20=20 In the first case, the search path is prepended to the DT_NEEDED entry. I t= hink it=92s a bug from ld.bfd, when we use -l flag, we never want the searc= h path to be present when the lib has no SONAME. This patch solves this issue, tested on elf x86_64 SLES 11 SP1 without regr= ession. ld/ 2014-02-16 Romain Geissler * ldlang.h (full_name_provided): New input flag. * ldlang.c (new_afile): Set full_name_provided flag. * ldlfile.c (ldfile_open_file_search): Don't complete lib name if full_name_provided flag is set. * emultempl/elf32.em (gld${EMULATION_NAME}_open_dynamic_archive): Correctly set DT_NEEDED for dynamic libraries with loaded with -l:namespec. * emultempl/aix.em (ppc_after_open_output): Don't try to load lib specified with -l:namespec. * emultempl/linux.em (gld${EMULATION_NAME}_open_dynamic_archive): Likewise. * emultempl/pe.em (gld${EMULATION_NAME}_open_dynamic_archive): Likewise. * emultempl/pep.em (gld${EMULATION_NAME}_open_dynamic_archive): Likewise. * emultempl/vms.em (gld${EMULATION_NAME}_open_dynamic_archive): Likewise. --- ld/emultempl/aix.em | 2 +- ld/emultempl/elf32.em | 61 ++++++++++++++++++++++++++++++++---------------= ---- ld/emultempl/linux.em | 2 +- ld/emultempl/pe.em | 2 +- ld/emultempl/pep.em | 2 +- ld/emultempl/vms.em | 2 +- ld/ldfile.c | 2 +- ld/ldlang.c | 15 ++++++------- ld/ldlang.h | 3 +++ 9 files changed, 55 insertions(+), 36 deletions(-) diff --git a/ld/emultempl/aix.em b/ld/emultempl/aix.em index d080133..4919ae6 100644 --- a/ld/emultempl/aix.em +++ b/ld/emultempl/aix.em @@ -1506,7 +1506,7 @@ gld${EMULATION_NAME}_open_dynamic_archive (const char= *arch, { char *path; =20 - if (!entry->flags.maybe_archive) + if (!entry->flags.maybe_archive || entry->flags.full_name_provided) return FALSE; =20 path =3D concat (search->name, "/lib", entry->filename, arch, ".a", NULL= ); diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index fda0e68..89ad0d0 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -1664,36 +1664,52 @@ gld${EMULATION_NAME}_open_dynamic_archive =20 filename =3D entry->filename; =20 - /* This allocates a few bytes too many when EXTRA_SHLIB_EXTENSION - is defined, but it does not seem worth the headache to optimize - away those two bytes of space. */ - string =3D (char *) xmalloc (strlen (search->name) - + strlen (filename) - + strlen (arch) + if (entry->flags.full_name_provided) + { + string =3D (char *) xmalloc (strlen (search->name) + strlen (filenam= e)); + sprintf (string, "%s/%s", search->name, filename); + + if (! (ldfile_try_open_bfd (string, entry) + && bfd_check_format (entry->the_bfd, bfd_object) + && (entry->the_bfd->flags & DYNAMIC) !=3D 0)) + { + free (string); + return FALSE; + } + } + else + { + /* This allocates a few bytes too many when EXTRA_SHLIB_EXTENSION + is defined, but it does not seem worth the headache to optimize + away those two bytes of space. */ + string =3D (char *) xmalloc (strlen (search->name) + + strlen (filename) + + strlen (arch) #ifdef EXTRA_SHLIB_EXTENSION - + strlen (EXTRA_SHLIB_EXTENSION) + + strlen (EXTRA_SHLIB_EXTENSION) #endif - + sizeof "/lib.so"); + + sizeof "/lib.so"); =20 - sprintf (string, "%s/lib%s%s.so", search->name, filename, arch); + sprintf (string, "%s/lib%s%s.so", search->name, filename, arch); =20 #ifdef EXTRA_SHLIB_EXTENSION - /* Try the .so extension first. If that fails build a new filename - using EXTRA_SHLIB_EXTENSION. */ - if (! ldfile_try_open_bfd (string, entry)) - { - sprintf (string, "%s/lib%s%s%s", search->name, - filename, arch, EXTRA_SHLIB_EXTENSION); + /* Try the .so extension first. If that fails build a new filename + using EXTRA_SHLIB_EXTENSION. */ + if (! ldfile_try_open_bfd (string, entry)) + { + sprintf (string, "%s/lib%s%s%s", search->name, + filename, arch, EXTRA_SHLIB_EXTENSION); #endif =20 - if (! ldfile_try_open_bfd (string, entry)) - { - free (string); - return FALSE; - } + if (! ldfile_try_open_bfd (string, entry)) + { + free (string); + return FALSE; + } #ifdef EXTRA_SHLIB_EXTENSION - } + } #endif + } =20 entry->filename =3D string; =20 @@ -1718,7 +1734,8 @@ gld${EMULATION_NAME}_open_dynamic_archive /* Rather than duplicating the logic above. Just use the filename we recorded earlier. */ =20 - filename =3D lbasename (entry->filename); + if (!entry->flags.full_name_provided) + filename =3D lbasename (entry->filename); bfd_elf_set_dt_needed_name (entry->the_bfd, filename); } =20 diff --git a/ld/emultempl/linux.em b/ld/emultempl/linux.em index 5cf5bfa..d9571ab 100644 --- a/ld/emultempl/linux.em +++ b/ld/emultempl/linux.em @@ -62,7 +62,7 @@ gld${EMULATION_NAME}_open_dynamic_archive { char *string; =20 - if (! entry->flags.maybe_archive) + if (! entry->flags.maybe_archive || entry->flags.full_name_provided) return FALSE; =20 string =3D (char *) xmalloc (strlen (search->name) diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index 5d6da9e..a85c8a3 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -2108,7 +2108,7 @@ gld_${EMULATION_NAME}_open_dynamic_archive unsigned int i; =20 =20 - if (! entry->flags.maybe_archive) + if (! entry->flags.maybe_archive || entry->flags.full_name_provided) return FALSE; =20 filename =3D entry->filename; diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em index b738800..70469db 100644 --- a/ld/emultempl/pep.em +++ b/ld/emultempl/pep.em @@ -1879,7 +1879,7 @@ gld_${EMULATION_NAME}_open_dynamic_archive unsigned int i; =20 =20 - if (! entry->flags.maybe_archive) + if (! entry->flags.maybe_archive || entry->flags.full_name_provided) return FALSE; =20 filename =3D entry->filename; diff --git a/ld/emultempl/vms.em b/ld/emultempl/vms.em index 30c1a16..6682208 100644 --- a/ld/emultempl/vms.em +++ b/ld/emultempl/vms.em @@ -58,7 +58,7 @@ gld${EMULATION_NAME}_open_dynamic_archive (const char *ar= ch ATTRIBUTE_UNUSED, { char *string; =20 - if (! entry->flags.maybe_archive) + if (! entry->flags.maybe_archive || entry->flags.full_name_provided) return FALSE; =20 string =3D (char *) xmalloc (strlen (search->name) diff --git a/ld/ldfile.c b/ld/ldfile.c index 16baef8..0048183 100644 --- a/ld/ldfile.c +++ b/ld/ldfile.c @@ -369,7 +369,7 @@ ldfile_open_file_search (const char *arch, return TRUE; } =20 - if (entry->flags.maybe_archive) + if (entry->flags.maybe_archive && !entry->flags.full_name_provided) string =3D concat (search->name, slash, lib, entry->filename, arch, suffix, (const char *) NULL); else diff --git a/ld/ldlang.c b/ld/ldlang.c index 4768af7..e4a595c 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1063,13 +1063,6 @@ new_afile (const char *name, p->flags.whole_archive =3D input_flags.whole_archive; p->flags.sysrooted =3D input_flags.sysrooted; =20 - if (file_type =3D=3D lang_input_file_is_l_enum - && name[0] =3D=3D ':' && name[1] !=3D '\0') - { - file_type =3D lang_input_file_is_search_file_enum; - name =3D name + 1; - } - switch (file_type) { case lang_input_file_is_symbols_only_enum: @@ -1083,7 +1076,13 @@ new_afile (const char *name, p->local_sym_name =3D name; break; case lang_input_file_is_l_enum: - p->filename =3D name; + if (name[0] =3D=3D ':' && name[1] !=3D '\0') + { + p->filename =3D name + 1; + p->flags.full_name_provided =3D TRUE; + } + else + p->filename =3D name; p->local_sym_name =3D concat ("-l", name, (const char *) NULL); p->flags.maybe_archive =3D TRUE; p->flags.real =3D TRUE; diff --git a/ld/ldlang.h b/ld/ldlang.h index 7236c1c..b4624d8 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -235,6 +235,9 @@ struct lang_input_statement_flags /* 1 means this file was specified in a -l option. */ unsigned int maybe_archive : 1; =20 + /* 1 means this file was specified in a -l:namespec option. */ + unsigned int full_name_provided : 1; + /* 1 means search a set of directories for this file. */ unsigned int search_dirs : 1; =20 --=20