--- /dev/null
+#!/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 <lang_padding_statement_enum>): 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;
+