Rewrite add_sysroot

Relative paths shouldn't have the sysroot prefix added.  The patch
also makes some attempt at supporting DOS paths, and tidies code using
the new add_sysroot.

	* 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.
This commit is contained in:
Alan Modra 2017-03-11 22:57:29 +10:30
parent 4aef764338
commit 316a1245fe
2 changed files with 102 additions and 50 deletions

View File

@ -1,3 +1,12 @@
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

View File

@ -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;
size_t len, extra;
const char *p;
char *ret, *q;
int dos_drive_sysroot = HAS_DRIVE_SPEC (ld_sysroot);
len = strlen (path);
colons = 0;
i = 0;
while (path[i])
if (path[i++] == config.rpath_separator)
colons++;
len = strlen (ld_sysroot);
for (extra = 0, p = path; ; )
{
int dos_drive = HAS_DRIVE_SPEC (p);
if (path[i])
colons++;
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;
}
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++];
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;