It's because the generated ELF is different from the standard (or atleast isn't compatible for running on your system), it misses quite a lot of standard ELF header sections. readelf
can help you to find out the difference, for ex. do gcc -o ab a.c b.c
then do readelf -S ./ab
, you'll see there are 29 sections (as per my system). Also create another ELF through gcc -c a.c b.c
and ld a.o b.o -e main -o ab2
, then again use readelf -S ./ab2
now you'll see there's only 18 section (as per my case).
Now if you take close look, then you'll see there's quite a few sections those are missing - like. .init, .fini, __libc_start_main etc. Now if you take a look at objdump
of both executable's then you'll see at the time of returning there's few particular things which is done at .fini section (gcc internal stuffs, like restoring stack). So, these are the things which are missing from a standard ELF which is produces by invoking gcc -o ab a.c b.c
.
To make sure that the problem is at the time of returning from main, you can make sure this by using gdb
, I've figured the problem by generating object code by gcc -g3 a.c b.c
and ld a.o b.o -e main -o ab
. You'll see that problem is happening when you're about to return from main. Hope this will give you some idea, why it's happening.