PR ld/11304
* ldlang.c (exp_init_os): Delete forward declaration. (init_os): Don't check for bfd_section already created and don't init addr_tree and load_base expressions here. (map_input_to_output_sections): Only map input to output sections and set constraints here, and as an exception, create output sections which have their address set. Move all the other code to.. (create_other_output_sections): ..here. New function. Handle init of addr_tree and load_base here too. (lang_process): Call create_other_output_sections.
This commit is contained in:
parent
8a59fff3dd
commit
c380a809de
13
ld/ChangeLog
13
ld/ChangeLog
@ -1,3 +1,16 @@
|
||||
2010-02-22 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR ld/11304
|
||||
* ldlang.c (exp_init_os): Delete forward declaration.
|
||||
(init_os): Don't check for bfd_section already created and don't
|
||||
init addr_tree and load_base expressions here.
|
||||
(map_input_to_output_sections): Only map input to output sections
|
||||
and set constraints here, and as an exception, create output
|
||||
sections which have their address set. Move all the other code to..
|
||||
(create_other_output_sections): ..here. New function. Handle init
|
||||
of addr_tree and load_base here too.
|
||||
(lang_process): Call create_other_output_sections.
|
||||
|
||||
2010-02-19 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* Makefile.am (eelf32_i960.c): Depend on ELF_GEN_DEPS, not ELF_DEPS.
|
||||
|
159
ld/ldlang.c
159
ld/ldlang.c
@ -68,7 +68,6 @@ static struct unique_sections *unique_section_list;
|
||||
static bfd_boolean ldlang_sysrooted_script = FALSE;
|
||||
|
||||
/* Forward declarations. */
|
||||
static void exp_init_os (etree_type *);
|
||||
static void init_map_userdata (bfd *, asection *, void *);
|
||||
static lang_input_statement_type *lookup_name (const char *);
|
||||
static struct bfd_hash_entry *lang_definedness_newfunc
|
||||
@ -2048,12 +2047,8 @@ sort_def_symbol (struct bfd_link_hash_entry *hash_entry,
|
||||
/* Initialize an output section. */
|
||||
|
||||
static void
|
||||
init_os (lang_output_section_statement_type *s, asection *isec,
|
||||
flagword flags)
|
||||
init_os (lang_output_section_statement_type *s, asection *isec, flagword flags)
|
||||
{
|
||||
if (s->bfd_section != NULL)
|
||||
return;
|
||||
|
||||
if (strcmp (s->name, DISCARD_SECTION_NAME) == 0)
|
||||
einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME);
|
||||
|
||||
@ -2078,14 +2073,6 @@ init_os (lang_output_section_statement_type *s, asection *isec,
|
||||
get_userdata (s->bfd_section) = new_userdata;
|
||||
}
|
||||
|
||||
/* If there is a base address, make sure that any sections it might
|
||||
mention are initialized. */
|
||||
if (s->addr_tree != NULL)
|
||||
exp_init_os (s->addr_tree);
|
||||
|
||||
if (s->load_base != NULL)
|
||||
exp_init_os (s->load_base);
|
||||
|
||||
/* If supplied an alignment, set it. */
|
||||
if (s->section_alignment != -1)
|
||||
s->bfd_section->alignment_power = s->section_alignment;
|
||||
@ -3430,10 +3417,10 @@ map_input_to_output_sections
|
||||
(lang_statement_union_type *s, const char *target,
|
||||
lang_output_section_statement_type *os)
|
||||
{
|
||||
flagword flags;
|
||||
|
||||
for (; s != NULL; s = s->header.next)
|
||||
{
|
||||
lang_output_section_statement_type *tos;
|
||||
|
||||
switch (s->header.type)
|
||||
{
|
||||
case lang_wild_statement_enum:
|
||||
@ -3445,29 +3432,23 @@ map_input_to_output_sections
|
||||
os);
|
||||
break;
|
||||
case lang_output_section_statement_enum:
|
||||
if (s->output_section_statement.constraint)
|
||||
tos = &s->output_section_statement;
|
||||
if (tos->constraint != 0)
|
||||
{
|
||||
if (s->output_section_statement.constraint != ONLY_IF_RW
|
||||
&& s->output_section_statement.constraint != ONLY_IF_RO)
|
||||
if (tos->constraint != ONLY_IF_RW
|
||||
&& tos->constraint != ONLY_IF_RO)
|
||||
break;
|
||||
s->output_section_statement.all_input_readonly = TRUE;
|
||||
check_input_sections (s->output_section_statement.children.head,
|
||||
&s->output_section_statement);
|
||||
if ((s->output_section_statement.all_input_readonly
|
||||
&& s->output_section_statement.constraint == ONLY_IF_RW)
|
||||
|| (!s->output_section_statement.all_input_readonly
|
||||
&& s->output_section_statement.constraint == ONLY_IF_RO))
|
||||
tos->all_input_readonly = TRUE;
|
||||
check_input_sections (tos->children.head, tos);
|
||||
if (tos->all_input_readonly != (tos->constraint == ONLY_IF_RO))
|
||||
{
|
||||
s->output_section_statement.constraint = -1;
|
||||
tos->constraint = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
map_input_to_output_sections (s->output_section_statement.children.head,
|
||||
map_input_to_output_sections (tos->children.head,
|
||||
target,
|
||||
&s->output_section_statement);
|
||||
break;
|
||||
case lang_output_statement_enum:
|
||||
tos);
|
||||
break;
|
||||
case lang_target_statement_enum:
|
||||
target = s->target_statement.target;
|
||||
@ -3477,19 +3458,102 @@ map_input_to_output_sections
|
||||
target,
|
||||
os);
|
||||
break;
|
||||
case lang_address_statement_enum:
|
||||
/* Mark the specified section with the supplied address.
|
||||
If this section was actually a segment marker, then the
|
||||
directive is ignored if the linker script explicitly
|
||||
processed the segment marker. Originally, the linker
|
||||
treated segment directives (like -Ttext on the
|
||||
command-line) as section directives. We honor the
|
||||
section directive semantics for backwards compatibilty;
|
||||
linker scripts that do not specifically check for
|
||||
SEGMENT_START automatically get the old semantics. */
|
||||
if (!s->address_statement.segment
|
||||
|| !s->address_statement.segment->used)
|
||||
{
|
||||
const char *name = s->address_statement.section_name;
|
||||
|
||||
/* Create the output section statement here rather than
|
||||
in create_other_output_sections so that orphans with
|
||||
a set address will be placed after other script
|
||||
sections. If we let the orphan placement code place
|
||||
them in amongst other sections then the address will
|
||||
affect following script sections, which is likely to
|
||||
surprise naive users. */
|
||||
tos = lang_output_section_statement_lookup (name, 0, TRUE);
|
||||
tos->addr_tree = s->address_statement.address;
|
||||
}
|
||||
break;
|
||||
case lang_output_statement_enum:
|
||||
case lang_data_statement_enum:
|
||||
case lang_input_section_enum:
|
||||
case lang_fill_statement_enum:
|
||||
case lang_object_symbols_statement_enum:
|
||||
case lang_reloc_statement_enum:
|
||||
case lang_padding_statement_enum:
|
||||
case lang_input_statement_enum:
|
||||
case lang_assignment_statement_enum:
|
||||
case lang_insert_statement_enum:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Create any other output sections, such as needed for data statements
|
||||
or those referenced in expressions. */
|
||||
|
||||
static void
|
||||
create_other_output_sections
|
||||
(lang_statement_union_type *s,
|
||||
lang_output_section_statement_type *os)
|
||||
{
|
||||
lang_output_section_statement_type *tos;
|
||||
flagword flags;
|
||||
|
||||
for (; s != NULL; s = s->header.next)
|
||||
{
|
||||
switch (s->header.type)
|
||||
{
|
||||
case lang_wild_statement_enum:
|
||||
break;
|
||||
case lang_constructors_statement_enum:
|
||||
create_other_output_sections (constructor_list.head, os);
|
||||
break;
|
||||
case lang_output_section_statement_enum:
|
||||
tos = &s->output_section_statement;
|
||||
if (tos->constraint != 0
|
||||
&& tos->constraint != ONLY_IF_RW
|
||||
&& tos->constraint != ONLY_IF_RO)
|
||||
break;
|
||||
create_other_output_sections (tos->children.head, tos);
|
||||
if (tos->bfd_section != NULL)
|
||||
{
|
||||
/* If there is a base address, make sure that any sections
|
||||
it might mention are initialized. */
|
||||
if (tos->addr_tree != NULL)
|
||||
exp_init_os (tos->addr_tree);
|
||||
if (tos->load_base != NULL)
|
||||
exp_init_os (tos->load_base);
|
||||
}
|
||||
break;
|
||||
case lang_output_statement_enum:
|
||||
case lang_target_statement_enum:
|
||||
break;
|
||||
case lang_group_statement_enum:
|
||||
create_other_output_sections (s->group_statement.children.head, os);
|
||||
break;
|
||||
case lang_data_statement_enum:
|
||||
/* Make sure that any sections mentioned in the expression
|
||||
are initialized. */
|
||||
exp_init_os (s->data_statement.exp);
|
||||
if (os->bfd_section == NULL)
|
||||
init_os (os, NULL, 0);
|
||||
flags = SEC_HAS_CONTENTS;
|
||||
/* The output section gets contents, and then we inspect for
|
||||
any flags set in the input script which override any ALLOC. */
|
||||
if (!(os->flags & SEC_NEVER_LOAD))
|
||||
flags |= SEC_ALLOC | SEC_LOAD;
|
||||
if (os->bfd_section == NULL)
|
||||
init_os (os, NULL, flags);
|
||||
else
|
||||
os->bfd_section->flags |= flags;
|
||||
os->bfd_section->flags |= flags;
|
||||
break;
|
||||
case lang_input_section_enum:
|
||||
break;
|
||||
@ -3510,25 +3574,14 @@ map_input_to_output_sections
|
||||
exp_init_os (s->assignment_statement.exp);
|
||||
break;
|
||||
case lang_address_statement_enum:
|
||||
/* Mark the specified section with the supplied address.
|
||||
If this section was actually a segment marker, then the
|
||||
directive is ignored if the linker script explicitly
|
||||
processed the segment marker. Originally, the linker
|
||||
treated segment directives (like -Ttext on the
|
||||
command-line) as section directives. We honor the
|
||||
section directive semantics for backwards compatibilty;
|
||||
linker scripts that do not specifically check for
|
||||
SEGMENT_START automatically get the old semantics. */
|
||||
if (!s->address_statement.segment
|
||||
|| !s->address_statement.segment->used)
|
||||
{
|
||||
lang_output_section_statement_type *aos
|
||||
= (lang_output_section_statement_lookup
|
||||
(s->address_statement.section_name, 0, TRUE));
|
||||
const char *name = s->address_statement.section_name;
|
||||
|
||||
if (aos->bfd_section == NULL)
|
||||
init_os (aos, NULL, 0);
|
||||
aos->addr_tree = s->address_statement.address;
|
||||
tos = lang_output_section_find (name);
|
||||
if (tos->bfd_section == NULL)
|
||||
init_os (tos, NULL, 0);
|
||||
}
|
||||
break;
|
||||
case lang_insert_statement_enum:
|
||||
@ -6347,6 +6400,10 @@ lang_process (void)
|
||||
/* Find any sections not attached explicitly and handle them. */
|
||||
lang_place_orphans ();
|
||||
|
||||
/* Create sections for data statements and those referenced in
|
||||
expressions but otherwise empty. */
|
||||
create_other_output_sections (statement_list.head, NULL);
|
||||
|
||||
if (! link_info.relocatable)
|
||||
{
|
||||
asection *found;
|
||||
|
Loading…
Reference in New Issue
Block a user