Bug 833355

Summary: -gc-sections ignores KEEP annotations
Product: [Fedora] Fedora Reporter: Enrico Scholz <rh-bugzilla>
Component: binutilsAssignee: Nick Clifton <nickc>
Status: CLOSED CURRENTRELEASE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 17CC: jakub, nickc
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2012-08-14 09:45:20 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Enrico Scholz 2012-06-19 09:49:20 UTC
[copy of http://sourceware.org/bugzilla/show_bug.cgi?id=14265]

Description of problem:

sections which are marked with KEEP() in a linker file will be removed
when -gc-sections is specified.  Old bfd linker kept them as expected.

In the sample below, it is expected that:

* __foo0_start == __foo0_end   (can be optimized way)

* __foo1_start < __foo1_end

* __foo2_end - __foo2_start == __foo1_end - __foo1_start


The last two expectations hold with bfd linker but not with gold.



--- x2.ld ---
SECTIONS
{
    .text : { *(.text) }

    __foo0_start = .;
    .foo0 : { *(.foo0.*) }
    __foo0_end = .;

    __foo1_start = .;
    .foo1 : { KEEP(*(.foo1.*)) }
    __foo1_end = .;

    .foo2 : {
        __foo2_start = .;
        KEEP(*(.foo2.*))
        __foo2_end = .;
    }
}


--- x2.c ---
int foo0 __attribute__((used,section(".foo0.0")));
int foo1 __attribute__((used,section(".foo1.0")));
int foo2 __attribute__((used,section(".foo2.0")));

extern unsigned long    __foo0_start;
extern unsigned long    __foo0_end;

extern unsigned long    __foo1_start;
extern unsigned long    __foo1_end;

extern unsigned long    __foo2_start;
extern unsigned long    __foo2_end;

int main() {
    return ((__foo0_end - __foo0_start) -
        (__foo1_end - __foo1_start) -
        (__foo2_end - __foo2_start));
}


-----

$ gcc -c x2.c
$ ld.gold -gc-sections -T x2.ld x2.o -o /tmp/x2-gold
$ ld.bfd  -gc-sections -T x2.ld x2.o -o /tmp/x2-bfd

$ readelf -s /tmp/x2-bfd /tmp/x2-gold

File: /tmp/x2-bfd

Symbol table '.symtab' contains 13 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     2: 0000000000000004     0 SECTION LOCAL  DEFAULT    2 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS x2.c
     5: 0000000000000004     0 NOTYPE  LOCAL  DEFAULT    2 __foo2_start
     6: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  ABS __foo1_start
     7: 0000000000000008     0 NOTYPE  LOCAL  DEFAULT    2 __foo2_end
     8: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  ABS __foo0_start
     9: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  ABS __foo0_end
    10: 0000000000000004     0 NOTYPE  LOCAL  DEFAULT  ABS __foo1_end
    11: 0000000000000004     4 OBJECT  GLOBAL DEFAULT    2 foo2
    12: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    1 foo1

File: /tmp/x2-gold

Symbol table '.symtab' contains 9 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS x2.c
     2: 0000000000000000    76 FUNC    GLOBAL DEFAULT    1 main
     3: 0000000000000090     0 NOTYPE  GLOBAL DEFAULT  ABS __foo0_end
     4: 0000000000000090     0 NOTYPE  GLOBAL DEFAULT  ABS __foo0_start
     5: 0000000000000090     0 NOTYPE  GLOBAL DEFAULT  ABS __foo1_start
     6: 0000000000000090     0 NOTYPE  GLOBAL DEFAULT  ABS __foo1_end
     7: 0000000000000090     0 NOTYPE  GLOBAL DEFAULT  ABS __foo2_start
     8: 00000000000000dc     0 NOTYPE  GLOBAL DEFAULT  ABS __foo2_end


$ ld.gold --version
GNU gold (version 2.22.52.0.1-10.fc17 20120131) 1.11

$ ld.bfd --version
GNU ld version 2.22.52.0.1-10.fc17 20120131


Version-Release number of selected component (if applicable):
binutils-2.22.52.0.1-10.fc17.x86_64

How reproducible:
100%

Comment 1 Nick Clifton 2012-08-14 09:45:20 UTC
This bug has now been fixed in the mainline FSF sources.  The patch from there has been imported into Fedora and is now available in:

  binutils-2.22.52.0.1-12.fc17 
  binutils-2.23.51.0.1-2.fc18 
  binutils-2.23.51.0.1-2.fc19 

Cheers
  Nick