Fix infinite loop when processing rpath tokens.
PR ld/20784 * emultempl/elf32.em (search_needed): Fix infinite loop when unable to process a token. Add support for curly braced enclosed tokens. * ld.texinfo (--rpath-link): Document supprot for $ORIGIN and $LIB.
This commit is contained in:
parent
9af89fbaec
commit
e680a6b69b
@ -1,3 +1,12 @@
|
||||
2016-11-07 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR ld/20784
|
||||
* emultempl/elf32.em (search_needed): Fix infinite loop when
|
||||
unable to process a token. Add support for curly braced enclosed
|
||||
tokens.
|
||||
* ld.texinfo (--rpath-link): Document supprot for $ORIGIN and
|
||||
$LIB.
|
||||
|
||||
2016-11-07 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* ld.texinfo (--compress-debug-sections): Expand documentation of
|
||||
|
@ -495,6 +495,7 @@ gld${EMULATION_NAME}_search_needed (const char *path,
|
||||
len = strlen (name);
|
||||
while (1)
|
||||
{
|
||||
unsigned offset = 0;
|
||||
char * var;
|
||||
char *filename, *sset;
|
||||
|
||||
@ -527,8 +528,10 @@ gld${EMULATION_NAME}_search_needed (const char *path,
|
||||
/* PR 20535: Support the same pseudo-environment variables that
|
||||
are supported by ld.so. Namely, $ORIGIN, $LIB and $PLATFORM.
|
||||
Since there can be more than one occurrence of these tokens in
|
||||
the path we loop until no more are found. */
|
||||
while ((var = strchr (filename, '$')) != NULL)
|
||||
the path we loop until no more are found. Since we might not
|
||||
be able to substitute some of the tokens we maintain an offset
|
||||
into the filename for where we should begin our scan. */
|
||||
while ((var = strchr (filename + offset, '$')) != NULL)
|
||||
{
|
||||
/* The ld.so manual page does not say, but I am going to assume that
|
||||
these tokens are terminated by a directory seperator character
|
||||
@ -536,13 +539,14 @@ gld${EMULATION_NAME}_search_needed (const char *path,
|
||||
$ORIGIN should only be used at the start of a path, but that is
|
||||
not enforced here.
|
||||
|
||||
FIXME: The ld.so manual page also states that it allows ${ORIGIN}
|
||||
${LIB} and ${PLATFORM}. We should support these variants too.
|
||||
The ld.so manual page also states that it allows ${ORIGIN},
|
||||
${LIB} and ${PLATFORM}, so these are supported as well.
|
||||
|
||||
FIXME: The code could be a lot cleverer about allocating space
|
||||
for the processed string. */
|
||||
char * end = strchr (var, '/');
|
||||
char * replacement = NULL;
|
||||
char * v = var + 1;
|
||||
char * freeme = NULL;
|
||||
unsigned flen = strlen (filename);
|
||||
|
||||
@ -550,16 +554,27 @@ gld${EMULATION_NAME}_search_needed (const char *path,
|
||||
/* Temporarily terminate the filename at the end of the token. */
|
||||
* end = 0;
|
||||
|
||||
switch (var[1])
|
||||
if (*v == '{')
|
||||
++ v;
|
||||
switch (*v++)
|
||||
{
|
||||
case 'O':
|
||||
if (strcmp (var + 2, "RIGIN") == 0)
|
||||
if (strcmp (v, "RIGIN") == 0 || strcmp (v, "RIGIN}") == 0)
|
||||
{
|
||||
/* ORIGIN - replace with the full path to the directory
|
||||
containing the program or shared object. */
|
||||
if (needed.by == NULL)
|
||||
break;
|
||||
replacement = bfd_get_filename (needed.by);
|
||||
{
|
||||
if (link_info.output_bfd == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
replacement = bfd_get_filename (link_info.output_bfd);
|
||||
}
|
||||
else
|
||||
replacement = bfd_get_filename (needed.by);
|
||||
|
||||
if (replacement)
|
||||
{
|
||||
char * slash;
|
||||
@ -582,7 +597,7 @@ gld${EMULATION_NAME}_search_needed (const char *path,
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
if (strcmp (var + 2, "IB") == 0)
|
||||
if (strcmp (v, "IB") == 0 || strcmp (v, "IB}") == 0)
|
||||
{
|
||||
/* LIB - replace with "lib" in 32-bit environments
|
||||
and "lib64" in 64-bit environments. */
|
||||
@ -603,17 +618,12 @@ gld${EMULATION_NAME}_search_needed (const char *path,
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
if (strcmp (var + 2, "LATFORM") == 0)
|
||||
{
|
||||
/* Supporting $PLATFORM in a cross-hosted environment is not
|
||||
possible. Supporting it in a native environment involves
|
||||
loading the <sys/auxv.h> header file which loads the
|
||||
system <elf.h> header file, which conflicts with the
|
||||
"include/elf/mips.h" header file. */
|
||||
replacement = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Supporting $PLATFORM in a cross-hosted environment is not
|
||||
possible. Supporting it in a native environment involves
|
||||
loading the <sys/auxv.h> header file which loads the
|
||||
system <elf.h> header file, which conflicts with the
|
||||
"include/elf/mips.h" header file. */
|
||||
/* Fall through. */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -623,13 +633,19 @@ gld${EMULATION_NAME}_search_needed (const char *path,
|
||||
char * filename2 = xmalloc (flen + strlen (replacement));
|
||||
|
||||
if (end)
|
||||
sprintf (filename2, "%.*s%s/%s",
|
||||
(int)(var - filename), filename,
|
||||
replacement, end + 1);
|
||||
{
|
||||
sprintf (filename2, "%.*s%s/%s",
|
||||
(int)(var - filename), filename,
|
||||
replacement, end + 1);
|
||||
offset = (var - filename) + 1 + strlen (replacement);
|
||||
}
|
||||
else
|
||||
sprintf (filename2, "%.*s%s",
|
||||
(int)(var - filename), filename,
|
||||
replacement);
|
||||
{
|
||||
sprintf (filename2, "%.*s%s",
|
||||
(int)(var - filename), filename,
|
||||
replacement);
|
||||
offset = var - filename + strlen (replacement);
|
||||
}
|
||||
|
||||
free (filename);
|
||||
filename = filename2;
|
||||
@ -647,12 +663,17 @@ gld${EMULATION_NAME}_search_needed (const char *path,
|
||||
if (end)
|
||||
/* Restore the path separator. */
|
||||
* end = '/';
|
||||
|
||||
/* PR 20784: Make sure that we resume the scan
|
||||
*after* the token that we could not replace. */
|
||||
offset = (var + 1) - filename;
|
||||
}
|
||||
|
||||
free (freeme);
|
||||
}
|
||||
|
||||
needed.name = filename;
|
||||
|
||||
if (gld${EMULATION_NAME}_try_needed (&needed, force))
|
||||
return TRUE;
|
||||
|
||||
|
@ -1865,6 +1865,16 @@ specifies the first set of directories to search. The
|
||||
either by specifying a list of names separated by colons, or by
|
||||
appearing multiple times.
|
||||
|
||||
The tokens @var{$ORIGIN} and @var{$LIB} can appear in these search
|
||||
directories. They will be replaced by the full path to the directory
|
||||
containing the program or shared object in the case of @var{$ORIGIN}
|
||||
and either @samp{lib} - for 32-bit binaries - or @samp{lib64} - for
|
||||
64-bit binaries - in the case of @var{$LIB}.
|
||||
|
||||
The alternative form of these tokens - @var{$@{ORIGIN@}} and
|
||||
@var{$@{LIB@}} can also be used. The token @var{$PLATFORM} is not
|
||||
supported.
|
||||
|
||||
This option should be used with caution as it overrides the search path
|
||||
that may have been hard compiled into a shared library. In such a case it
|
||||
is possible to use unintentionally a different search path than the
|
||||
|
Loading…
Reference in New Issue
Block a user