For relative paths in INPUT() and GROUP(), search the directory of the current linker script before searching other paths.
PR ld/25806 * ldlang.h (struct lang_input_statement_struct): Add extra_search_path. * ldlang.c (current_input_file): New. (ldirname): New. (new_afile): Add from_filename parameter. Set extra_search_path. (lang_add_input_file): Pass current_input_file to new_afile. (load_symbols): Set current_input_file.
This commit is contained in:
parent
31c89d6038
commit
161719466a
14
ld/ChangeLog
14
ld/ChangeLog
@ -1,3 +1,17 @@
|
||||
2020-04-22 Fangrui Song <maskray@google.com>
|
||||
|
||||
PR ld/25806
|
||||
* ldlang.h (struct lang_input_statement_struct): Add extra_search_path.
|
||||
* ldlang.c (current_input_file): New.
|
||||
(ldirname): New.
|
||||
(new_afile): Add from_filename parameter. Set extra_search_path.
|
||||
(lang_add_input_file): Pass current_input_file to new_afile.
|
||||
(load_symbols): Set current_input_file.
|
||||
* ldfile.c (ldfile_open_file): If extra_search_path has been set
|
||||
then scan it for the file that needs to be opened.
|
||||
* ld.texi: Document the new behaviour.
|
||||
* NEWS: Mention the new feature.
|
||||
|
||||
2020-04-22 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* testsuite/ld-scripts/default-script1.d: Correct mingw skip.
|
||||
|
4
ld/NEWS
4
ld/NEWS
@ -7,6 +7,10 @@
|
||||
IMAGIC (0411) for separate instruction and data spaces, and change the
|
||||
default format option for pdp11-aout to be --omagic.
|
||||
|
||||
* Relative pathnames in INPUT() and GROUP() directives in linker scripts are
|
||||
searched relative to the directory of the linker script before other search
|
||||
paths.
|
||||
|
||||
Changes in 2.34:
|
||||
|
||||
* The ld check for "PHDR segment not covered by LOAD segment" is more
|
||||
|
17
ld/ld.texi
17
ld/ld.texi
@ -3657,13 +3657,16 @@ script, and then invoke the linker with nothing but a @samp{-T} option.
|
||||
In case a @dfn{sysroot prefix} is configured, and the filename starts
|
||||
with the @samp{/} character, and the script being processed was
|
||||
located inside the @dfn{sysroot prefix}, the filename will be looked
|
||||
for in the @dfn{sysroot prefix}. Otherwise, the linker will try to
|
||||
open the file in the current directory. If it is not found, the
|
||||
linker will search through the archive library search path.
|
||||
The @dfn{sysroot prefix} can also be forced by specifying @code{=}
|
||||
as the first character in the filename path, or prefixing the filename
|
||||
path with @code{$SYSROOT}. See also the description of @samp{-L} in
|
||||
@ref{Options,,Command-line Options}.
|
||||
for in the @dfn{sysroot prefix}. The @dfn{sysroot prefix} can also be forced by specifying
|
||||
@code{=} as the first character in the filename path, or prefixing the
|
||||
filename path with @code{$SYSROOT}. See also the description of
|
||||
@samp{-L} in @ref{Options,,Command-line Options}.
|
||||
|
||||
If a @dfn{sysroot prefix} is not used then the linker will try to open
|
||||
the file in the directory containing the linker script. If it is not
|
||||
found the linker will then search the current directory. If it is still
|
||||
not found the linker will search through the archive library search
|
||||
path.
|
||||
|
||||
If you use @samp{INPUT (-l@var{file})}, @command{ld} will transform the
|
||||
name to @code{lib@var{file}.a}, as with the command-line argument
|
||||
|
19
ld/ldfile.c
19
ld/ldfile.c
@ -416,7 +416,24 @@ ldfile_open_file (lang_input_statement_type *entry)
|
||||
search_arch_type *arch;
|
||||
bfd_boolean found = FALSE;
|
||||
|
||||
/* Try to open <filename><suffix> or lib<filename><suffix>.a */
|
||||
/* If extra_search_path is set, entry->filename is a relative path.
|
||||
Search the directory of the current linker script before searching
|
||||
other paths. */
|
||||
if (entry->extra_search_path)
|
||||
{
|
||||
char *path = concat (entry->extra_search_path, slash, entry->filename,
|
||||
(const char *)0);
|
||||
if (ldfile_try_open_bfd (path, entry))
|
||||
{
|
||||
entry->filename = path;
|
||||
entry->flags.search_dirs = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
free (path);
|
||||
}
|
||||
|
||||
/* Try to open <filename><suffix> or lib<filename><suffix>.a. */
|
||||
for (arch = search_arch_head; arch != NULL; arch = arch->next)
|
||||
{
|
||||
found = ldfile_open_file_search (arch->name, entry, "lib", ".a");
|
||||
|
32
ld/ldlang.c
32
ld/ldlang.c
@ -117,6 +117,7 @@ lang_statement_list_type file_chain = { NULL, NULL };
|
||||
lang_input_statement_type statement (reached via input_statement field in a
|
||||
lang_statement_union). */
|
||||
lang_statement_list_type input_file_chain;
|
||||
static const char *current_input_file;
|
||||
struct bfd_sym_chain entry_symbol = { NULL, NULL };
|
||||
const char *entry_section = ".text";
|
||||
struct lang_input_statement_flags input_flags;
|
||||
@ -176,6 +177,21 @@ name_match (const char *pattern, const char *name)
|
||||
return strcmp (pattern, name);
|
||||
}
|
||||
|
||||
static char *
|
||||
ldirname (const char *name)
|
||||
{
|
||||
const char *base = lbasename (name);
|
||||
char *dirname;
|
||||
|
||||
while (base > name && IS_DIR_SEPARATOR (base[-1]))
|
||||
--base;
|
||||
if (base == name)
|
||||
return strdup (".");
|
||||
dirname = strdup (name);
|
||||
dirname[base - name] = '\0';
|
||||
return dirname;
|
||||
}
|
||||
|
||||
/* If PATTERN is of the form archive:file, return a pointer to the
|
||||
separator. If not, return NULL. */
|
||||
|
||||
@ -1093,7 +1109,8 @@ new_statement (enum statement_enum type,
|
||||
static lang_input_statement_type *
|
||||
new_afile (const char *name,
|
||||
lang_input_file_enum_type file_type,
|
||||
const char *target)
|
||||
const char *target,
|
||||
const char *from_filename)
|
||||
{
|
||||
lang_input_statement_type *p;
|
||||
|
||||
@ -1102,6 +1119,7 @@ new_afile (const char *name,
|
||||
p = new_stat (lang_input_statement, stat_ptr);
|
||||
memset (&p->the_bfd, 0,
|
||||
sizeof (*p) - offsetof (lang_input_statement_type, the_bfd));
|
||||
p->extra_search_path = NULL;
|
||||
p->target = target;
|
||||
p->flags.dynamic = input_flags.dynamic;
|
||||
p->flags.add_DT_NEEDED_for_dynamic = input_flags.add_DT_NEEDED_for_dynamic;
|
||||
@ -1142,6 +1160,10 @@ new_afile (const char *name,
|
||||
case lang_input_file_is_search_file_enum:
|
||||
p->filename = name;
|
||||
p->local_sym_name = name;
|
||||
/* If name is a relative path, search the directory of the current linker
|
||||
script first. */
|
||||
if (from_filename && !IS_ABSOLUTE_PATH (name))
|
||||
p->extra_search_path = ldirname (from_filename);
|
||||
p->flags.real = TRUE;
|
||||
p->flags.search_dirs = TRUE;
|
||||
break;
|
||||
@ -1181,12 +1203,12 @@ lang_add_input_file (const char *name,
|
||||
within the sysroot subdirectory.) */
|
||||
unsigned int outer_sysrooted = input_flags.sysrooted;
|
||||
input_flags.sysrooted = 0;
|
||||
ret = new_afile (sysrooted_name, file_type, target);
|
||||
ret = new_afile (sysrooted_name, file_type, target, NULL);
|
||||
input_flags.sysrooted = outer_sysrooted;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return new_afile (name, file_type, target);
|
||||
return new_afile (name, file_type, target, current_input_file);
|
||||
}
|
||||
|
||||
struct out_section_hash_entry
|
||||
@ -2909,7 +2931,7 @@ lookup_name (const char *name)
|
||||
lang_statement_union_type *rest = *after;
|
||||
stat_ptr->tail = after;
|
||||
search = new_afile (name, lang_input_file_is_search_file_enum,
|
||||
default_target);
|
||||
default_target, NULL);
|
||||
*stat_ptr->tail = rest;
|
||||
if (*tail == NULL)
|
||||
stat_ptr->tail = tail;
|
||||
@ -3051,7 +3073,9 @@ load_symbols (lang_input_statement_type *entry,
|
||||
|
||||
ldfile_assumed_script = TRUE;
|
||||
parser_input = input_script;
|
||||
current_input_file = entry->filename;
|
||||
yyparse ();
|
||||
current_input_file = NULL;
|
||||
ldfile_assumed_script = FALSE;
|
||||
|
||||
/* missing_file is sticky. sysrooted will already have been
|
||||
|
@ -293,6 +293,9 @@ typedef struct lang_input_statement_struct
|
||||
Usually the same as filename, but for a file spec'd with
|
||||
-l this is the -l switch itself rather than the filename. */
|
||||
const char *local_sym_name;
|
||||
/* Extra search path. Used to find a file relative to the
|
||||
directory of the current linker script. */
|
||||
const char *extra_search_path;
|
||||
|
||||
bfd *the_bfd;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user