bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug gold/17704] icf doesn't respect section alignment


From: roland at gnu dot org
Subject: [Bug gold/17704] icf doesn't respect section alignment
Date: Fri, 15 Jan 2016 20:41:26 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=17704

Roland McGrath <roland at gnu dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
                 CC|                            |roland at gnu dot org

--- Comment #1 from Roland McGrath <roland at gnu dot org> ---
This issue has actually bitten in the Chromium build:
https://code.google.com/p/chromium/issues/detail?id=576197

I produced another minimal test case for it before finding this existing
bug report.  I'll show it here just in case it's helpful.

        ==> icf-first.cc <==
        class A {
        public:
          void direct_member_function();
          virtual void virtual_member_function();
        };

        int extra_function() { return 1; }
        void plain_function(A* obj) {}

        ==> icf.cc <==
        class A {
        public:
          void direct_member_function();
          virtual void virtual_member_function();
        };

        extern void plain_function(A*);

        __attribute__((noinline)) void A::direct_member_function() {}

        __attribute__((noinline)) void A::virtual_member_function() {}

        __attribute__((noinline)) void call_A_method(A* receiver, void
(A::*method)()) {
          (receiver->*method)();
        }

        int main(int argc, char** argv) {
          A a;

          if (argc == 1) {
            call_A_method(&a, &A::direct_member_function);
          } else if (argc == 2) {
            call_A_method(&a, &A::virtual_member_function);
          } else {
            plain_function(&a);
          }

          return 0;
        }
        $ g++ -Os -c -ffunction-sections icf-first.cc icf.cc
        $ g++ -Os -fuse-ld=gold -Wl,--icf=all,--print-icf-sections -o icf
icf-first.o icf.o
        ld.gold: ICF Converged after 2 iteration(s)
        ld.gold: ICF folding section '.text' in file 'icf-first.o' into '.text'
in file '/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crti.o'
        ld.gold: ICF folding section '.text' in file 'icf.o' into '.text' in
file '/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crti.o'
        ld.gold: ICF folding section '.text._ZN1A22direct_member_functionEv' in
file 'icf.o' into '.text._Z14plain_functionP1A' in file 'icf-first.o'
        ld.gold: ICF folding section '.text._ZN1A23virtual_member_functionEv'
in file 'icf.o' into '.text._Z14plain_functionP1A' in file 'icf-first.o'
        ld.gold: ICF folding section '.text' in file
'/usr/lib/gcc/x86_64-linux-gnu/4.8/crtend.o' into '.text' in file
'/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crti.o'
        ld.gold: ICF folding section '.text' in file
'/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crtn.o' into
'.text' in file
'/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crti.o'
        $ ./icf 1; echo $?
        0
        $ ./icf 1 2; echo $?
        0
        $ ./icf; echo $?
        Segmentation fault (core dumped)
        139
        $ readelf -WS icf-first.o icf.o

        File: icf-first.o
        There are 13 section headers, starting at offset 0x148:

        Section Headers:
          [Nr] Name              Type            Address          Off    Size  
ES Flg Lk Inf Al
          [ 0]                   NULL            0000000000000000 000000 000000
00      0   0  0
          [ 1] .text             PROGBITS        0000000000000000 000040 000000
00  AX  0   0  1
          [ 2] .data             PROGBITS        0000000000000000 000040 000000
00  WA  0   0  1
          [ 3] .bss              NOBITS          0000000000000000 000040 000000
00  WA  0   0  1
          [ 4] .text._Z14extra_functionv PROGBITS        0000000000000000
000040 000006 00  AX  0   0  1
          [ 5] .text._Z14plain_functionP1A PROGBITS        0000000000000000
000046 000001 00  AX  0   0  1
          [ 6] .comment          PROGBITS        0000000000000000 000047 00002a
01  MS  0   0  1
          [ 7] .note.GNU-stack   PROGBITS        0000000000000000 000071 000000
00      0   0  1
          [ 8] .eh_frame         PROGBITS        0000000000000000 000078 000040
00   A  0   0  8
          [ 9] .rela.eh_frame    RELA            0000000000000000 0005e0 000030
18     11   8  8
          [10] .shstrtab         STRTAB          0000000000000000 0000b8 00008a
00      0   0  1
          [11] .symtab           SYMTAB          0000000000000000 000488 000120
18     12  10  8
          [12] .strtab           STRTAB          0000000000000000 0005a8 000038
00      0   0  1
        Key to Flags:
          W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
          I (info), L (link order), G (group), T (TLS), E (exclude), x
(unknown)
          O (extra OS processing required) o (OS specific), p (processor
specific)

        File: icf.o
        There are 24 section headers, starting at offset 0x2a8:

        Section Headers:
          [Nr] Name              Type            Address          Off    Size  
ES Flg Lk Inf Al
          [ 0]                   NULL            0000000000000000 000000 000000
00      0   0  0
          [ 1] .group            GROUP           0000000000000000 000040 000008
04     22  24  4
          [ 2] .group            GROUP           0000000000000000 000048 000008
04     22  25  4
          [ 3] .group            GROUP           0000000000000000 000050 000008
