parent
826fec2f76
commit
a431bc2e60
|
@ -1,3 +1,8 @@
|
||||||
|
2010-02-23 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
PR ld/11304
|
||||||
|
* ldlang.c: Revert last patch.
|
||||||
|
|
||||||
2010-02-23 Nick Clifton <nickc@redhat.com>
|
2010-02-23 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* po/bg.po: Updated Bulgarian translation.
|
* po/bg.po: Updated Bulgarian translation.
|
||||||
|
|
159
ld/ldlang.c
159
ld/ldlang.c
|
@ -68,6 +68,7 @@ static struct unique_sections *unique_section_list;
|
||||||
static bfd_boolean ldlang_sysrooted_script = FALSE;
|
static bfd_boolean ldlang_sysrooted_script = FALSE;
|
||||||
|
|
||||||
/* Forward declarations. */
|
/* Forward declarations. */
|
||||||
|
static void exp_init_os (etree_type *);
|
||||||
static void init_map_userdata (bfd *, asection *, void *);
|
static void init_map_userdata (bfd *, asection *, void *);
|
||||||
static lang_input_statement_type *lookup_name (const char *);
|
static lang_input_statement_type *lookup_name (const char *);
|
||||||
static struct bfd_hash_entry *lang_definedness_newfunc
|
static struct bfd_hash_entry *lang_definedness_newfunc
|
||||||
|
@ -2047,8 +2048,12 @@ sort_def_symbol (struct bfd_link_hash_entry *hash_entry,
|
||||||
/* Initialize an output section. */
|
/* Initialize an output section. */
|
||||||
|
|
||||||
static void
|
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)
|
if (strcmp (s->name, DISCARD_SECTION_NAME) == 0)
|
||||||
einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME);
|
einfo (_("%P%F: Illegal use of `%s' section\n"), DISCARD_SECTION_NAME);
|
||||||
|
|
||||||
|
@ -2073,6 +2078,14 @@ init_os (lang_output_section_statement_type *s, asection *isec, flagword flags)
|
||||||
get_userdata (s->bfd_section) = new_userdata;
|
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 supplied an alignment, set it. */
|
||||||
if (s->section_alignment != -1)
|
if (s->section_alignment != -1)
|
||||||
s->bfd_section->alignment_power = s->section_alignment;
|
s->bfd_section->alignment_power = s->section_alignment;
|
||||||
|
@ -3417,10 +3430,10 @@ map_input_to_output_sections
|
||||||
(lang_statement_union_type *s, const char *target,
|
(lang_statement_union_type *s, const char *target,
|
||||||
lang_output_section_statement_type *os)
|
lang_output_section_statement_type *os)
|
||||||
{
|
{
|
||||||
|
flagword flags;
|
||||||
|
|
||||||
for (; s != NULL; s = s->header.next)
|
for (; s != NULL; s = s->header.next)
|
||||||
{
|
{
|
||||||
lang_output_section_statement_type *tos;
|
|
||||||
|
|
||||||
switch (s->header.type)
|
switch (s->header.type)
|
||||||
{
|
{
|
||||||
case lang_wild_statement_enum:
|
case lang_wild_statement_enum:
|
||||||
|
@ -3432,23 +3445,29 @@ map_input_to_output_sections
|
||||||
os);
|
os);
|
||||||
break;
|
break;
|
||||||
case lang_output_section_statement_enum:
|
case lang_output_section_statement_enum:
|
||||||
tos = &s->output_section_statement;
|
if (s->output_section_statement.constraint)
|
||||||
if (tos->constraint != 0)
|
|
||||||
{
|
{
|
||||||
if (tos->constraint != ONLY_IF_RW
|
if (s->output_section_statement.constraint != ONLY_IF_RW
|
||||||
&& tos->constraint != ONLY_IF_RO)
|
&& s->output_section_statement.constraint != ONLY_IF_RO)
|
||||||
break;
|
break;
|
||||||
tos->all_input_readonly = TRUE;
|
s->output_section_statement.all_input_readonly = TRUE;
|
||||||
check_input_sections (tos->children.head, tos);
|
check_input_sections (s->output_section_statement.children.head,
|
||||||
if (tos->all_input_readonly != (tos->constraint == ONLY_IF_RO))
|
&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->constraint = -1;
|
s->output_section_statement.constraint = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map_input_to_output_sections (tos->children.head,
|
|
||||||
|
map_input_to_output_sections (s->output_section_statement.children.head,
|
||||||
target,
|
target,
|
||||||
tos);
|
&s->output_section_statement);
|
||||||
|
break;
|
||||||
|
case lang_output_statement_enum:
|
||||||
break;
|
break;
|
||||||
case lang_target_statement_enum:
|
case lang_target_statement_enum:
|
||||||
target = s->target_statement.target;
|
target = s->target_statement.target;
|
||||||
|
@ -3458,102 +3477,19 @@ map_input_to_output_sections
|
||||||
target,
|
target,
|
||||||
os);
|
os);
|
||||||
break;
|
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:
|
case lang_data_statement_enum:
|
||||||
/* Make sure that any sections mentioned in the expression
|
/* Make sure that any sections mentioned in the expression
|
||||||
are initialized. */
|
are initialized. */
|
||||||
exp_init_os (s->data_statement.exp);
|
exp_init_os (s->data_statement.exp);
|
||||||
if (os->bfd_section == NULL)
|
|
||||||
init_os (os, NULL, 0);
|
|
||||||
flags = SEC_HAS_CONTENTS;
|
flags = SEC_HAS_CONTENTS;
|
||||||
/* The output section gets contents, and then we inspect for
|
/* The output section gets contents, and then we inspect for
|
||||||
any flags set in the input script which override any ALLOC. */
|
any flags set in the input script which override any ALLOC. */
|
||||||
if (!(os->flags & SEC_NEVER_LOAD))
|
if (!(os->flags & SEC_NEVER_LOAD))
|
||||||
flags |= SEC_ALLOC | SEC_LOAD;
|
flags |= SEC_ALLOC | SEC_LOAD;
|
||||||
os->bfd_section->flags |= flags;
|
if (os->bfd_section == NULL)
|
||||||
|
init_os (os, NULL, flags);
|
||||||
|
else
|
||||||
|
os->bfd_section->flags |= flags;
|
||||||
break;
|
break;
|
||||||
case lang_input_section_enum:
|
case lang_input_section_enum:
|
||||||
break;
|
break;
|
||||||
|
@ -3574,14 +3510,25 @@ create_other_output_sections
|
||||||
exp_init_os (s->assignment_statement.exp);
|
exp_init_os (s->assignment_statement.exp);
|
||||||
break;
|
break;
|
||||||
case lang_address_statement_enum:
|
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
|
if (!s->address_statement.segment
|
||||||
|| !s->address_statement.segment->used)
|
|| !s->address_statement.segment->used)
|
||||||
{
|
{
|
||||||
const char *name = s->address_statement.section_name;
|
lang_output_section_statement_type *aos
|
||||||
|
= (lang_output_section_statement_lookup
|
||||||
|
(s->address_statement.section_name, 0, TRUE));
|
||||||
|
|
||||||
tos = lang_output_section_find (name);
|
if (aos->bfd_section == NULL)
|
||||||
if (tos->bfd_section == NULL)
|
init_os (aos, NULL, 0);
|
||||||
init_os (tos, NULL, 0);
|
aos->addr_tree = s->address_statement.address;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case lang_insert_statement_enum:
|
case lang_insert_statement_enum:
|
||||||
|
@ -6400,10 +6347,6 @@ lang_process (void)
|
||||||
/* Find any sections not attached explicitly and handle them. */
|
/* Find any sections not attached explicitly and handle them. */
|
||||||
lang_place_orphans ();
|
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)
|
if (! link_info.relocatable)
|
||||||
{
|
{
|
||||||
asection *found;
|
asection *found;
|
||||||
|
|
Loading…
Reference in New Issue