From d4ae5fb0b5d1ae4270b3343509e8bd2d529aa291 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 14 Mar 2014 11:25:59 +1030 Subject: [PATCH] Remove search path from -l:namespec DT_NEEDED For libraries without a soname, -l:libfoo.so set DT_NEEDED to the search dir plus filename, while gold and -lfoo just use the filename. This patch fixes the inconsistency. * ldlang.h (full_name_provided): New input flag. * ldlang.c (new_afile): Don't use lang_input_file_is_search_file_enum for -l:namespec. Instead use lang_input_file_is_l_enum with 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): Handle full_name_provided libraries. Tidy EXTRA_SHLIB_EXTENSION support. Set DT_NEEDED for -l:namespec as namespec. * emultempl/aix.em (ppc_after_open_output): Handle full_name_provided. * emultempl/linux.em (gld${EMULATION_NAME}_open_dynamic_archive): Don't handle full_name_provided libraries. * emultempl/pe.em (gld${EMULATION_NAME}_open_dynamic_archive): Ditto. * emultempl/pep.em (gld${EMULATION_NAME}_open_dynamic_archive): Ditto. * emultempl/vms.em (gld${EMULATION_NAME}_open_dynamic_archive): Ditto. --- ld/ChangeLog | 19 +++++++++++++++++ ld/emultempl/aix.em | 8 ++++++- ld/emultempl/elf32.em | 49 ++++++++++++++++++++++++------------------- 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 +++ 10 files changed, 68 insertions(+), 36 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index cc5f8286cb2..9c728aee746 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,22 @@ +2014-03-14 Romain Geissler + Alan Modra + + * ldlang.h (full_name_provided): New input flag. + * ldlang.c (new_afile): Don't use lang_input_file_is_search_file_enum + for -l:namespec. Instead use lang_input_file_is_l_enum with + 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): + Handle full_name_provided libraries. Tidy EXTRA_SHLIB_EXTENSION + support. Set DT_NEEDED for -l:namespec as namespec. + * emultempl/aix.em (ppc_after_open_output): Handle full_name_provided. + * emultempl/linux.em (gld${EMULATION_NAME}_open_dynamic_archive): + Don't handle full_name_provided libraries. + * emultempl/pe.em (gld${EMULATION_NAME}_open_dynamic_archive): Ditto. + * emultempl/pep.em (gld${EMULATION_NAME}_open_dynamic_archive): Ditto. + * emultempl/vms.em (gld${EMULATION_NAME}_open_dynamic_archive): Ditto. + 2014-03-12 Alan Modra * Makefile.in: Regenerate. diff --git a/ld/emultempl/aix.em b/ld/emultempl/aix.em index 4a06c71c332..caa74a990e2 100644 --- a/ld/emultempl/aix.em +++ b/ld/emultempl/aix.em @@ -1509,7 +1509,13 @@ gld${EMULATION_NAME}_open_dynamic_archive (const char *arch, if (!entry->flags.maybe_archive) return FALSE; - path = concat (search->name, "/lib", entry->filename, arch, ".a", NULL); + if (entry->flags.full_name_provided) + path = concat (search->name, "/", entry->filename, + (const char *) NULL); + else + path = concat (search->name, "/lib", entry->filename, arch, ".a", + (const char *) NULL); + if (!ldfile_try_open_bfd (path, entry)) { free (path); diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index 789e12c2298..7ea5adcc42b 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -1656,42 +1656,46 @@ gld${EMULATION_NAME}_open_dynamic_archive { const char *filename; char *string; + size_t len; + bfd_boolean opened = FALSE; if (! entry->flags.maybe_archive) return FALSE; filename = entry->filename; + len = strlen (search->name) + strlen (filename); + if (entry->flags.full_name_provided) + { + len += sizeof "/"; + string = (char *) xmalloc (len); + sprintf (string, "%s/%s", search->name, filename); + } + else + { + size_t xlen = 0; - /* 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 = (char *) xmalloc (strlen (search->name) - + strlen (filename) - + strlen (arch) + len += strlen (arch) + sizeof "/lib.so"; #ifdef EXTRA_SHLIB_EXTENSION - + strlen (EXTRA_SHLIB_EXTENSION) + xlen = (strlen (EXTRA_SHLIB_EXTENSION) > 3 + ? strlen (EXTRA_SHLIB_EXTENSION) - 3 + : 0); #endif - + sizeof "/lib.so"); - - sprintf (string, "%s/lib%s%s.so", search->name, filename, arch); - + string = (char *) xmalloc (len + xlen); + sprintf (string, "%s/lib%s%s.so", search->name, filename, arch); #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. */ + opened = ldfile_try_open_bfd (string, entry); + if (!opened) + strcpy (string + len - 4, EXTRA_SHLIB_EXTENSION); #endif + } - if (! ldfile_try_open_bfd (string, entry)) + if (!opened && !ldfile_try_open_bfd (string, entry)) { free (string); return FALSE; } -#ifdef EXTRA_SHLIB_EXTENSION - } -#endif entry->filename = string; @@ -1716,7 +1720,8 @@ gld${EMULATION_NAME}_open_dynamic_archive /* Rather than duplicating the logic above. Just use the filename we recorded earlier. */ - filename = lbasename (entry->filename); + if (!entry->flags.full_name_provided) + filename = lbasename (entry->filename); bfd_elf_set_dt_needed_name (entry->the_bfd, filename); } diff --git a/ld/emultempl/linux.em b/ld/emultempl/linux.em index e7fa35d2c63..b30e872c3e6 100644 --- a/ld/emultempl/linux.em +++ b/ld/emultempl/linux.em @@ -61,7 +61,7 @@ gld${EMULATION_NAME}_open_dynamic_archive { char *string; - if (! entry->flags.maybe_archive) + if (! entry->flags.maybe_archive || entry->flags.full_name_provided) return FALSE; string = (char *) xmalloc (strlen (search->name) diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index 6de71bd18bf..67df2bc4dba 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -2108,7 +2108,7 @@ gld_${EMULATION_NAME}_open_dynamic_archive unsigned int i; - if (! entry->flags.maybe_archive) + if (! entry->flags.maybe_archive || entry->flags.full_name_provided) return FALSE; filename = entry->filename; diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em index 9309c11fd64..dca36cc341a 100644 --- a/ld/emultempl/pep.em +++ b/ld/emultempl/pep.em @@ -1879,7 +1879,7 @@ gld_${EMULATION_NAME}_open_dynamic_archive unsigned int i; - if (! entry->flags.maybe_archive) + if (! entry->flags.maybe_archive || entry->flags.full_name_provided) return FALSE; filename = entry->filename; diff --git a/ld/emultempl/vms.em b/ld/emultempl/vms.em index 08650f5e1e6..b1f61d5b3b0 100644 --- a/ld/emultempl/vms.em +++ b/ld/emultempl/vms.em @@ -57,7 +57,7 @@ gld${EMULATION_NAME}_open_dynamic_archive (const char *arch ATTRIBUTE_UNUSED, { char *string; - if (! entry->flags.maybe_archive) + if (! entry->flags.maybe_archive || entry->flags.full_name_provided) return FALSE; string = (char *) xmalloc (strlen (search->name) diff --git a/ld/ldfile.c b/ld/ldfile.c index 61660ab889d..782ed7f03a1 100644 --- a/ld/ldfile.c +++ b/ld/ldfile.c @@ -367,7 +367,7 @@ ldfile_open_file_search (const char *arch, return TRUE; } - if (entry->flags.maybe_archive) + if (entry->flags.maybe_archive && !entry->flags.full_name_provided) string = concat (search->name, slash, lib, entry->filename, arch, suffix, (const char *) NULL); else diff --git a/ld/ldlang.c b/ld/ldlang.c index 57e2ee82af7..37ef2652e3a 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1063,13 +1063,6 @@ new_afile (const char *name, p->flags.whole_archive = input_flags.whole_archive; p->flags.sysrooted = input_flags.sysrooted; - if (file_type == lang_input_file_is_l_enum - && name[0] == ':' && name[1] != '\0') - { - file_type = lang_input_file_is_search_file_enum; - name = 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 = name; break; case lang_input_file_is_l_enum: - p->filename = name; + if (name[0] == ':' && name[1] != '\0') + { + p->filename = name + 1; + p->flags.full_name_provided = TRUE; + } + else + p->filename = name; p->local_sym_name = concat ("-l", name, (const char *) NULL); p->flags.maybe_archive = TRUE; p->flags.real = TRUE; diff --git a/ld/ldlang.h b/ld/ldlang.h index 8f525d189f6..aacd5dcaed5 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; + /* 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; -- 2.30.2