Index: src/bfd/coffcode.h =================================================================== --- src.orig/bfd/coffcode.h 2010-09-02 10:37:25.000000000 +0200 +++ src/bfd/coffcode.h 2010-09-22 10:32:14.982051600 +0200 @@ -636,6 +636,14 @@ static long sec_to_styp_flags (const char *sec_name, flagword sec_flags) { long styp_flags = 0; + bfd_boolean is_dbg = FALSE; + + if (CONST_STRNEQ (sec_name, DOT_DEBUG) +#ifdef COFF_LONG_SECTION_NAMES + || CONST_STRNEQ (sec_name, GNU_LINKONCE_WI) +#endif + || CONST_STRNEQ (sec_name, ".stab")) + is_dbg = TRUE; /* caution: there are at least three groups of symbols that have very similar bits and meanings: IMAGE_SCN*, SEC_*, and STYP_*. @@ -646,16 +654,15 @@ sec_to_styp_flags (const char *sec_name, but there are more IMAGE_SCN_* flags. */ /* FIXME: There is no gas syntax to specify the debug section flag. */ - if (CONST_STRNEQ (sec_name, DOT_DEBUG) - || CONST_STRNEQ (sec_name, GNU_LINKONCE_WI)) - sec_flags = SEC_DEBUGGING | SEC_READONLY; + if (is_dbg) + sec_flags = SEC_DEBUGGING | SEC_READONLY; /* skip LOAD */ /* READONLY later */ /* skip RELOC */ if ((sec_flags & SEC_CODE) != 0) styp_flags |= IMAGE_SCN_CNT_CODE; - if ((sec_flags & SEC_DATA) != 0) + if ((sec_flags & (SEC_DATA | SEC_DEBUGGING)) != 0) styp_flags |= IMAGE_SCN_CNT_INITIALIZED_DATA; if ((sec_flags & SEC_ALLOC) != 0 && (sec_flags & SEC_LOAD) == 0) styp_flags |= IMAGE_SCN_CNT_UNINITIALIZED_DATA; /* ==STYP_BSS */ @@ -666,9 +673,9 @@ sec_to_styp_flags (const char *sec_name, styp_flags |= IMAGE_SCN_LNK_COMDAT; if ((sec_flags & SEC_DEBUGGING) != 0) styp_flags |= IMAGE_SCN_MEM_DISCARDABLE; - if ((sec_flags & SEC_EXCLUDE) != 0) + if ((sec_flags & SEC_EXCLUDE) != 0 && !is_dbg) styp_flags |= IMAGE_SCN_LNK_REMOVE; - if ((sec_flags & SEC_NEVER_LOAD) != 0) + if ((sec_flags & SEC_NEVER_LOAD) != 0 && !is_dbg) styp_flags |= IMAGE_SCN_LNK_REMOVE; /* skip IN_MEMORY */ /* skip SORT */ @@ -1120,7 +1127,14 @@ styp_to_sec_flags (bfd *abfd, long styp_flags = internal_s->s_flags; flagword sec_flags; bfd_boolean result = TRUE; + bfd_boolean is_dbg = FALSE; + if (CONST_STRNEQ (name, DOT_DEBUG) +#ifdef COFF_LONG_SECTION_NAMES + || CONST_STRNEQ (name, GNU_LINKONCE_WI) +#endif + || CONST_STRNEQ (name, ".stab")) + is_dbg = TRUE; /* Assume read only unless IMAGE_SCN_MEM_WRITE is specified. */ sec_flags = SEC_READONLY; @@ -1190,27 +1204,30 @@ styp_to_sec_flags (bfd *abfd, mean that a given section contains debug information. Thus we only set the SEC_DEBUGGING flag on sections that we recognise as containing debug information. */ - if (CONST_STRNEQ (name, DOT_DEBUG) + if (is_dbg #ifdef _COMMENT || strcmp (name, _COMMENT) == 0 #endif -#ifdef COFF_LONG_SECTION_NAMES - || CONST_STRNEQ (name, GNU_LINKONCE_WI) -#endif - || CONST_STRNEQ (name, ".stab")) - sec_flags |= SEC_DEBUGGING; + ) + { + sec_flags |= SEC_DEBUGGING | SEC_READONLY; + } break; case IMAGE_SCN_MEM_SHARED: sec_flags |= SEC_COFF_SHARED; break; case IMAGE_SCN_LNK_REMOVE: - sec_flags |= SEC_EXCLUDE; + if (!is_dbg) + sec_flags |= SEC_EXCLUDE; break; case IMAGE_SCN_CNT_CODE: sec_flags |= SEC_CODE | SEC_ALLOC | SEC_LOAD; break; case IMAGE_SCN_CNT_INITIALIZED_DATA: - sec_flags |= SEC_DATA | SEC_ALLOC | SEC_LOAD; + if (is_dbg) + sec_flags |= SEC_DEBUGGING; + else + sec_flags |= SEC_DATA | SEC_ALLOC | SEC_LOAD; break; case IMAGE_SCN_CNT_UNINITIALIZED_DATA: sec_flags |= SEC_ALLOC; Index: src/ld/ldlang.c =================================================================== --- src.orig/ld/ldlang.c 2010-09-20 11:18:14.000000000 +0200 +++ src/ld/ldlang.c 2010-09-22 14:06:07.290815400 +0200 @@ -2245,7 +2245,15 @@ lang_add_section (lang_statement_list_ty case noload_section: flags &= ~SEC_LOAD; flags |= SEC_NEVER_LOAD; - if ((flags & SEC_COFF_SHARED_LIBRARY) == 0) + if (((bfd_get_flavour (section->owner) + == bfd_target_ecoff_flavour) + || (bfd_get_flavour (section->owner) + == bfd_target_coff_flavour))) + { + if ((flags & (SEC_COFF_SHARED_LIBRARY | SEC_DEBUGGING)) == 0) + flags &= ~SEC_HAS_CONTENTS; + } + else flags &= ~SEC_HAS_CONTENTS; break; } @@ -4555,8 +4563,11 @@ sort_sections_by_lma (const void *arg1, return 0; } +/* On ELF, a debugging section has not to set SEC_NEVER_LOAD, as no output + would be written for it. So the combination of debugging and never-load + is something what can just happen for pe-coff and has not to be ignored. */ #define IGNORE_SECTION(s) \ - ((s->flags & SEC_NEVER_LOAD) != 0 \ + ((s->flags & (SEC_NEVER_LOAD | SEC_DEBUGGING)) == SEC_NEVER_LOAD \ || (s->flags & SEC_ALLOC) == 0 \ || ((s->flags & SEC_THREAD_LOCAL) != 0 \ && (s->flags & SEC_LOAD) == 0)) @@ -4590,7 +4601,7 @@ lang_check_section_addresses (void) for (s = link_info.output_bfd->sections; s != NULL; s = s->next) { /* Only consider loadable sections with real contents. */ - if ((s->flags & SEC_NEVER_LOAD) + if ((s->flags & (SEC_NEVER_LOAD | SEC_DEBUGGING)) == SEC_NEVER_LOAD || !(s->flags & SEC_LOAD) || !(s->flags & SEC_ALLOC) || s->size == 0) Index: src/ld/ldwrite.c =================================================================== --- src.orig/ld/ldwrite.c 2010-09-20 11:18:14.000000000 +0200 +++ src/ld/ldwrite.c 2010-09-22 10:24:39.327744500 +0200 @@ -245,7 +245,8 @@ build_link_order (lang_statement_union_t link_order = bfd_new_link_order (link_info.output_bfd, output_section); - if (i->flags & SEC_NEVER_LOAD) + if ((i->flags & SEC_NEVER_LOAD) != 0 + && (i->flags & SEC_DEBUGGING) == 0) { /* We've got a never load section inside one which is going to be output, we'll change it into a