#!/bin/sh -e ## 311_pr5006.dpatch ## ## DP: Description: Fix PR ld/5006 ## DP: Upstream status: CVS head 20070908 if [ $# -ne 1 ]; then echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" exit 1 fi [ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts patch_opts="${patch_opts:--f --no-backup-if-mismatch}" case "$1" in -patch) patch $patch_opts -p1 < $0;; -unpatch) patch $patch_opts -p1 -R < $0;; *) echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" exit 1;; esac exit 0 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 ): Correct condition under which we build a bfd_data_link_order. @DPATCH@ 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;