Summary: | --gc-sections discards .debug_types | ||
---|---|---|---|
Product: | binutils | Reporter: | Jan Kratochvil <jan> |
Component: | ld | Assignee: | Alan Modra <amodra> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | hjl.tools |
Priority: | P2 | ||
Version: | 2.24 | ||
Target Milestone: | --- | ||
Host: | Target: | x86_64-fedora16-linux-gnu | |
Build: | Last reconfirmed: | ||
Bug Depends on: | 13195 | ||
Bug Blocks: |
Description
Jan Kratochvil
2011-09-28 18:40:32 UTC
Testing of this Bug is dependent on PR ld/13195 for --gc-sections. It is caused by http://sourceware.org/ml/binutils/2011-06/msg00175.html Since .debug_types is in a comdat group section, it is discarded by /* Keep debug and special sections like .comment when they are not part of a group. */ for (isec = ibfd->sections; isec != NULL; isec = isec->next) if (elf_next_in_group (isec) == NULL && ((isec->flags & SEC_DEBUGGING) != 0 || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)) isec->gc_mark = 1; This patch --- diff --git a/bfd/elflink.c b/bfd/elflink.c index a15ad27..42d2e97 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -11670,9 +11670,9 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info, /* Keep debug and special sections like .comment when they are not part of a group. */ for (isec = ibfd->sections; isec != NULL; isec = isec->next) - if (elf_next_in_group (isec) == NULL - && ((isec->flags & SEC_DEBUGGING) != 0 - || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)) + if ((isec->flags & SEC_DEBUGGING) != 0 + || (elf_next_in_group (isec) == NULL + && (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)) isec->gc_mark = 1; } return TRUE; --- works for me. I don't see why debug and special sections shouldn't be kept when they are part of a group: diff --git a/bfd/elflink.c b/bfd/elflink.c index a15ad27..6fed561 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -11667,12 +11667,10 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info, if (!some_kept) continue; - /* Keep debug and special sections like .comment when they are - not part of a group. */ + /* Keep debug and special sections like .comment. */ for (isec = ibfd->sections; isec != NULL; isec = isec->next) - if (elf_next_in_group (isec) == NULL - && ((isec->flags & SEC_DEBUGGING) != 0 - || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)) + if ((isec->flags & SEC_DEBUGGING) != 0 + || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0) isec->gc_mark = 1; } return TRUE; Huh, if .debug_types is now made part of a comdat group (when did that happen?), then are you not telling the linker that you want this section to be discarded according to the usual rules for groups? Of course, the linker generally only marks groups as needed when seeing a reference via some relocation from another kept section. Other references like the .debug_info one shown here are not seen. You could call that a bug, but I certainly am not motivated to write the code to process debug sections for --gc-sections! I'd say a) It's a gcc bug to put .debug_types in a single member comdat group since it totally ignores current linker limitations regarding group processing. b) HJ's patch is wrong as it disables a more reasonable use of group sections which would be to put all code, data, *and* debug info for a function into a group. I know there are problems with actually doing that.. It might be reasonable for the linker to keep single-member comdat groups containing just debug info. Jan, does this work for you? Index: bfd/elflink.c =================================================================== RCS file: /cvs/src/src/bfd/elflink.c,v retrieving revision 1.420 diff -u -p -r1.420 elflink.c --- bfd/elflink.c 16 Sep 2011 01:17:16 -0000 1.420 +++ bfd/elflink.c 29 Sep 2011 01:10:38 -0000 @@ -11667,9 +11667,10 @@ _bfd_elf_gc_mark_extra_sections (struct continue; /* Keep debug and special sections like .comment when they are - not part of a group. */ + not part of a group, or when we have single-member groups. */ for (isec = ibfd->sections; isec != NULL; isec = isec->next) - if (elf_next_in_group (isec) == NULL + if ((elf_next_in_group (isec) == NULL + || elf_next_in_group (isec) == isec) && ((isec->flags & SEC_DEBUGGING) != 0 || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)) isec->gc_mark = 1; (In reply to comment #6) > a) It's a gcc bug to put .debug_types in a single member comdat group since it > totally ignores current linker limitations regarding group processing. OK, I agree: COMDAT group section [ 1] `.group' [wt.13f2b295a1b7fce5] contains 1 sections: [Index] Name [ 5] .debug_types > It might be reasonable for the linker to keep single-member comdat groups > containing just debug info. Jan, does this work for you? It fixes the problem for me, thanks. CVSROOT: /cvs/src Module name: src Changes by: amodra@sourceware.org 2011-09-29 05:40:22 Modified files: bfd : ChangeLog elflink.c Log message: PR ld/13233 * elflink.c (_bfd_elf_gc_mark_extra_sections): Mark single member debug and special section groups. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.5475&r2=1.5476 http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elflink.c.diff?cvsroot=src&r1=1.421&r2=1.422 CVSROOT: /cvs/src Module name: src Branch: binutils-2_22-branch Changes by: amodra@sourceware.org 2011-09-29 05:40:45 Modified files: bfd : ChangeLog elflink.c Log message: PR ld/13233 * elflink.c (_bfd_elf_gc_mark_extra_sections): Mark single member debug and special section groups. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&only_with_tag=binutils-2_22-branch&r1=1.5473.2.1&r2=1.5473.2.2 http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elflink.c.diff?cvsroot=src&only_with_tag=binutils-2_22-branch&r1=1.420&r2=1.420.2.1 patch applied |