04     22  22  4
          [ 4] .text             PROGBITS        0000000000000000 000058 000000
00  AX  0   0  1
          [ 5] .data             PROGBITS        0000000000000000 000058 000000
00  WA  0   0  1
          [ 6] .bss              NOBITS          0000000000000000 000058 000000
00  WA  0   0  1
          [ 7] .text._ZN1A22direct_member_functionEv PROGBITS       
0000000000000000 000058 000001 00  AX  0   0  2
          [ 8] .text._ZN1A23virtual_member_functionEv PROGBITS       
0000000000000000 00005a 000001 00  AX  0   0  2
          [ 9] .text._Z13call_A_methodP1AMS_FvvE PROGBITS       
0000000000000000 00005b 000014 00  AX  0   0  1
          [10] .text.startup.main PROGBITS        0000000000000000 00006f
000040 00  AX  0   0  1
          [11] .rela.text.startup.main RELA            0000000000000000 000bf0
000060 18     22  10  8
          [12] .rodata._ZTS1A    PROGBITS        0000000000000000 0000af 000003
00  AG  0   0  1
          [13] .rodata._ZTI1A    PROGBITS        0000000000000000 0000c0 000010
00  AG  0   0 16
          [14] .rela.rodata._ZTI1A RELA            0000000000000000 000c50
000030 18     22  13  8
          [15] .rodata._ZTV1A    PROGBITS        0000000000000000 0000d0 000018
00  AG  0   0 16
          [16] .rela.rodata._ZTV1A RELA            0000000000000000 000c80
000030 18     22  15  8
          [17] .comment          PROGBITS        0000000000000000 0000e8 00002a
01  MS  0   0  1
          [18] .note.GNU-stack   PROGBITS        0000000000000000 000112 000000
00      0   0  1
          [19] .eh_frame         PROGBITS        0000000000000000 000118 000070
00   A  0   0  8
          [20] .rela.eh_frame    RELA            0000000000000000 000cb0 000060
18     22  19  8
          [21] .shstrtab         STRTAB          0000000000000000 000188 000119
00      0   0  1
          [22] .symtab           SYMTAB          0000000000000000 0008a8 000288
18     23  18  8
          [23] .strtab           STRTAB          0000000000000000 000b30 0000bb
00      0   0  1
        Key to Flags:
          W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
          I (info), L (link order), G (group), T (TLS), E (exclude), x
(unknown)
          O (extra OS processing required) o (OS specific), p (processor
specific)
        $ nm -n icf
                         w __gmon_start__
                         w _ITM_deregisterTMCloneTable
                         w _ITM_registerTMCloneTable
                         w _Jv_RegisterClasses
                         U __libc_start_main
        00000000004004e0 T _init
        0000000000400530 T main
        0000000000400570 T _start
        00000000004005a0 t deregister_tm_clones
        00000000004005d0 t register_tm_clones
        0000000000400610 t __do_global_dtors_aux
        0000000000400630 t frame_dummy
        000000000040065d T _Z14extra_functionv
        0000000000400663 T _Z14plain_functionP1A
        0000000000400663 T _ZN1A22direct_member_functionEv
        0000000000400663 T _ZN1A23virtual_member_functionEv
        0000000000400664 T _Z13call_A_methodP1AMS_FvvE
        0000000000400680 T __libc_csu_init
        00000000004006f0 T __libc_csu_fini
        00000000004006f4 T _fini
        0000000000400700 R _IO_stdin_used
        0000000000400704 V _ZTS1A
        0000000000400710 V _ZTI1A
        0000000000400720 V _ZTV1A
        0000000000400870 r __FRAME_END__
        0000000000401de8 d __JCR_END__
        0000000000401de8 d __JCR_LIST__
        0000000000401df0 t __do_global_dtors_aux_fini_array_entry
        0000000000401df8 t __frame_dummy_init_array_entry
        0000000000401df8 t __init_array_start
        0000000000401e00 d _DYNAMIC
        0000000000401e00 t __init_array_end
        0000000000401fe8 d _GLOBAL_OFFSET_TABLE_
        0000000000402010 D __data_start
        0000000000402010 W data_start
        0000000000402018 d __dso_handle
        0000000000402020 A __bss_start
        0000000000402020 b completed.6973
        0000000000402020 A _edata
        0000000000402020 d __TMC_END__
        0000000000402020 d __TMC_LIST__
        0000000000402040 B _ZTVN10__cxxabiv117__class_type_infoE
        0000000000402098 A _end
        $

In the readelf output you can see that two of the folded sections had
sh_addralign==2 while the one that was kept had sh_addralign==1.  The nm
output shows clearly that all three of these wound up at the same address
(as expected) and that this address is not aligned to 2 bytes (the bug).

Without knowing anything about the C++ ABI, the linker can know that the
alignment requirements expressed in input sections might be semantically
important to the code.  So it's breaking the expectations here by
delivering output that is less aligned than the requirement of the
corresponding input section.

This should be straightforward to fix: when doing ICF, simply choose among
the identical input sections to keep the one that has the largest
sh_addralign value.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]