PR24806, Linking with -T inside --start-group/--end-group
This patch processes INSERT AFTER and INSERT BEFORE in a user -T script when such a script is invoked on the command line inside --start-group/--end-group. Also, ld now warns when the user simply forgot --end-group. PR 24806 * ldlang.c (process_insert_statements): Add start of list parameter. Use rather than lang_os_list.head. Process insert statements inside group statements with a recursive call. (lang_process): Adjust process_insert_statements call. * lexsup.c (parse_args): Warn when adding missing --end-group.
This commit is contained in:
parent
5c1e6d53a5
commit
776ab89fe3
@ -1,3 +1,12 @@
|
|||||||
|
2019-08-01 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
PR 24806
|
||||||
|
* ldlang.c (process_insert_statements): Add start of list
|
||||||
|
parameter. Use rather than lang_os_list.head. Process insert
|
||||||
|
statements inside group statements with a recursive call.
|
||||||
|
(lang_process): Adjust process_insert_statements call.
|
||||||
|
* lexsup.c (parse_args): Warn when adding missing --end-group.
|
||||||
|
|
||||||
2019-08-01 Alan Modra <amodra@gmail.com>
|
2019-08-01 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* ldlang.h (lang_os_list): Rename from lang_output_section_statement.
|
* ldlang.h (lang_os_list): Rename from lang_output_section_statement.
|
||||||
|
50
ld/ldlang.c
50
ld/ldlang.c
@ -3916,21 +3916,26 @@ map_input_to_output_sections
|
|||||||
start of the list and places them after the output section
|
start of the list and places them after the output section
|
||||||
statement specified by the insert. This operation is complicated
|
statement specified by the insert. This operation is complicated
|
||||||
by the fact that we keep a doubly linked list of output section
|
by the fact that we keep a doubly linked list of output section
|
||||||
statements as well as the singly linked list of all statements. */
|
statements as well as the singly linked list of all statements.
|
||||||
|
FIXME someday: Twiddling with the list not only moves statements
|
||||||
|
from the user's script but also input and group statements that are
|
||||||
|
built from command line object files and --start-group. We only
|
||||||
|
get away with this because the list pointers used by file_chain
|
||||||
|
and input_file_chain are not reordered, and processing via
|
||||||
|
statement_list after this point mostly ignores input statements.
|
||||||
|
One exception is the map file, where LOAD and START GROUP/END GROUP
|
||||||
|
can end up looking odd. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
process_insert_statements (void)
|
process_insert_statements (lang_statement_union_type **start)
|
||||||
{
|
{
|
||||||
lang_statement_union_type **s;
|
lang_statement_union_type **s;
|
||||||
lang_output_section_statement_type *first_os = NULL;
|
lang_output_section_statement_type *first_os = NULL;
|
||||||
lang_output_section_statement_type *last_os = NULL;
|
lang_output_section_statement_type *last_os = NULL;
|
||||||
lang_output_section_statement_type *os;
|
lang_output_section_statement_type *os;
|
||||||
|
|
||||||
/* "start of list" is actually the statement immediately after
|
s = start;
|
||||||
the special abs_section output statement, so that it isn't
|
while (*s != NULL)
|
||||||
reordered. */
|
|
||||||
s = &lang_os_list.head;
|
|
||||||
while (*(s = &(*s)->header.next) != NULL)
|
|
||||||
{
|
{
|
||||||
if ((*s)->header.type == lang_output_section_statement_enum)
|
if ((*s)->header.type == lang_output_section_statement_enum)
|
||||||
{
|
{
|
||||||
@ -3949,6 +3954,18 @@ process_insert_statements (void)
|
|||||||
if (first_os == NULL)
|
if (first_os == NULL)
|
||||||
first_os = last_os;
|
first_os = last_os;
|
||||||
}
|
}
|
||||||
|
else if ((*s)->header.type == lang_group_statement_enum)
|
||||||
|
{
|
||||||
|
/* A user might put -T between --start-group and
|
||||||
|
--end-group. One way this odd construct might arise is
|
||||||
|
from a wrapper around ld to change library search
|
||||||
|
behaviour. For example:
|
||||||
|
#! /bin/sh
|
||||||
|
exec real_ld --start-group "$@" --end-group
|
||||||
|
This isn't completely unreasonable so go looking inside a
|
||||||
|
group statement for insert statements. */
|
||||||
|
process_insert_statements (&(*s)->group_statement.children.head);
|
||||||
|
}
|
||||||
else if ((*s)->header.type == lang_insert_statement_enum)
|
else if ((*s)->header.type == lang_insert_statement_enum)
|
||||||
{
|
{
|
||||||
lang_insert_statement_type *i = &(*s)->insert_statement;
|
lang_insert_statement_type *i = &(*s)->insert_statement;
|
||||||
@ -4049,18 +4066,19 @@ process_insert_statements (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ptr = insert_os_after (where);
|
ptr = insert_os_after (where);
|
||||||
/* Snip everything after the abs_section output statement we
|
/* Snip everything from the start of the list, up to and
|
||||||
know is at the start of the list, up to and including
|
including the insert statement we are currently processing. */
|
||||||
the insert statement we are currently processing. */
|
first = *start;
|
||||||
first = lang_os_list.head->header.next;
|
*start = (*s)->header.next;
|
||||||
lang_os_list.head->header.next = (*s)->header.next;
|
/* Add them back where they belong, minus the insert. */
|
||||||
/* Add them back where they belong. */
|
|
||||||
*s = *ptr;
|
*s = *ptr;
|
||||||
if (*s == NULL)
|
if (*s == NULL)
|
||||||
statement_list.tail = s;
|
statement_list.tail = s;
|
||||||
*ptr = first;
|
*ptr = first;
|
||||||
s = &lang_os_list.head;
|
s = start;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
s = &(*s)->header.next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Undo constraint twiddling. */
|
/* Undo constraint twiddling. */
|
||||||
@ -7544,7 +7562,9 @@ lang_process (void)
|
|||||||
lang_statement_iteration++;
|
lang_statement_iteration++;
|
||||||
map_input_to_output_sections (statement_list.head, NULL, NULL);
|
map_input_to_output_sections (statement_list.head, NULL, NULL);
|
||||||
|
|
||||||
process_insert_statements ();
|
/* Start at the statement immediately after the special abs_section
|
||||||
|
output statement, so that it isn't reordered. */
|
||||||
|
process_insert_statements (&lang_os_list.head->header.next);
|
||||||
|
|
||||||
/* Find any sections not attached explicitly and handle them. */
|
/* Find any sections not attached explicitly and handle them. */
|
||||||
lang_place_orphans ();
|
lang_place_orphans ();
|
||||||
|
@ -1602,6 +1602,7 @@ parse_args (unsigned argc, char **argv)
|
|||||||
|
|
||||||
while (ingroup)
|
while (ingroup)
|
||||||
{
|
{
|
||||||
|
einfo (_("%P: missing --end-group; added as last command line option\n"));
|
||||||
lang_leave_group ();
|
lang_leave_group ();
|
||||||
ingroup--;
|
ingroup--;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user