This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: ld 2.18 --gc-sections bug? (with testcase)
This one turns out to be nothing to do with --gc-sections, but a
rather more serious bug. If an input section with contents is linked
in to a bss output section, the ELF linker currently leaves the output
section as NOBITS. File space is thus not allocated for the output
section, but a number of places write to the file regardless,
typically trashing the symbol table, string table, or debug sections.
bfd/
PR ld/2864, ld/5006
* elf.c (special_sections): Comment typo.
(elf_fake_sections): Force SHT_PROGBITS for sections that are
SHT_NOBITS if BFD section flags say they have contents.
ld/
* ldwrite.c (build_link_order <lang_padding_statement_enum>): Correct
condition under which we build a bfd_data_link_order.
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.413
diff -u -p -r1.413 elf.c
--- bfd/elf.c 25 Aug 2007 13:20:41 -0000 1.413
+++ bfd/elf.c 8 Sep 2007 08:07:42 -0000
@@ -2084,7 +2084,7 @@ static const struct bfd_elf_special_sect
static const struct bfd_elf_special_section *special_sections[] =
{
special_sections_b, /* 'b' */
- special_sections_c, /* 'b' */
+ special_sections_c, /* 'c' */
special_sections_d, /* 'd' */
NULL, /* 'e' */
special_sections_f, /* 'f' */
@@ -2475,16 +2475,28 @@ elf_fake_sections (bfd *abfd, asection *
/* If the section type is unspecified, we set it based on
asect->flags. */
+ if ((asect->flags & SEC_GROUP) != 0)
+ sh_type = SHT_GROUP;
+ else if ((asect->flags & SEC_ALLOC) != 0
+ && (((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
+ || (asect->flags & SEC_NEVER_LOAD) != 0))
+ sh_type = SHT_NOBITS;
+ else
+ sh_type = SHT_PROGBITS;
+
if (this_hdr->sh_type == SHT_NULL)
- {
- if ((asect->flags & SEC_GROUP) != 0)
- this_hdr->sh_type = SHT_GROUP;
- else if ((asect->flags & SEC_ALLOC) != 0
- && (((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
- || (asect->flags & SEC_NEVER_LOAD) != 0))
- this_hdr->sh_type = SHT_NOBITS;
- else
- this_hdr->sh_type = SHT_PROGBITS;
+ this_hdr->sh_type = sh_type;
+ else if (this_hdr->sh_type == SHT_NOBITS
+ && sh_type == SHT_PROGBITS
+ && (asect->flags & SEC_ALLOC) != 0)
+ {
+ /* Warn if we are changing a NOBITS section to PROGBITS, but
+ allow the link to proceed. This can happen when users link
+ non-bss input sections to bss output sections, or emit data
+ to a bss output section via a linker script. */
+ (*_bfd_error_handler)
+ (_("section `%A' type changed to PROGBITS"), asect);
+ this_hdr->sh_type = sh_type;
}
switch (this_hdr->sh_type)
Index: ld/ldwrite.c
===================================================================
RCS file: /cvs/src/src/ld/ldwrite.c,v
retrieving revision 1.26
diff -u -p -r1.26 ldwrite.c
--- ld/ldwrite.c 6 Jul 2007 14:09:41 -0000 1.26
+++ ld/ldwrite.c 8 Sep 2007 08:08:37 -0000
@@ -270,7 +270,10 @@ build_link_order (lang_statement_union_t
output_section = statement->padding_statement.output_section;
ASSERT (statement->padding_statement.output_section->owner
== output_bfd);
- if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
+ if (((output_section->flags & SEC_HAS_CONTENTS) != 0
+ || ((output_section->flags & SEC_LOAD) != 0
+ && (output_section->flags & SEC_THREAD_LOCAL)))
+ && (output_section->flags & SEC_NEVER_LOAD) == 0)
{
link_order = bfd_new_link_order (output_bfd, output_section);
link_order->type = bfd_data_link_order;
--
Alan Modra
Australia Development Lab, IBM