aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog9
-rw-r--r--ld/emultempl/elf32.em149
2 files changed, 105 insertions, 53 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 47c07b9..f4baea8 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,14 @@
2017-03-11 Alan Modra <amodra@gmail.com>
+ * emultempl/elf32.em (gld${EMULATION_NAME}_add_sysroot): Rewrite.
+ Only prefix absolute paths with sysroot. Handle DOS paths.
+ (gld${EMULATION_NAME}_check_ld_elf_hints): Constify variable.
+ (gld${EMULATION_NAME}_check_ld_so_conf): Likewise.
+ (gld${EMULATION_NAME}_after_open): Short-circuit NULL path
+ searches. Rename variable. Simplify get_runpath search.
+
+2017-03-11 Alan Modra <amodra@gmail.com>
+
* testsuite/ld-elf/shared.exp: Use -Wl,-export-dynamic rather
than -rdynamic.
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 84adaef..16220d5 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -691,41 +691,85 @@ EOF
if [ "x${USE_LIBPATH}" = xyes ] ; then
fragment <<EOF
-/* Add the sysroot to every entry in a path separated by
- config.rpath_separator. */
+/* Prefix the sysroot to absolute paths in PATH, a string containing
+ paths separated by config.rpath_separator. If running on a DOS
+ file system, paths containing a drive spec won't have the sysroot
+ prefix added, unless the sysroot also specifies the same drive. */
-static char *
+static const char *
gld${EMULATION_NAME}_add_sysroot (const char *path)
{
- int len, colons, i;
- char *ret, *p;
-
- len = strlen (path);
- colons = 0;
- i = 0;
- while (path[i])
- if (path[i++] == config.rpath_separator)
- colons++;
-
- if (path[i])
- colons++;
-
- len = len + (colons + 1) * strlen (ld_sysroot);
- ret = xmalloc (len + 1);
- strcpy (ret, ld_sysroot);
- p = ret + strlen (ret);
- i = 0;
- while (path[i])
- if (path[i] == config.rpath_separator)
- {
- *p++ = path[i++];
- strcpy (p, ld_sysroot);
- p = p + strlen (p);
- }
- else
- *p++ = path[i++];
+ size_t len, extra;
+ const char *p;
+ char *ret, *q;
+ int dos_drive_sysroot = HAS_DRIVE_SPEC (ld_sysroot);
+
+ len = strlen (ld_sysroot);
+ for (extra = 0, p = path; ; )
+ {
+ int dos_drive = HAS_DRIVE_SPEC (p);
+
+ if (dos_drive)
+ p += 2;
+ if (IS_DIR_SEPARATOR (*p)
+ && (!dos_drive
+ || (dos_drive_sysroot
+ && ld_sysroot[0] == p[-2])))
+ {
+ if (dos_drive && dos_drive_sysroot)
+ extra += len - 2;
+ else
+ extra += len;
+ }
+ p = strchr (p, config.rpath_separator);
+ if (!p)
+ break;
+ ++p;
+ }
+
+ ret = xmalloc (strlen (path) + extra + 1);
+
+ for (q = ret, p = path; ; )
+ {
+ const char *end;
+ int dos_drive = HAS_DRIVE_SPEC (p);
+
+ if (dos_drive)
+ {
+ *q++ = *p++;
+ *q++ = *p++;
+ }
+ if (IS_DIR_SEPARATOR (*p)
+ && (!dos_drive
+ || (dos_drive_sysroot
+ && ld_sysroot[0] == p[-2])))
+ {
+ if (dos_drive && dos_drive_sysroot)
+ {
+ strcpy (q, ld_sysroot + 2);
+ q += len - 2;
+ }
+ else
+ {
+ strcpy (q, ld_sysroot);
+ q += len;
+ }
+ }
+ end = strchr (p, config.rpath_separator);
+ if (end)
+ {
+ size_t n = end - p + 1;
+ strncpy (q, p, n);
+ q += n;
+ p += n;
+ }
+ else
+ {
+ strcpy (q, p);
+ break;
+ }
+ }
- *p = 0;
return ret;
}
@@ -745,7 +789,7 @@ gld${EMULATION_NAME}_check_ld_elf_hints (const struct bfd_link_needed_list *l,
int force)
{
static bfd_boolean initialized;
- static char *ld_elf_hints;
+ static const char *ld_elf_hints;
struct dt_needed needed;
if (!initialized)
@@ -963,7 +1007,7 @@ gld${EMULATION_NAME}_check_ld_so_conf (const struct bfd_link_needed_list *l,
int force)
{
static bfd_boolean initialized;
- static char *ld_so_conf;
+ static const char *ld_so_conf;
struct dt_needed needed;
if (! initialized)
@@ -986,9 +1030,8 @@ gld${EMULATION_NAME}_check_ld_so_conf (const struct bfd_link_needed_list *l,
if (info.path)
{
- char *d = gld${EMULATION_NAME}_add_sysroot (info.path);
+ ld_so_conf = gld${EMULATION_NAME}_add_sysroot (info.path);
free (info.path);
- ld_so_conf = d;
}
initialized = TRUE;
}
@@ -1381,9 +1424,9 @@ gld${EMULATION_NAME}_after_open (void)
size_t len;
search_dirs_type *search;
EOF
-if [ "x${NATIVE}" = xyes ] ; then
+if [ "x${NATIVE}" = xyes ] || [ "x${USE_LIBPATH}" = xyes ] ; then
fragment <<EOF
- const char *lib_path;
+ const char *path;
EOF
fi
if [ "x${USE_LIBPATH}" = xyes ] ; then
@@ -1400,9 +1443,13 @@ fragment <<EOF
EOF
if [ "x${USE_LIBPATH}" = xyes ] ; then
fragment <<EOF
- if (gld${EMULATION_NAME}_search_needed (command_line.rpath,
- &n, force))
- break;
+ path = command_line.rpath;
+ if (path)
+ {
+ found = gld${EMULATION_NAME}_search_needed (path, &n, force);
+ if (found)
+ break;
+ }
EOF
fi
if [ "x${NATIVE}" = xyes ] ; then
@@ -1410,13 +1457,14 @@ fragment <<EOF
if (command_line.rpath_link == NULL
&& command_line.rpath == NULL)
{
- lib_path = (const char *) getenv ("LD_RUN_PATH");
- if (gld${EMULATION_NAME}_search_needed (lib_path, &n,
- force))
+ path = (const char *) getenv ("LD_RUN_PATH");
+ if (path
+ && gld${EMULATION_NAME}_search_needed (path, &n, force))
break;
}
- lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
- if (gld${EMULATION_NAME}_search_needed (lib_path, &n, force))
+ path = (const char *) getenv ("LD_LIBRARY_PATH");
+ if (path
+ && gld${EMULATION_NAME}_search_needed (path, &n, force))
break;
EOF
fi
@@ -1426,16 +1474,11 @@ fragment <<EOF
rp = bfd_elf_get_runpath_list (link_info.output_bfd, &link_info);
for (; !found && rp != NULL; rp = rp->next)
{
- const char *tmpname = rp->name;
-
- if (IS_ABSOLUTE_PATH (tmpname))
- tmpname = gld${EMULATION_NAME}_add_sysroot (tmpname);
+ path = gld${EMULATION_NAME}_add_sysroot (rp->name);
found = (rp->by == l->by
- && gld${EMULATION_NAME}_search_needed (tmpname,
- &n,
+ && gld${EMULATION_NAME}_search_needed (path, &n,
force));
- if (tmpname != rp->name)
- free ((char *) tmpname);
+ free ((char *) path);
}
if (found)
break;