summaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog19
-rw-r--r--ld/emultempl/aix.em8
-rw-r--r--ld/emultempl/elf32.em49
-rw-r--r--ld/emultempl/linux.em2
-rw-r--r--ld/emultempl/pe.em2
-rw-r--r--ld/emultempl/pep.em2
-rw-r--r--ld/emultempl/vms.em2
-rw-r--r--ld/ldfile.c2
-rw-r--r--ld/ldlang.c15
-rw-r--r--ld/ldlang.h3
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 <romain.geissler@amadeus.com>
+ Alan Modra <amodra@gmail.com>
+
+ * 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 <amodra@gmail.com>
* 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;