3

I compare three compilers:

  • GCC (x86) from Debian (6.3.0) produces hugo_x86.so with 7.8K,
  • GCC (ppc) from Codesourcery (4.6.0) produces hugo_46.so with 6.6K,
  • GCC (x86) from Buildroot 2017.08 (7.2.0) produces hugo.so with 7.5K,
  • GCC (ppc) from Buildroot 2017.08 (7.2.0) produces hugo.so with 67K,
  • GCC (ppc) from Buildroot 2017.08 (6.4.0) produces hugo.so with 67K and
  • GCC (ppc) from Buildroot 2017.08 (4.9.4) produces hugo.so with 67K

The code was taken from eli.thegreenplace.net:

int myglob = 42;

int ml_func(int a, int b)
{
    myglob += a;
    return b + myglob;
}

I ve compiled all sources like this:

powerpc-linux-gcc -c -o hugo.o hugo.c
powerpc-linux-gcc --shared -o hugo.so hugo.o

The difference between the files seems to be a padding (hexdump hugo.so | wc -l):

  • Debian (6.3.0): 381 lines
  • Codesourcery (4.6.0): 283 lines
  • Buildroot 2017.08 (7.2.0): 298 lines
  • Buildroot 2017.08 (6.4.0): 294 lines

(objdump -s shows a similar result)

Questions:

  1. How can I analyze the difference in the Object file best? (objdump, readelf, etc)
  2. How can I analyze the difference (e.g. default options) of the compiler best? (e.g. -dumpspecs)
  3. What could be the reason, for blowing up the shared object? How to increase the file size?

Thanks!

-- Edit: It is also independent of the GCC specs. I ve dumped (-dumpspec) the spec of the Codesourcery (4.6.0) GCC which produces a small shared object, and used it with the Buildroot GCC (-specs) and got again a 67K shared object.

Charly
  • 1,270
  • 19
  • 42
  • Somewhat unrelated to your question and problem, but you should really create your object files with `-fPIC` when building. – Some programmer dude Jan 17 '18 at 10:18
  • 1
    Also, if you try to `strip` the libraries, how does that change the sizes? – Some programmer dude Jan 17 '18 at 10:19
  • Yes, I just wanted to keep the example simple. I came to the problem, that my rootfs increased from 40Mb to 60Mb and the lines above are just a example to talk about. – Charly Jan 17 '18 at 10:20
  • 1
    Are you using similar optimization levels for all the runs? Even if the optimization levels are the same, different compilers could be running different individual optimizations, so there is nothing to compare. For this code specifically, you can just look at the generated assembly and manually compare what is different – Ajay Brahmakshatriya Jan 17 '18 at 10:20
  • Stripping makes no difference: 67K to 66K – Charly Jan 17 '18 at 10:20
  • I compiled the code with -Os: also 67K – Charly Jan 17 '18 at 10:21
  • 1
    @Charly, each compiler has a different definition of `-Os` (there is a huge difference in the versions of your gcc too). So I wouldn't be surprised. – Ajay Brahmakshatriya Jan 17 '18 at 10:22
  • If binary size is the only concern for you, you can just chose the compiler that gives you the smallest size. Even a higher version doesn't necessarily guarantee anything. – Ajay Brahmakshatriya Jan 17 '18 at 10:23
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/163314/discussion-between-charly-and-ajay-brahmakshatriya). – Charly Jan 17 '18 at 10:26
  • It might be relevant to show which optimizations you have enabled, if any. – Lundin Jan 17 '18 at 10:35
  • how do I see, which optimizations are enabled? In the command-line I perform the command as I written above - so without any flags. – Charly Jan 17 '18 at 13:20

1 Answers1

2

from How to reduce ELF section padding?:

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.

When adding BR2_BINUTILS_EXTRA_CONFIG_OPTIONS="--disable-relro" to my buildroot configuration, the share object size is reduced.

Charly
  • 1,270
  • 19
  • 42