mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-23 02:51:56 +00:00
bfd/
PR ld/11304 * elf.c (_bfd_elf_init_private_section_data): Rename need_group to final_link and invert. For final link allow some flags to differ. Don't specially allow flags to be all zero. ld/ * ldlang.c (init_os): Remove isec param. Don't check for bfd_section already set or call bfd_init_private_section_data here. (exp_init_os): Update init_os call. (lang_add_section): Tidy. Really don't set SEC_LINK_ONCE flags. Call bfd_init_private_section_data here. (map_input_to_output_sections): Tidy. Update init_os calls. Use os->sectype to select sec flags for lang_data_statement.
This commit is contained in:
parent
63d0fa4e9e
commit
dfa7b0b817
@ -1,3 +1,10 @@
|
||||
2010-02-25 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR ld/11304
|
||||
* elf.c (_bfd_elf_init_private_section_data): Rename need_group
|
||||
to final_link and invert. For final link allow some flags to
|
||||
differ. Don't specially allow flags to be all zero.
|
||||
|
||||
2010-02-24 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR binutils/10858
|
||||
|
17
bfd/elf.c
17
bfd/elf.c
@ -6056,18 +6056,21 @@ _bfd_elf_init_private_section_data (bfd *ibfd,
|
||||
|
||||
{
|
||||
Elf_Internal_Shdr *ihdr, *ohdr;
|
||||
bfd_boolean need_group = link_info == NULL || link_info->relocatable;
|
||||
bfd_boolean final_link = link_info != NULL && !link_info->relocatable;
|
||||
|
||||
if (ibfd->xvec->flavour != bfd_target_elf_flavour
|
||||
|| obfd->xvec->flavour != bfd_target_elf_flavour)
|
||||
return TRUE;
|
||||
|
||||
/* Don't copy the output ELF section type from input if the
|
||||
output BFD section flags have been set to something different.
|
||||
elf_fake_sections will set ELF section type based on BFD
|
||||
section flags. */
|
||||
/* For objcopy and relocatable link, don't copy the output ELF
|
||||
section type from input if the output BFD section flags have been
|
||||
set to something different. For a final link allow some flags
|
||||
that the linker clears to differ. */
|
||||
if (elf_section_type (osec) == SHT_NULL
|
||||
&& (osec->flags == isec->flags || !osec->flags))
|
||||
&& (osec->flags == isec->flags
|
||||
|| (final_link
|
||||
&& ((osec->flags ^ isec->flags)
|
||||
& ~ (SEC_LINK_ONCE | SEC_LINK_DUPLICATES)) == 0)))
|
||||
elf_section_type (osec) = elf_section_type (isec);
|
||||
|
||||
/* FIXME: Is this correct for all OS/PROC specific flags? */
|
||||
@ -6078,7 +6081,7 @@ _bfd_elf_init_private_section_data (bfd *ibfd,
|
||||
SHT_GROUP section will have its elf_next_in_group pointing back
|
||||
to the input group members. Ignore linker created group section.
|
||||
See elfNN_ia64_object_p in elfxx-ia64.c. */
|
||||
if (need_group)
|
||||
if (!final_link)
|
||||
{
|
||||
if (elf_sec_group (isec) == NULL
|
||||
|| (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0)
|
||||
|
12
ld/ChangeLog
12
ld/ChangeLog
@ -1,3 +1,15 @@
|
||||
2010-02-25 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR ld/11304
|
||||
* ldlang.c (init_os): Remove isec param. Don't check for
|
||||
bfd_section already set or call bfd_init_private_section_data
|
||||
here.
|
||||
(exp_init_os): Update init_os call.
|
||||
(lang_add_section): Tidy. Really don't set SEC_LINK_ONCE
|
||||
flags. Call bfd_init_private_section_data here.
|
||||
(map_input_to_output_sections): Tidy. Update init_os calls.
|
||||
Use os->sectype to select sec flags for lang_data_statement.
|
||||
|
||||
2010-02-23 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR ld/11304
|
||||
|
266
ld/ldlang.c
266
ld/ldlang.c
@ -2048,12 +2048,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, 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);
|
||||
|
||||
@ -2089,11 +2085,6 @@ init_os (lang_output_section_statement_type *s, asection *isec,
|
||||
/* If supplied an alignment, set it. */
|
||||
if (s->section_alignment != -1)
|
||||
s->bfd_section->alignment_power = s->section_alignment;
|
||||
|
||||
if (isec)
|
||||
bfd_init_private_section_data (isec->owner, isec,
|
||||
link_info.output_bfd, s->bfd_section,
|
||||
&link_info);
|
||||
}
|
||||
|
||||
/* Make sure that all output sections mentioned in an expression are
|
||||
@ -2139,7 +2130,7 @@ exp_init_os (etree_type *exp)
|
||||
|
||||
os = lang_output_section_find (exp->name.name);
|
||||
if (os != NULL && os->bfd_section == NULL)
|
||||
init_os (os, NULL, 0);
|
||||
init_os (os, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -2183,6 +2174,7 @@ lang_add_section (lang_statement_list_type *ptr,
|
||||
{
|
||||
flagword flags = section->flags;
|
||||
bfd_boolean discard;
|
||||
lang_input_section_type *new_section;
|
||||
|
||||
/* Discard sections marked with SEC_EXCLUDE. */
|
||||
discard = (flags & SEC_EXCLUDE) != 0;
|
||||
@ -2208,109 +2200,105 @@ lang_add_section (lang_statement_list_type *ptr,
|
||||
return;
|
||||
}
|
||||
|
||||
if (section->output_section == NULL)
|
||||
if (section->output_section != NULL)
|
||||
return;
|
||||
|
||||
/* We don't copy the SEC_NEVER_LOAD flag from an input section
|
||||
to an output section, because we want to be able to include a
|
||||
SEC_NEVER_LOAD section in the middle of an otherwise loaded
|
||||
section (I don't know why we want to do this, but we do).
|
||||
build_link_order in ldwrite.c handles this case by turning
|
||||
the embedded SEC_NEVER_LOAD section into a fill. */
|
||||
flags &= ~ SEC_NEVER_LOAD;
|
||||
|
||||
/* If final link, don't copy the SEC_LINK_ONCE flags, they've
|
||||
already been processed. One reason to do this is that on pe
|
||||
format targets, .text$foo sections go into .text and it's odd
|
||||
to see .text with SEC_LINK_ONCE set. */
|
||||
|
||||
if (!link_info.relocatable)
|
||||
flags &= ~ (SEC_LINK_ONCE | SEC_LINK_DUPLICATES);
|
||||
|
||||
switch (output->sectype)
|
||||
{
|
||||
bfd_boolean first;
|
||||
lang_input_section_type *new_section;
|
||||
case normal_section:
|
||||
case overlay_section:
|
||||
break;
|
||||
case noalloc_section:
|
||||
flags &= ~SEC_ALLOC;
|
||||
break;
|
||||
case noload_section:
|
||||
flags &= ~SEC_LOAD;
|
||||
flags |= SEC_NEVER_LOAD;
|
||||
break;
|
||||
}
|
||||
|
||||
/* We don't copy the SEC_NEVER_LOAD flag from an input section
|
||||
to an output section, because we want to be able to include a
|
||||
SEC_NEVER_LOAD section in the middle of an otherwise loaded
|
||||
section (I don't know why we want to do this, but we do).
|
||||
build_link_order in ldwrite.c handles this case by turning
|
||||
the embedded SEC_NEVER_LOAD section into a fill. */
|
||||
flags &= ~ SEC_NEVER_LOAD;
|
||||
if (output->bfd_section == NULL)
|
||||
init_os (output, flags);
|
||||
|
||||
switch (output->sectype)
|
||||
{
|
||||
case normal_section:
|
||||
case overlay_section:
|
||||
break;
|
||||
case noalloc_section:
|
||||
flags &= ~SEC_ALLOC;
|
||||
break;
|
||||
case noload_section:
|
||||
flags &= ~SEC_LOAD;
|
||||
flags |= SEC_NEVER_LOAD;
|
||||
break;
|
||||
}
|
||||
/* If SEC_READONLY is not set in the input section, then clear
|
||||
it from the output section. */
|
||||
output->bfd_section->flags &= flags | ~SEC_READONLY;
|
||||
|
||||
if (output->bfd_section == NULL)
|
||||
init_os (output, section, flags);
|
||||
|
||||
first = ! output->bfd_section->linker_has_input;
|
||||
output->bfd_section->linker_has_input = 1;
|
||||
|
||||
if (!link_info.relocatable
|
||||
&& !stripped_excluded_sections)
|
||||
{
|
||||
asection *s = output->bfd_section->map_tail.s;
|
||||
output->bfd_section->map_tail.s = section;
|
||||
section->map_head.s = NULL;
|
||||
section->map_tail.s = s;
|
||||
if (s != NULL)
|
||||
s->map_head.s = section;
|
||||
else
|
||||
output->bfd_section->map_head.s = section;
|
||||
}
|
||||
|
||||
/* Add a section reference to the list. */
|
||||
new_section = new_stat (lang_input_section, ptr);
|
||||
|
||||
new_section->section = section;
|
||||
section->output_section = output->bfd_section;
|
||||
|
||||
/* If final link, don't copy the SEC_LINK_ONCE flags, they've
|
||||
already been processed. One reason to do this is that on pe
|
||||
format targets, .text$foo sections go into .text and it's odd
|
||||
to see .text with SEC_LINK_ONCE set. */
|
||||
|
||||
if (! link_info.relocatable)
|
||||
flags &= ~ (SEC_LINK_ONCE | SEC_LINK_DUPLICATES);
|
||||
|
||||
/* If this is not the first input section, and the SEC_READONLY
|
||||
flag is not currently set, then don't set it just because the
|
||||
input section has it set. */
|
||||
|
||||
if (! first && (output->bfd_section->flags & SEC_READONLY) == 0)
|
||||
flags &= ~ SEC_READONLY;
|
||||
if (output->bfd_section->linker_has_input)
|
||||
{
|
||||
/* Only set SEC_READONLY flag on the first input section. */
|
||||
flags &= ~ SEC_READONLY;
|
||||
|
||||
/* Keep SEC_MERGE and SEC_STRINGS only if they are the same. */
|
||||
if (! first
|
||||
&& ((output->bfd_section->flags & (SEC_MERGE | SEC_STRINGS))
|
||||
!= (flags & (SEC_MERGE | SEC_STRINGS))
|
||||
|| ((flags & SEC_MERGE)
|
||||
&& output->bfd_section->entsize != section->entsize)))
|
||||
if ((output->bfd_section->flags & (SEC_MERGE | SEC_STRINGS))
|
||||
!= (flags & (SEC_MERGE | SEC_STRINGS))
|
||||
|| ((flags & SEC_MERGE) != 0
|
||||
&& output->bfd_section->entsize != section->entsize))
|
||||
{
|
||||
output->bfd_section->flags &= ~ (SEC_MERGE | SEC_STRINGS);
|
||||
flags &= ~ (SEC_MERGE | SEC_STRINGS);
|
||||
}
|
||||
|
||||
output->bfd_section->flags |= flags;
|
||||
|
||||
if (flags & SEC_MERGE)
|
||||
output->bfd_section->entsize = section->entsize;
|
||||
|
||||
/* If SEC_READONLY is not set in the input section, then clear
|
||||
it from the output section. */
|
||||
if ((section->flags & SEC_READONLY) == 0)
|
||||
output->bfd_section->flags &= ~SEC_READONLY;
|
||||
|
||||
/* Copy over SEC_SMALL_DATA. */
|
||||
if (section->flags & SEC_SMALL_DATA)
|
||||
output->bfd_section->flags |= SEC_SMALL_DATA;
|
||||
|
||||
if (section->alignment_power > output->bfd_section->alignment_power)
|
||||
output->bfd_section->alignment_power = section->alignment_power;
|
||||
|
||||
if (bfd_get_arch (section->owner) == bfd_arch_tic54x
|
||||
&& (section->flags & SEC_TIC54X_BLOCK) != 0)
|
||||
{
|
||||
output->bfd_section->flags |= SEC_TIC54X_BLOCK;
|
||||
/* FIXME: This value should really be obtained from the bfd... */
|
||||
output->block_value = 128;
|
||||
}
|
||||
}
|
||||
output->bfd_section->flags |= flags;
|
||||
|
||||
if (!output->bfd_section->linker_has_input)
|
||||
{
|
||||
output->bfd_section->linker_has_input = 1;
|
||||
/* This must happen after flags have been updated. The output
|
||||
section may have been created before we saw its first input
|
||||
section, eg. for a data statement. */
|
||||
bfd_init_private_section_data (section->owner, section,
|
||||
link_info.output_bfd,
|
||||
output->bfd_section,
|
||||
&link_info);
|
||||
if ((flags & SEC_MERGE) != 0)
|
||||
output->bfd_section->entsize = section->entsize;
|
||||
}
|
||||
|
||||
if ((flags & SEC_TIC54X_BLOCK) != 0
|
||||
&& bfd_get_arch (section->owner) == bfd_arch_tic54x)
|
||||
{
|
||||
/* FIXME: This value should really be obtained from the bfd... */
|
||||
output->block_value = 128;
|
||||
}
|
||||
|
||||
if (section->alignment_power > output->bfd_section->alignment_power)
|
||||
output->bfd_section->alignment_power = section->alignment_power;
|
||||
|
||||
section->output_section = output->bfd_section;
|
||||
|
||||
if (!link_info.relocatable
|
||||
&& !stripped_excluded_sections)
|
||||
{
|
||||
asection *s = output->bfd_section->map_tail.s;
|
||||
output->bfd_section->map_tail.s = section;
|
||||
section->map_head.s = NULL;
|
||||
section->map_tail.s = s;
|
||||
if (s != NULL)
|
||||
s->map_head.s = section;
|
||||
else
|
||||
output->bfd_section->map_head.s = section;
|
||||
}
|
||||
|
||||
/* Add a section reference to the list. */
|
||||
new_section = new_stat (lang_input_section, ptr);
|
||||
new_section->section = section;
|
||||
}
|
||||
|
||||
/* Handle wildcard sorting. This returns the lang_input_section which
|
||||
@ -3430,10 +3418,11 @@ 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;
|
||||
flagword flags;
|
||||
|
||||
switch (s->header.type)
|
||||
{
|
||||
case lang_wild_statement_enum:
|
||||
@ -3445,27 +3434,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);
|
||||
tos);
|
||||
break;
|
||||
case lang_output_statement_enum:
|
||||
break;
|
||||
@ -3481,13 +3466,23 @@ map_input_to_output_sections
|
||||
/* Make sure that any sections mentioned in the expression
|
||||
are initialized. */
|
||||
exp_init_os (s->data_statement.exp);
|
||||
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;
|
||||
/* The output section gets CONTENTS, and usually ALLOC and
|
||||
LOAD, but the latter two may be overridden by the script. */
|
||||
flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD;
|
||||
switch (os->sectype)
|
||||
{
|
||||
case normal_section:
|
||||
case overlay_section:
|
||||
break;
|
||||
case noalloc_section:
|
||||
flags = SEC_HAS_CONTENTS;
|
||||
break;
|
||||
case noload_section:
|
||||
flags = SEC_HAS_CONTENTS | SEC_NEVER_LOAD;
|
||||
break;
|
||||
}
|
||||
if (os->bfd_section == NULL)
|
||||
init_os (os, NULL, flags);
|
||||
init_os (os, flags);
|
||||
else
|
||||
os->bfd_section->flags |= flags;
|
||||
break;
|
||||
@ -3499,11 +3494,11 @@ map_input_to_output_sections
|
||||
case lang_padding_statement_enum:
|
||||
case lang_input_statement_enum:
|
||||
if (os != NULL && os->bfd_section == NULL)
|
||||
init_os (os, NULL, 0);
|
||||
init_os (os, 0);
|
||||
break;
|
||||
case lang_assignment_statement_enum:
|
||||
if (os != NULL && os->bfd_section == NULL)
|
||||
init_os (os, NULL, 0);
|
||||
init_os (os, 0);
|
||||
|
||||
/* Make sure that any sections mentioned in the assignment
|
||||
are initialized. */
|
||||
@ -3522,13 +3517,18 @@ map_input_to_output_sections
|
||||
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;
|
||||
/* Create the output section statement here 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;
|
||||
if (tos->bfd_section == NULL)
|
||||
init_os (tos, 0);
|
||||
}
|
||||
break;
|
||||
case lang_insert_statement_enum:
|
||||
|
Loading…
x
Reference in New Issue
Block a user