Fix a conflict between the linker's need to rename some PE format input libraries and the BFD library's file caching mechanism.
PR 29389 bfd * bfd.c (BFD_CLOSED_BY_CACHE): New bfd flag. * cache.c (bfd_cache_delete): Set BFD_CLOSED_BY_DELETE on the closed bfd. (bfd_cache_lookup_worker): Clear BFD_CLOSED_BY_DELETE on the newly reopened bfd. * opncls.c (bfd_set_filename): Refuse to change the name of a bfd that has been closed by bfd_cache_delete. Mark changed bfds as uncacheable. * bfd-in2.h: Regenerate. ld * ldlang.h (lang_input_statement_struct): Add sort_key field. * emultempl/pe.em (after_open): If multiple import libraries refer to the same bfd, store their names in the sort_key field. * emultempl/pep.em (after_open): Likewise. * ldlang.c (sort_filename): New function. Returns the filename to be used when sorting input files. (wild_sort): Use the sort_filename function.
This commit is contained in:
parent
8b8da1a9f3
commit
a6ad791442
@ -1,3 +1,16 @@
|
||||
2022-08-03 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR 29389
|
||||
* bfd.c (BFD_CLOSED_BY_CACHE): New bfd flag.
|
||||
* cache.c (bfd_cache_delete): Set BFD_CLOSED_BY_DELETE on the
|
||||
closed bfd.
|
||||
(bfd_cache_lookup_worker): Clear BFD_CLOSED_BY_DELETE on the newly
|
||||
reopened bfd.
|
||||
* opncls.c (bfd_set_filename): Refuse to change the name of a bfd
|
||||
that has been closed by bfd_cache_delete. Mark changed bfds as
|
||||
uncacheable.
|
||||
* bfd-in2.h: Regenerate.
|
||||
|
||||
2022-07-29 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR 29424
|
||||
|
@ -6638,6 +6638,8 @@ struct bfd
|
||||
/* Put pathnames into archives (non-POSIX). */
|
||||
#define BFD_ARCHIVE_FULL_PATH 0x100000
|
||||
|
||||
#define BFD_CLOSED_BY_CACHE 0x200000
|
||||
|
||||
/* Flags bits to be saved in bfd_preserve_save. */
|
||||
#define BFD_FLAGS_SAVED \
|
||||
(BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \
|
||||
|
@ -176,6 +176,8 @@ CODE_FRAGMENT
|
||||
. {* Put pathnames into archives (non-POSIX). *}
|
||||
.#define BFD_ARCHIVE_FULL_PATH 0x100000
|
||||
.
|
||||
.#define BFD_CLOSED_BY_CACHE 0x200000
|
||||
.
|
||||
. {* Flags bits to be saved in bfd_preserve_save. *}
|
||||
.#define BFD_FLAGS_SAVED \
|
||||
. (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \
|
||||
|
@ -177,6 +177,7 @@ bfd_cache_delete (bfd *abfd)
|
||||
|
||||
abfd->iostream = NULL;
|
||||
--open_files;
|
||||
abfd->flags |= BFD_CLOSED_BY_CACHE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -265,10 +266,13 @@ bfd_cache_lookup_worker (bfd *abfd, enum cache_flag flag)
|
||||
&& !(flag & CACHE_NO_SEEK_ERROR))
|
||||
bfd_set_error (bfd_error_system_call);
|
||||
else
|
||||
{
|
||||
abfd->flags &= ~BFD_CLOSED_BY_CACHE;
|
||||
return (FILE *) abfd->iostream;
|
||||
}
|
||||
|
||||
/* xgettext:c-format */
|
||||
_bfd_error_handler (_("reopening %pB: %s\n"),
|
||||
_bfd_error_handler (_("reopening %pB: %s"),
|
||||
abfd, bfd_errmsg (bfd_get_error ()));
|
||||
return NULL;
|
||||
}
|
||||
|
22
bfd/opncls.c
22
bfd/opncls.c
@ -2107,10 +2107,28 @@ bfd_set_filename (bfd *abfd, const char *filename)
|
||||
{
|
||||
size_t len = strlen (filename) + 1;
|
||||
char *n = bfd_alloc (abfd, len);
|
||||
if (n)
|
||||
|
||||
if (n == NULL)
|
||||
return NULL;
|
||||
|
||||
if (abfd->filename != NULL)
|
||||
{
|
||||
/* PR 29389. If we attempt to rename a file that has been closed due
|
||||
to caching, then we will not be able to reopen it later on. */
|
||||
if (abfd->iostream == NULL && (abfd->flags & BFD_CLOSED_BY_CACHE))
|
||||
{
|
||||
bfd_set_error (bfd_error_invalid_operation);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Similarly if we attempt to close a renamed file because the
|
||||
cache is now full, we will not be able to reopen it later on. */
|
||||
if (abfd->iostream != NULL)
|
||||
abfd->cacheable = 0;
|
||||
}
|
||||
|
||||
memcpy (n, filename, len);
|
||||
abfd->filename = n;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
11
ld/ChangeLog
11
ld/ChangeLog
@ -1,3 +1,14 @@
|
||||
2022-08-03 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR 29389
|
||||
* ldlang.h (lang_input_statement_struct): Add sort_key field.
|
||||
* emultempl/pe.em (after_open): If multiple import libraries refer
|
||||
to the same bfd, store their names in the sort_key field.
|
||||
* emultempl/pep.em (after_open): Likewise.
|
||||
* ldlang.c (sort_filename): New function. Returns the filename to
|
||||
be used when sorting input files.
|
||||
(wild_sort): Use the sort_filename function.
|
||||
|
||||
2022-07-29 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
PR ld/29411
|
||||
|
@ -1583,6 +1583,7 @@ gld${EMULATION_NAME}_after_open (void)
|
||||
{
|
||||
struct bfd_symbol *s;
|
||||
struct bfd_link_hash_entry * blhe;
|
||||
bfd *other_bfd;
|
||||
const char *other_bfd_filename;
|
||||
|
||||
s = (relocs[i]->sym_ptr_ptr)[0];
|
||||
@ -1599,20 +1600,25 @@ gld${EMULATION_NAME}_after_open (void)
|
||||
|| blhe->type != bfd_link_hash_defined)
|
||||
continue;
|
||||
|
||||
other_bfd = blhe->u.def.section->owner;
|
||||
if (other_bfd->my_archive == is->the_bfd->my_archive)
|
||||
continue;
|
||||
|
||||
other_bfd_filename
|
||||
= blhe->u.def.section->owner->my_archive
|
||||
? bfd_get_filename (blhe->u.def.section->owner->my_archive)
|
||||
: bfd_get_filename (blhe->u.def.section->owner);
|
||||
= (other_bfd->my_archive
|
||||
? bfd_get_filename (other_bfd->my_archive)
|
||||
: bfd_get_filename (other_bfd));
|
||||
|
||||
if (filename_cmp (bfd_get_filename
|
||||
(is->the_bfd->my_archive),
|
||||
other_bfd_filename) == 0)
|
||||
continue;
|
||||
|
||||
/* Rename this implib to match the other one. */
|
||||
if (!bfd_set_filename (is->the_bfd->my_archive,
|
||||
other_bfd_filename))
|
||||
einfo ("%F%P: %pB: %E\n", is->the_bfd);
|
||||
/* Sort this implib to match the other one. */
|
||||
lang_input_statement_type *arch_is
|
||||
= bfd_usrdata (is->the_bfd->my_archive);
|
||||
arch_is->sort_key = other_bfd_filename;
|
||||
break;
|
||||
}
|
||||
|
||||
free (relocs);
|
||||
@ -1719,10 +1725,7 @@ gld${EMULATION_NAME}_after_open (void)
|
||||
= xmalloc (strlen (bfd_get_filename (is->the_bfd)) + 3);
|
||||
sprintf (new_name, "%s.%c",
|
||||
bfd_get_filename (is->the_bfd), seq);
|
||||
is->filename = bfd_set_filename (is->the_bfd, new_name);
|
||||
free (new_name);
|
||||
if (!is->filename)
|
||||
einfo ("%F%P: %pB: %E\n", is->the_bfd);
|
||||
is->sort_key = new_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1547,6 +1547,7 @@ gld${EMULATION_NAME}_after_open (void)
|
||||
{
|
||||
struct bfd_symbol *s;
|
||||
struct bfd_link_hash_entry * blhe;
|
||||
bfd *other_bfd;
|
||||
const char *other_bfd_filename;
|
||||
|
||||
s = (relocs[i]->sym_ptr_ptr)[0];
|
||||
@ -1563,20 +1564,25 @@ gld${EMULATION_NAME}_after_open (void)
|
||||
|| blhe->type != bfd_link_hash_defined)
|
||||
continue;
|
||||
|
||||
other_bfd = blhe->u.def.section->owner;
|
||||
if (other_bfd->my_archive == is->the_bfd->my_archive)
|
||||
continue;
|
||||
|
||||
other_bfd_filename
|
||||
= blhe->u.def.section->owner->my_archive
|
||||
? bfd_get_filename (blhe->u.def.section->owner->my_archive)
|
||||
: bfd_get_filename (blhe->u.def.section->owner);
|
||||
= (other_bfd->my_archive
|
||||
? bfd_get_filename (other_bfd->my_archive)
|
||||
: bfd_get_filename (other_bfd));
|
||||
|
||||
if (filename_cmp (bfd_get_filename
|
||||
(is->the_bfd->my_archive),
|
||||
other_bfd_filename) == 0)
|
||||
continue;
|
||||
|
||||
/* Rename this implib to match the other one. */
|
||||
if (!bfd_set_filename (is->the_bfd->my_archive,
|
||||
other_bfd_filename))
|
||||
einfo ("%F%P: %pB: %E\n", is->the_bfd);
|
||||
/* Sort this implib to match the other one. */
|
||||
lang_input_statement_type *arch_is
|
||||
= bfd_usrdata (is->the_bfd->my_archive);
|
||||
arch_is->sort_key = other_bfd_filename;
|
||||
break;
|
||||
}
|
||||
|
||||
free (relocs);
|
||||
@ -1683,10 +1689,7 @@ gld${EMULATION_NAME}_after_open (void)
|
||||
= xmalloc (strlen (bfd_get_filename (is->the_bfd)) + 3);
|
||||
sprintf (new_name, "%s.%c",
|
||||
bfd_get_filename (is->the_bfd), seq);
|
||||
is->filename = bfd_set_filename (is->the_bfd, new_name);
|
||||
free (new_name);
|
||||
if (!is->filename)
|
||||
einfo ("%F%P: %pB: %E\n", is->the_bfd);
|
||||
is->sort_key = new_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
43
ld/ldlang.c
43
ld/ldlang.c
@ -1125,6 +1125,7 @@ new_afile (const char *name,
|
||||
p->flags.add_DT_NEEDED_for_regular = input_flags.add_DT_NEEDED_for_regular;
|
||||
p->flags.whole_archive = input_flags.whole_archive;
|
||||
p->flags.sysrooted = input_flags.sysrooted;
|
||||
p->sort_key = NULL;
|
||||
|
||||
switch (file_type)
|
||||
{
|
||||
@ -2723,6 +2724,17 @@ lang_add_section (lang_statement_list_type *ptr,
|
||||
new_section->pattern = pattern;
|
||||
}
|
||||
|
||||
/* PE puts the sort key in the input statement. */
|
||||
|
||||
static const char *
|
||||
sort_filename (bfd *abfd)
|
||||
{
|
||||
lang_input_statement_type *is = bfd_usrdata (abfd);
|
||||
if (is->sort_key)
|
||||
return is->sort_key;
|
||||
return bfd_get_filename (abfd);
|
||||
}
|
||||
|
||||
/* Handle wildcard sorting. This returns the lang_input_section which
|
||||
should follow the one we are going to create for SECTION and FILE,
|
||||
based on the sorting requirements of WILD. It returns NULL if the
|
||||
@ -2762,28 +2774,17 @@ wild_sort (lang_wild_statement_type *wild,
|
||||
the archive and then the name of the file within the
|
||||
archive. */
|
||||
|
||||
if (file->the_bfd != NULL
|
||||
&& file->the_bfd->my_archive != NULL)
|
||||
{
|
||||
fn = bfd_get_filename (file->the_bfd->my_archive);
|
||||
fa = true;
|
||||
}
|
||||
fa = file->the_bfd->my_archive != NULL;
|
||||
if (fa)
|
||||
fn = sort_filename (file->the_bfd->my_archive);
|
||||
else
|
||||
{
|
||||
fn = file->filename;
|
||||
fa = false;
|
||||
}
|
||||
fn = sort_filename (file->the_bfd);
|
||||
|
||||
if (ls->section->owner->my_archive != NULL)
|
||||
{
|
||||
ln = bfd_get_filename (ls->section->owner->my_archive);
|
||||
la = true;
|
||||
}
|
||||
la = ls->section->owner->my_archive != NULL;
|
||||
if (la)
|
||||
ln = sort_filename (ls->section->owner->my_archive);
|
||||
else
|
||||
{
|
||||
ln = bfd_get_filename (ls->section->owner);
|
||||
la = false;
|
||||
}
|
||||
ln = sort_filename (ls->section->owner);
|
||||
|
||||
i = filename_cmp (fn, ln);
|
||||
if (i > 0)
|
||||
@ -2794,9 +2795,9 @@ wild_sort (lang_wild_statement_type *wild,
|
||||
if (fa || la)
|
||||
{
|
||||
if (fa)
|
||||
fn = file->filename;
|
||||
fn = sort_filename (file->the_bfd);
|
||||
if (la)
|
||||
ln = bfd_get_filename (ls->section->owner);
|
||||
ln = sort_filename (ls->section->owner);
|
||||
|
||||
i = filename_cmp (fn, ln);
|
||||
if (i > 0)
|
||||
|
@ -305,6 +305,8 @@ 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;
|
||||
/* Name to use when sorting. */
|
||||
const char *sort_key;
|
||||
/* Extra search path. Used to find a file relative to the
|
||||
directory of the current linker script. */
|
||||
const char *extra_search_path;
|
||||
|
Loading…
x
Reference in New Issue
Block a user