I used crosstool-NG to create a PowerPC toolchain with gcc 6.3.0 and glibc 2.25. I have the following test program, test.c:
int main() { return 0; }
I compiled it with the command:
powerpc-unknown-linux-gnu-gcc -s -Os -o test test.c
The final binary is 66904 bytes, which is much larger than expected. The section headers look like this:
$ powerpc-unknown-linux-gnu-readelf -S test
There are 27 section headers, starting at offset 0x10120:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .interp PROGBITS 10000154 000154 00000d 00 A 0 0 1
[ 2] .note.ABI-tag NOTE 10000164 000164 000020 00 A 0 0 4
[ 3] .hash HASH 10000184 000184 000024 04 A 4 0 4
[ 4] .dynsym DYNSYM 100001a8 0001a8 000040 10 A 5 1 4
[ 5] .dynstr STRTAB 100001e8 0001e8 000045 00 A 0 0 1
[ 6] .gnu.version VERSYM 1000022e 00022e 000008 02 A 4 0 2
[ 7] .gnu.version_r VERNEED 10000238 000238 000020 00 A 5 1 4
[ 8] .rela.dyn RELA 10000258 000258 00000c 0c A 4 0 4
[ 9] .rela.plt RELA 10000264 000264 000018 0c AI 4 23 4
[10] .init PROGBITS 1000027c 00027c 00004c 00 AX 0 0 4
[11] .text PROGBITS 100002c8 0002c8 00031c 00 AX 0 0 4
[12] .fini PROGBITS 100005e4 0005e4 000030 00 AX 0 0 4
[13] .rodata PROGBITS 10000614 000614 000014 00 A 0 0 4
[14] .eh_frame_hdr PROGBITS 10000628 000628 000014 00 A 0 0 4
[15] .eh_frame PROGBITS 1000063c 00063c 000080 00 A 0 0 4
[16] .ctors PROGBITS 1001ff1c 00ff1c 000008 00 WA 0 0 4
[17] .dtors PROGBITS 1001ff24 00ff24 000008 00 WA 0 0 4
[18] .jcr PROGBITS 1001ff2c 00ff2c 000004 00 WA 0 0 4
[19] .got2 PROGBITS 1001ff30 00ff30 000008 00 WA 0 0 1
[20] .dynamic DYNAMIC 1001ff38 00ff38 0000c8 08 WA 5 0 4
[21] .data PROGBITS 10020000 010000 000008 00 WA 0 0 4
[22] .got PROGBITS 10020008 010008 000014 04 WAX 0 0 4
[23] .plt NOBITS 1002001c 01001c 000060 00 WAX 0 0 4
[24] .bss NOBITS 1002007c 01001c 000008 00 WA 0 0 4
[25] .comment PROGBITS 00000000 01001c 00002e 01 MS 0 0 1
[26] .shstrtab STRTAB 00000000 01004a 0000d4 00 0 0 1
You can see that there's a large jump between the .eh_frame and .ctors sections. If I use 'hd' to look at the file, I can see that the space between .eh_frame and .ctors is filled entirely with null bytes.
Why is gcc adding such a huge amount of space between the sections and is there any way to change its behavior?
It looks like this is due to binutils 2.27 increasing the default page size of PowerPC targets to 64k, resulting in bloated binaries on embedded platforms.
There's a discussion on the crosstool-NG github here.
Configuring binutils with --disable-relro
should improve things.
You can also add -Wl,-z,max-page-size=0x1000
to gcc when compiling.