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> 2017-03-11 Alan Modra <amodra@gmail.com>
* testsuite/ld-elf/shared.exp: Use -Wl,-export-dynamic rather * testsuite/ld-elf/shared.exp: Use -Wl,-export-dynamic rather

View File

@ -691,41 +691,85 @@ EOF
if [ "x${USE_LIBPATH}" = xyes ] ; then if [ "x${USE_LIBPATH}" = xyes ] ; then
fragment <<EOF fragment <<EOF
/* Add the sysroot to every entry in a path separated by /* Prefix the sysroot to absolute paths in PATH, a string containing
config.rpath_separator. */ 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) gld${EMULATION_NAME}_add_sysroot (const char *path)
{ {
int len, colons, i; size_t len, extra;
char *ret, *p; const char *p;
char *ret, *q;
int dos_drive_sysroot = HAS_DRIVE_SPEC (ld_sysroot);
len = strlen (path); len = strlen (ld_sysroot);
colons = 0; for (extra = 0, p = path; ; )
i = 0; {
while (path[i]) int dos_drive = HAS_DRIVE_SPEC (p);
if (path[i++] == config.rpath_separator)
colons++;
if (path[i]) if (dos_drive)
colons++; 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 (strlen (path) + extra + 1);
ret = xmalloc (len + 1);
strcpy (ret, ld_sysroot); for (q = ret, p = path; ; )
p = ret + strlen (ret); {
i = 0; const char *end;
while (path[i]) int dos_drive = HAS_DRIVE_SPEC (p);
if (path[i] == config.rpath_separator)
{ if (dos_drive)
*p++ = path[i++]; {
strcpy (p, ld_sysroot); *q++ = *p++;
p = p + strlen (p); *q++ = *p++;
} }
else if (IS_DIR_SEPARATOR (*p)
*p++ = path[i++]; && (!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; return ret;
} }
@ -745,7 +789,7 @@ gld${EMULATION_NAME}_check_ld_elf_hints (const struct bfd_link_needed_list *l,
int force) int force)
{ {
static bfd_boolean initialized; static bfd_boolean initialized;
static char *ld_elf_hints; static const char *ld_elf_hints;
struct dt_needed needed; struct dt_needed needed;
if (!initialized) if (!initialized)
@ -963,7 +1007,7 @@ gld${EMULATION_NAME}_check_ld_so_conf (const struct bfd_link_needed_list *l,
int force) int force)
{ {
static bfd_boolean initialized; static bfd_boolean initialized;
static char *ld_so_conf; static const char *ld_so_conf;
struct dt_needed needed; struct dt_needed needed;
if (! initialized) if (! initialized)
@ -986,9 +1030,8 @@ gld${EMULATION_NAME}_check_ld_so_conf (const struct bfd_link_needed_list *l,
if (info.path) 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); free (info.path);
ld_so_conf = d;
} }
initialized = TRUE; initialized = TRUE;
} }
@ -1381,9 +1424,9 @@ gld${EMULATION_NAME}_after_open (void)
size_t len; size_t len;
search_dirs_type *search; search_dirs_type *search;
EOF EOF
if [ "x${NATIVE}" = xyes ] ; then if [ "x${NATIVE}" = xyes ] || [ "x${USE_LIBPATH}" = xyes ] ; then
fragment <<EOF fragment <<EOF
const char *lib_path; const char *path;
EOF EOF
fi fi
if [ "x${USE_LIBPATH}" = xyes ] ; then if [ "x${USE_LIBPATH}" = xyes ] ; then
@ -1400,9 +1443,13 @@ fragment <<EOF
EOF EOF
if [ "x${USE_LIBPATH}" = xyes ] ; then if [ "x${USE_LIBPATH}" = xyes ] ; then
fragment <<EOF fragment <<EOF
if (gld${EMULATION_NAME}_search_needed (command_line.rpath, path = command_line.rpath;
&n, force)) if (path)
break; {
found = gld${EMULATION_NAME}_search_needed (path, &n, force);
if (found)
break;
}
EOF EOF
fi fi
if [ "x${NATIVE}" = xyes ] ; then if [ "x${NATIVE}" = xyes ] ; then
@ -1410,13 +1457,14 @@ fragment <<EOF
if (command_line.rpath_link == NULL if (command_line.rpath_link == NULL
&& command_line.rpath == NULL) && command_line.rpath == NULL)
{ {
lib_path = (const char *) getenv ("LD_RUN_PATH"); path = (const char *) getenv ("LD_RUN_PATH");
if (gld${EMULATION_NAME}_search_needed (lib_path, &n, if (path
force)) && gld${EMULATION_NAME}_search_needed (path, &n, force))
break; break;
} }
lib_path = (const char *) getenv ("LD_LIBRARY_PATH"); path = (const char *) getenv ("LD_LIBRARY_PATH");
if (gld${EMULATION_NAME}_search_needed (lib_path, &n, force)) if (path
&& gld${EMULATION_NAME}_search_needed (path, &n, force))
break; break;
EOF EOF
fi fi
@ -1426,16 +1474,11 @@ fragment <<EOF
rp = bfd_elf_get_runpath_list (link_info.output_bfd, &link_info); rp = bfd_elf_get_runpath_list (link_info.output_bfd, &link_info);
for (; !found && rp != NULL; rp = rp->next) for (; !found && rp != NULL; rp = rp->next)
{ {
const char *tmpname = rp->name; path = gld${EMULATION_NAME}_add_sysroot (rp->name);
if (IS_ABSOLUTE_PATH (tmpname))
tmpname = gld${EMULATION_NAME}_add_sysroot (tmpname);
found = (rp->by == l->by found = (rp->by == l->by
&& gld${EMULATION_NAME}_search_needed (tmpname, && gld${EMULATION_NAME}_search_needed (path, &n,
&n,
force)); force));
if (tmpname != rp->name) free ((char *) path);
free ((char *) tmpname);
} }
if (found) if (found)
break; break;