9
votes

I came across the size command which gives the section size of the ELF file. While playing around with it, I created an output file for the simplest C++ program :

int main(){return 0;}

Clearly, I have not defined any initialized or uninitialized, data then why are my BSS and DATA sections of the size 512 and 8 bytes?

I thought it might be because of int main(), I tried creating object file for the following C program :

void main(){}

I still don't get 0 for BSS and DATA sections.

Is it because a certain minimum sized memory is allocated to those section?

EDIT- I thought it might be because of linked libraries but my object is dynamically linked so probably it shouldn't be the issue

2
There is a static library for the C runtime which is linked by the compiler, and which includes the real entry point which calls main(). You should see the real entry point function e.g. if you run objdump --disassemble. objdump -f will show information including the "start address". - sourcejedi
I see a few libraries linked to my object when i run objdump on it, the ouput of file a.out said it's dynamically linked ELF so i assumed there are no statically linked libraries, guess i was wrong. - Time Traveller
Compile it with -g and run nm on it - you will see all the symbols in the elf file. - filo

2 Answers

11
votes

int main(){return 0;} puts data in .text only.

$ echo 'int main(){return 0;}' | gcc -xc - -c -o main.o && size main.o
   text    data     bss     dec     hex filename
     67       0       0      67      43 main.o

You're probably sizeing a fully linked executable.

$ gcc main.o -o main && size main
   text    data     bss     dec     hex filename
   1415     544       8    1967     7af main
10
votes

In fact, if you are compiling with the libc attached to the binary, there are functions that are added before (and after) the main() function. They are here mostly to load dynamic libraries (even if you do not need it in your case) and unload it properly once main() end.

These functions have global variables that require storage; uninitialized (zero initialized) global variables in the BSS segment and initialized global variables in the DATA segment.

This is why, you will always see BSS and DATA in all the binaries compiled with the libc. If you want to get rid of this, then you should write your own assembly program, like this (asm.s):

.globl _start
 _start:
    mov %eax, %ebx

And, then compile it without the libc:

$> gcc -nostdlib -o asm asm.s

You should reduce your footprint to the BSS and DATA segment on this ELF binary.