LTO object insertion point
This is a mostly cosmetic fix for cases like PR24873 where LTO recompiled objects were supposed to be inserted inside a group. The specific case handled by this patch is when the first file inside a group is an archive, the first file claimed by the plugin. Prior to this patch we would have inserted the recompiled objects before the group, which doesn't matter really since the entire group will be reloaded, but it looks a little wrong in map files. PR 24873 * ldlang.c (find_replacements_insert_point): Return "before" flag. (find_next_input_statement): New function. (lang_process): When placing recompiled LTO objects before a claimed archive, place them immediately before in the statement list.
This commit is contained in:
parent
b02c4f1623
commit
128bf1fe60
@ -1,3 +1,12 @@
|
|||||||
|
2019-08-06 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
PR 24873
|
||||||
|
* ldlang.c (find_replacements_insert_point): Return "before" flag.
|
||||||
|
(find_next_input_statement): New function.
|
||||||
|
(lang_process): When placing recompiled LTO objects before a
|
||||||
|
claimed archive, place them immediately before in the statement
|
||||||
|
list.
|
||||||
|
|
||||||
2019-08-06 Alan Modra <amodra@gmail.com>
|
2019-08-06 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
PR 24873
|
PR 24873
|
||||||
|
59
ld/ldlang.c
59
ld/ldlang.c
@ -7226,7 +7226,7 @@ lang_relax_sections (bfd_boolean need_layout)
|
|||||||
inserted at the head of the file_chain. */
|
inserted at the head of the file_chain. */
|
||||||
|
|
||||||
static lang_input_statement_type *
|
static lang_input_statement_type *
|
||||||
find_replacements_insert_point (void)
|
find_replacements_insert_point (bfd_boolean *before)
|
||||||
{
|
{
|
||||||
lang_input_statement_type *claim1, *lastobject;
|
lang_input_statement_type *claim1, *lastobject;
|
||||||
lastobject = &input_file_chain.head->input_statement;
|
lastobject = &input_file_chain.head->input_statement;
|
||||||
@ -7235,7 +7235,10 @@ find_replacements_insert_point (void)
|
|||||||
claim1 = &claim1->next->input_statement)
|
claim1 = &claim1->next->input_statement)
|
||||||
{
|
{
|
||||||
if (claim1->flags.claimed)
|
if (claim1->flags.claimed)
|
||||||
return claim1->flags.claim_archive ? lastobject : claim1;
|
{
|
||||||
|
*before = claim1->flags.claim_archive;
|
||||||
|
return claim1->flags.claim_archive ? lastobject : claim1;
|
||||||
|
}
|
||||||
/* Update lastobject if this is a real object file. */
|
/* Update lastobject if this is a real object file. */
|
||||||
if (claim1->the_bfd != NULL && claim1->the_bfd->my_archive == NULL)
|
if (claim1->the_bfd != NULL && claim1->the_bfd->my_archive == NULL)
|
||||||
lastobject = claim1;
|
lastobject = claim1;
|
||||||
@ -7243,6 +7246,7 @@ find_replacements_insert_point (void)
|
|||||||
/* No files were claimed by the plugin. Choose the last object
|
/* No files were claimed by the plugin. Choose the last object
|
||||||
file found on the list (maybe the first, dummy entry) as the
|
file found on the list (maybe the first, dummy entry) as the
|
||||||
insert point. */
|
insert point. */
|
||||||
|
*before = FALSE;
|
||||||
return lastobject;
|
return lastobject;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7323,6 +7327,35 @@ lang_list_remove_tail (lang_statement_list_type *destlist,
|
|||||||
destlist->tail = savetail;
|
destlist->tail = savetail;
|
||||||
*savetail = NULL;
|
*savetail = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static lang_statement_union_type **
|
||||||
|
find_next_input_statement (lang_statement_union_type **s)
|
||||||
|
{
|
||||||
|
for ( ; *s; s = &(*s)->header.next)
|
||||||
|
{
|
||||||
|
lang_statement_union_type **t;
|
||||||
|
switch ((*s)->header.type)
|
||||||
|
{
|
||||||
|
case lang_input_statement_enum:
|
||||||
|
return s;
|
||||||
|
case lang_wild_statement_enum:
|
||||||
|
t = &(*s)->wild_statement.children.head;
|
||||||
|
break;
|
||||||
|
case lang_group_statement_enum:
|
||||||
|
t = &(*s)->group_statement.children.head;
|
||||||
|
break;
|
||||||
|
case lang_output_section_statement_enum:
|
||||||
|
t = &(*s)->output_section_statement.children.head;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
t = find_next_input_statement (t);
|
||||||
|
if (*t)
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
#endif /* ENABLE_PLUGINS */
|
#endif /* ENABLE_PLUGINS */
|
||||||
|
|
||||||
/* Add NAME to the list of garbage collection entry points. */
|
/* Add NAME to the list of garbage collection entry points. */
|
||||||
@ -7447,16 +7480,30 @@ lang_process (void)
|
|||||||
if (added.head != NULL)
|
if (added.head != NULL)
|
||||||
{
|
{
|
||||||
/* If so, we will insert them into the statement list immediately
|
/* If so, we will insert them into the statement list immediately
|
||||||
after the first input file that was claimed by the plugin. */
|
after the first input file that was claimed by the plugin,
|
||||||
plugin_insert = find_replacements_insert_point ();
|
unless that file was an archive in which case it is inserted
|
||||||
|
immediately before. */
|
||||||
|
bfd_boolean before;
|
||||||
|
lang_statement_union_type **prev;
|
||||||
|
plugin_insert = find_replacements_insert_point (&before);
|
||||||
/* If a plugin adds input files without having claimed any, we
|
/* If a plugin adds input files without having claimed any, we
|
||||||
don't really have a good idea where to place them. Just putting
|
don't really have a good idea where to place them. Just putting
|
||||||
them at the start or end of the list is liable to leave them
|
them at the start or end of the list is liable to leave them
|
||||||
outside the crtbegin...crtend range. */
|
outside the crtbegin...crtend range. */
|
||||||
ASSERT (plugin_insert != NULL);
|
ASSERT (plugin_insert != NULL);
|
||||||
/* Splice the new statement list into the old one. */
|
/* Splice the new statement list into the old one. */
|
||||||
lang_list_insert_after (stat_ptr, &added,
|
prev = &plugin_insert->header.next;
|
||||||
&plugin_insert->header.next);
|
if (before)
|
||||||
|
{
|
||||||
|
prev = find_next_input_statement (prev);
|
||||||
|
if (*prev != plugin_insert->next_real_file)
|
||||||
|
{
|
||||||
|
/* Huh? We didn't find the expected input statement. */
|
||||||
|
ASSERT (0);
|
||||||
|
prev = &plugin_insert->header.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lang_list_insert_after (stat_ptr, &added, prev);
|
||||||
/* Likewise for the file chains. */
|
/* Likewise for the file chains. */
|
||||||
lang_list_insert_after (&input_file_chain, &inputfiles,
|
lang_list_insert_after (&input_file_chain, &inputfiles,
|
||||||
&plugin_insert->next_real_file);
|
&plugin_insert->next_real_file);
|
||||||
|
Loading…
Reference in New Issue
Block a user