Duplicate output sections in scripts
Previously, ld merged duplicate output sections if such existed in scripts, except for those with a constraint of SPECIAL. This makes scripts with duplicate output section statements create duplicate output sections in the linker output file. * ldlang.c (lang_output_section_statement_lookup): Change "create" parameter to a tristate, if 2 then always create a new output section statement. Update all callers, with lang_enter_output_section_statement using "2". (map_input_to_output_sections): Don't ignore SPECIAL constraint here. * ldlang.h (lang_output_section_statement_type): Update prototype. (lang_output_section_find): Update.
This commit is contained in:
parent
6595cf3ce8
commit
21401fc7bf
11
ld/ChangeLog
11
ld/ChangeLog
@ -1,3 +1,14 @@
|
|||||||
|
2020-11-25 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* ldlang.c (lang_output_section_statement_lookup): Change "create"
|
||||||
|
parameter to a tristate, if 2 then always create a new output
|
||||||
|
section statement. Update all callers, with
|
||||||
|
lang_enter_output_section_statement using "2".
|
||||||
|
(map_input_to_output_sections): Don't ignore SPECIAL constraint
|
||||||
|
here.
|
||||||
|
* ldlang.h (lang_output_section_statement_type): Update prototype.
|
||||||
|
(lang_output_section_find): Update.
|
||||||
|
|
||||||
2020-11-24 H.J. Lu <hongjiu.lu@intel.com>
|
2020-11-24 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
PR gold/26939
|
PR gold/26939
|
||||||
|
72
ld/ldlang.c
72
ld/ldlang.c
@ -1305,7 +1305,7 @@ lang_init (void)
|
|||||||
first_file = lang_add_input_file (NULL, lang_input_file_is_marker_enum,
|
first_file = lang_add_input_file (NULL, lang_input_file_is_marker_enum,
|
||||||
NULL);
|
NULL);
|
||||||
abs_output_section =
|
abs_output_section =
|
||||||
lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME, 0, TRUE);
|
lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME, 0, 1);
|
||||||
|
|
||||||
abs_output_section->bfd_section = bfd_abs_section_ptr;
|
abs_output_section->bfd_section = bfd_abs_section_ptr;
|
||||||
|
|
||||||
@ -1464,19 +1464,21 @@ lang_output_section_get (const asection *output_section)
|
|||||||
|
|
||||||
/* Find or create an output_section_statement with the given NAME.
|
/* Find or create an output_section_statement with the given NAME.
|
||||||
If CONSTRAINT is non-zero match one with that constraint, otherwise
|
If CONSTRAINT is non-zero match one with that constraint, otherwise
|
||||||
match any non-negative constraint. If CREATE, always make a
|
match any non-negative constraint. If CREATE is 0 return NULL when
|
||||||
new output_section_statement for SPECIAL CONSTRAINT. */
|
no match exists. If CREATE is 1, create an output_section_statement
|
||||||
|
when no match exists or if CONSTRAINT is SPECIAL. If CREATE is 2,
|
||||||
|
always make a new output_section_statement. */
|
||||||
|
|
||||||
lang_output_section_statement_type *
|
lang_output_section_statement_type *
|
||||||
lang_output_section_statement_lookup (const char *name,
|
lang_output_section_statement_lookup (const char *name,
|
||||||
int constraint,
|
int constraint,
|
||||||
bfd_boolean create)
|
int create)
|
||||||
{
|
{
|
||||||
struct out_section_hash_entry *entry;
|
struct out_section_hash_entry *entry;
|
||||||
|
|
||||||
entry = ((struct out_section_hash_entry *)
|
entry = ((struct out_section_hash_entry *)
|
||||||
bfd_hash_lookup (&output_section_statement_table, name,
|
bfd_hash_lookup (&output_section_statement_table, name,
|
||||||
create, FALSE));
|
create != 0, FALSE));
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
{
|
{
|
||||||
if (create)
|
if (create)
|
||||||
@ -1491,23 +1493,19 @@ lang_output_section_statement_lookup (const char *name,
|
|||||||
struct out_section_hash_entry *last_ent;
|
struct out_section_hash_entry *last_ent;
|
||||||
|
|
||||||
name = entry->s.output_section_statement.name;
|
name = entry->s.output_section_statement.name;
|
||||||
if (create && constraint == SPECIAL)
|
do
|
||||||
/* Not traversing to the end reverses the order of the second
|
{
|
||||||
and subsequent SPECIAL sections in the hash table chain,
|
if (create != 2
|
||||||
but that shouldn't matter. */
|
&& !(create && constraint == SPECIAL)
|
||||||
last_ent = entry;
|
&& (constraint == entry->s.output_section_statement.constraint
|
||||||
else
|
|| (constraint == 0
|
||||||
do
|
&& entry->s.output_section_statement.constraint >= 0)))
|
||||||
{
|
return &entry->s.output_section_statement;
|
||||||
if (constraint == entry->s.output_section_statement.constraint
|
last_ent = entry;
|
||||||
|| (constraint == 0
|
entry = (struct out_section_hash_entry *) entry->root.next;
|
||||||
&& entry->s.output_section_statement.constraint >= 0))
|
}
|
||||||
return &entry->s.output_section_statement;
|
while (entry != NULL
|
||||||
last_ent = entry;
|
&& name == entry->s.output_section_statement.name);
|
||||||
entry = (struct out_section_hash_entry *) entry->root.next;
|
|
||||||
}
|
|
||||||
while (entry != NULL
|
|
||||||
&& name == entry->s.output_section_statement.name);
|
|
||||||
|
|
||||||
if (!create)
|
if (!create)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -4175,22 +4173,18 @@ map_input_to_output_sections
|
|||||||
break;
|
break;
|
||||||
case lang_output_section_statement_enum:
|
case lang_output_section_statement_enum:
|
||||||
tos = &s->output_section_statement;
|
tos = &s->output_section_statement;
|
||||||
if (tos->constraint != 0)
|
if (tos->constraint == ONLY_IF_RW
|
||||||
|
|| tos->constraint == ONLY_IF_RO)
|
||||||
{
|
{
|
||||||
if (tos->constraint != ONLY_IF_RW
|
|
||||||
&& tos->constraint != ONLY_IF_RO)
|
|
||||||
break;
|
|
||||||
tos->all_input_readonly = TRUE;
|
tos->all_input_readonly = TRUE;
|
||||||
check_input_sections (tos->children.head, tos);
|
check_input_sections (tos->children.head, tos);
|
||||||
if (tos->all_input_readonly != (tos->constraint == ONLY_IF_RO))
|
if (tos->all_input_readonly != (tos->constraint == ONLY_IF_RO))
|
||||||
{
|
tos->constraint = -1;
|
||||||
tos->constraint = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
map_input_to_output_sections (tos->children.head,
|
if (tos->constraint >= 0)
|
||||||
target,
|
map_input_to_output_sections (tos->children.head,
|
||||||
tos);
|
target,
|
||||||
|
tos);
|
||||||
break;
|
break;
|
||||||
case lang_output_statement_enum:
|
case lang_output_statement_enum:
|
||||||
break;
|
break;
|
||||||
@ -4270,7 +4264,7 @@ map_input_to_output_sections
|
|||||||
place them in amongst other sections then the address
|
place them in amongst other sections then the address
|
||||||
will affect following script sections, which is
|
will affect following script sections, which is
|
||||||
likely to surprise naive users. */
|
likely to surprise naive users. */
|
||||||
tos = lang_output_section_statement_lookup (name, 0, TRUE);
|
tos = lang_output_section_statement_lookup (name, 0, 1);
|
||||||
tos->addr_tree = s->address_statement.address;
|
tos->addr_tree = s->address_statement.address;
|
||||||
if (tos->bfd_section == NULL)
|
if (tos->bfd_section == NULL)
|
||||||
init_os (tos, 0);
|
init_os (tos, 0);
|
||||||
@ -7206,8 +7200,7 @@ ldlang_place_orphan (asection *s)
|
|||||||
if (config.orphan_handling == orphan_handling_discard)
|
if (config.orphan_handling == orphan_handling_discard)
|
||||||
{
|
{
|
||||||
lang_output_section_statement_type *os;
|
lang_output_section_statement_type *os;
|
||||||
os = lang_output_section_statement_lookup (DISCARD_SECTION_NAME, 0,
|
os = lang_output_section_statement_lookup (DISCARD_SECTION_NAME, 0, 1);
|
||||||
TRUE);
|
|
||||||
if (os->addr_tree == NULL
|
if (os->addr_tree == NULL
|
||||||
&& (bfd_link_relocatable (&link_info)
|
&& (bfd_link_relocatable (&link_info)
|
||||||
|| (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0))
|
|| (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0))
|
||||||
@ -7230,7 +7223,7 @@ ldlang_place_orphan (asection *s)
|
|||||||
os = ldemul_place_orphan (s, name, constraint);
|
os = ldemul_place_orphan (s, name, constraint);
|
||||||
if (os == NULL)
|
if (os == NULL)
|
||||||
{
|
{
|
||||||
os = lang_output_section_statement_lookup (name, constraint, TRUE);
|
os = lang_output_section_statement_lookup (name, constraint, 1);
|
||||||
if (os->addr_tree == NULL
|
if (os->addr_tree == NULL
|
||||||
&& (bfd_link_relocatable (&link_info)
|
&& (bfd_link_relocatable (&link_info)
|
||||||
|| (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0))
|
|| (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0))
|
||||||
@ -7277,8 +7270,7 @@ lang_place_orphans (void)
|
|||||||
{
|
{
|
||||||
if (default_common_section == NULL)
|
if (default_common_section == NULL)
|
||||||
default_common_section
|
default_common_section
|
||||||
= lang_output_section_statement_lookup (".bss", 0,
|
= lang_output_section_statement_lookup (".bss", 0, 1);
|
||||||
TRUE);
|
|
||||||
lang_add_section (&default_common_section->children, s,
|
lang_add_section (&default_common_section->children, s,
|
||||||
NULL, default_common_section);
|
NULL, default_common_section);
|
||||||
}
|
}
|
||||||
@ -7420,7 +7412,7 @@ lang_enter_output_section_statement (const char *output_section_statement_name,
|
|||||||
lang_output_section_statement_type *os;
|
lang_output_section_statement_type *os;
|
||||||
|
|
||||||
os = lang_output_section_statement_lookup (output_section_statement_name,
|
os = lang_output_section_statement_lookup (output_section_statement_name,
|
||||||
constraint, TRUE);
|
constraint, 2);
|
||||||
current_section = os;
|
current_section = os;
|
||||||
|
|
||||||
if (os->addr_tree == NULL)
|
if (os->addr_tree == NULL)
|
||||||
|
@ -586,7 +586,7 @@ extern asection *section_for_dot
|
|||||||
statement = statement->next)
|
statement = statement->next)
|
||||||
|
|
||||||
#define lang_output_section_find(NAME) \
|
#define lang_output_section_find(NAME) \
|
||||||
lang_output_section_statement_lookup (NAME, 0, FALSE)
|
lang_output_section_statement_lookup (NAME, 0, 0)
|
||||||
|
|
||||||
extern void lang_process
|
extern void lang_process
|
||||||
(void);
|
(void);
|
||||||
@ -605,7 +605,7 @@ extern void lang_add_keepsyms_file
|
|||||||
extern lang_output_section_statement_type *lang_output_section_get
|
extern lang_output_section_statement_type *lang_output_section_get
|
||||||
(const asection *);
|
(const asection *);
|
||||||
extern lang_output_section_statement_type *lang_output_section_statement_lookup
|
extern lang_output_section_statement_type *lang_output_section_statement_lookup
|
||||||
(const char *, int, bfd_boolean);
|
(const char *, int, int);
|
||||||
extern lang_output_section_statement_type *next_matching_output_section_statement
|
extern lang_output_section_statement_type *next_matching_output_section_statement
|
||||||
(lang_output_section_statement_type *, int);
|
(lang_output_section_statement_type *, int);
|
||||||
extern void ldlang_add_undef
|
extern void ldlang_add_undef
|
||||||
|
Loading…
Reference in New Issue
Block a user