mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-15 04:31:49 +08:00
PR26150, Assertion when asm() defines global symbols, -flto and --start-group
If an archive map contains symbols that aren't actually defined by the indexed element for any reason, then loading that element will leave the symbol undefined (or common). This leads to the possibility of the element being loaded again should the archive be searched again due to the action of --start-group/--end-group. The testcase triggering this problem was an archive containing fat lto objects, with the archive map incorrectly created by ar rather than gcc-ar. PR 26150 * ldlang.c (ldlang_add_file): Assert that we aren't adding the current end of link.next list again too. * ldmain.c (add_archive_element): Don't load archive elements again that have already been loaded.
This commit is contained in:
parent
39f381cb80
commit
9221725d1f
@ -1,3 +1,11 @@
|
||||
2020-06-23 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR 26150
|
||||
* ldlang.c (ldlang_add_file): Assert that we aren't adding the
|
||||
current end of link.next list again too.
|
||||
* ldmain.c (add_archive_element): Don't load archive elements
|
||||
again that have already been loaded.
|
||||
|
||||
2020-06-23 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* testsuite/ld-elf/shared.exp (pr14170): Clear xfail for
|
||||
|
@ -7266,7 +7266,8 @@ ldlang_add_file (lang_input_statement_type *entry)
|
||||
|
||||
/* The BFD linker needs to have a list of all input BFDs involved in
|
||||
a link. */
|
||||
ASSERT (entry->the_bfd->link.next == NULL);
|
||||
ASSERT (link_info.input_bfds_tail != &entry->the_bfd->link.next
|
||||
&& entry->the_bfd->link.next == NULL);
|
||||
ASSERT (entry->the_bfd != link_info.output_bfd);
|
||||
|
||||
*link_info.input_bfds_tail = entry->the_bfd;
|
||||
|
21
ld/ldmain.c
21
ld/ldmain.c
@ -822,10 +822,6 @@ add_archive_element (struct bfd_link_info *info,
|
||||
input->local_sym_name = bfd_get_filename (abfd);
|
||||
input->the_bfd = abfd;
|
||||
|
||||
parent = bfd_usrdata (abfd->my_archive);
|
||||
if (parent != NULL && !parent->flags.reload)
|
||||
parent->next = input;
|
||||
|
||||
/* Save the original data for trace files/tries below, as plugins
|
||||
(if enabled) may possibly alter it to point to a replacement
|
||||
BFD, but we still want to output the original BFD filename. */
|
||||
@ -853,6 +849,23 @@ add_archive_element (struct bfd_link_info *info,
|
||||
}
|
||||
#endif /* BFD_SUPPORTS_PLUGINS */
|
||||
|
||||
if (link_info.input_bfds_tail == &input->the_bfd->link.next
|
||||
|| input->the_bfd->link.next != NULL)
|
||||
{
|
||||
/* We have already loaded this element, and are attempting to
|
||||
load it again. This can happen when the archive map doesn't
|
||||
match actual symbols defined by the element. */
|
||||
free (input);
|
||||
bfd_set_error (bfd_error_malformed_archive);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Set the file_chain pointer of archives to the last element loaded
|
||||
from the archive. See ldlang.c:find_rescan_insertion. */
|
||||
parent = bfd_usrdata (abfd->my_archive);
|
||||
if (parent != NULL && !parent->flags.reload)
|
||||
parent->next = input;
|
||||
|
||||
ldlang_add_file (input);
|
||||
|
||||
if (config.map_file != NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user