I have a simple C program. I run:$ gcc Q1.c -Wall -save-temps -o Q1Then I inspect the executable generated:$  objdump -f Q1Q1:     file format elf32-i386architecture: i386, flags 0x00000112:EXEC_P, HAS_SYMS, D_PAGEDstart address 0x080483b0Then I compile it with static linking:$ gcc Q1.c -Wall -save-temps -static -o Q1and inspect the file again:$ objdump -f Q1Q1:     file format elf32-i386architecture: i386, flags 0x00000112:EXEC_P, HAS_SYMS, D_PAGEDstart address 0x08048e08What effect does static and dynamic linking have on the start address of the program? The start address is the address of main(), right?
Effect of static and dynamic linking on start address
c;gcc;dynamic linking;static linking
The start address is the address of main(), right?Not really: The start of a program isn't really main(). By default, GCC will produce executables whose start address corresponds to the _start symbol. You can see that by doing a objdump --disassemble Q1. Here's the output on a simple program of mine that only does return 0; in main():0000000000400e30 <_start>:  400e30:       31 ed                   xor    %ebp,%ebp  400e32:       49 89 d1                mov    %rdx,%r9  400e35:       5e                      pop    %rsi  400e36:       48 89 e2                mov    %rsp,%rdx  400e39:       48 83 e4 f0             and    $0xfffffffffffffff0,%rsp  400e3d:       50                      push   %rax  400e3e:       54                      push   %rsp  400e3f:       49 c7 c0 a0 15 40 00    mov    $0x4015a0,%r8  400e46:       48 c7 c1 10 15 40 00    mov    $0x401510,%rcx  400e4d:       48 c7 c7 40 0f 40 00    mov    $0x400f40,%rdi  400e54:       e8 f7 00 00 00          callq  400f50 <__libc_start_main>  400e59:       f4                      hlt      400e5a:       66 90                   xchg   %ax,%ax  400e5c:       0f 1f 40 00             nopl   0x0(%rax)As you can see at address 400e54, _start() in turn invokes __libc_start_main, which initializes the necessary stuff (pthreads, atexit,...) and finally calls main() with the appropriate arguments (argc, argv and env).Okay, but what does it have to do with the start address changing?When you ask gcc to link statically, it means that all the initialization that I mentioned above has to be done using functions that are in the executable. And indeed if you look at the sizes of both executables, you'll find that the static version is way larger. On my test, the static version is 800K while the shared version is only 6K.The extra functions happen to be placed before _start(), hence the change in start address. Here's the layout of the static executable around start():000000000049e960 r translit_from_tbl0000000000400a76 t _i18n_number_rewrite0000000000400bc0 t fini0000000000400bd0 t init_cacheinfo0000000000400e30 T _start0000000000400e60 t deregister_tm_clones0000000000400e90 t register_tm_clones0000000000400ed0 t __do_global_dtors_auxAnd here's the layout of the shared executable:00000000004003c0 T _start00000000004003f0 t deregister_tm_clones00000000004004b0 T main00000000004004c0 T __libc_csu_init00000000006008a0 B _end0000000000400370 T _initAs a result, I get slightly different start addresses: 0x400e30 in the static case and 0x4003c0 in the shared case.