Difference between static and dynamic linking

Lets write a simple helloworld program and using which we will try to understand the difference between static and dynamic linking.

 $ vim helloworld.c 
#include <stdio.h>

int main(int argc, char **argv) {
        printf("Hello World !");
        return 0;
}

Now, we will try to compile this program as,

 $ gcc -o helloworld helloworld.c 
 $ file helloworld
helloworld: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=57cffc47f6d9d1f05a43c3b1cda6bc43d4f95dbf, not stripped 
 $ ldd helloworld
	linux-gate.so.1 =>  (0xb773e000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7559000)
	/lib/ld-linux.so.2 (0x8008a000)

Above two commands, “file” and “ldd” shows that by default “gcc” created dynamically linked executable.

Now, lets try to create “statically linked” executable of same program as,

 $ gcc -o helloworld_static helloworld.c -static 
 $ file helloworld_static helloworld_static: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=a7cc1db70ccce3a1640579f2637e8d5ee1a6b9e4, not stripped 
 $ ldd helloworld_static 
	not a dynamic executable 

Above two commands shows we now have a “statically linked” executable.

Now lets try to compare the file sizes of both executable as,

 $ ls -alh helloworld
-rwxrwxr-x 1 myuser myuser 7.2K Sep  2 21:08 helloworld

$ size helloworld
   text	   data	    bss	    dec	    hex	filename
   1124	    276	      4	   1404	    57c	helloworld

$ ls -alh helloworld_static 
-rwxrwxr-x 1 myuser myuser 712K Sep  2 21:08 helloworld_static

$ size helloworld_static    text	   data	    bss	    dec	    hex	filename
 658287	   4096	   3644	 666027	  a29ab	helloworld_static

So above two commands, shows that dynamically linked executable “helloworld” generates much smaller in size (7.2K) binary compared to statically linked executable “helloworld_static” (712K)

So the first difference is that, statically linked executable requires more space compared to dymanically linked executables which is the disadvantage of static linking and advantage of dynamic linking.

Another difference is, If several processes call the same object module of a shared library simultaneously, Only one copy of shared library resides in memory for dynamically linked executables where as for static linking all things of library gets copied as part of static linking hence Several copies each for a process resides in memory.

 $ strace ./helloworld
execve("./helloworld", ["./helloworld"], [/* 69 vars */]) = 0
brk(NULL)                               = 0x9046000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76ee000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=170313, ...}) = 0
mmap2(NULL, 170313, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb76c4000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\320\207\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1786484, ...}) = 0
mmap2(NULL, 1792540, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb750e000
mmap2(0xb76be000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1af000) = 0xb76be000
mmap2(0xb76c1000, 10780, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb76c1000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7715000
set_thread_area({entry_number:-1, base_addr:0xb7715940, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 (entry_number:6)
mprotect(0xb76be000, 8192, PROT_READ)   = 0
mprotect(0x8049000, 4096, PROT_READ)    = 0
mprotect(0xb7716000, 4096, PROT_READ)   = 0
munmap(0xb76c4000, 170313)              = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 13), ...}) = 0
brk(NULL)                               = 0x9046000
brk(0x9067000)                          = 0x9067000
write(1, "Hello World !", 13Hello World !)           = 13
exit_group(0)                           = ?
+++ exited with 0 +++
 $ strace ./helloworld_static 
execve("./helloworld_static", ["./helloworld_static"], [/* 69 vars */]) = 0
uname({sysname="Linux", nodename="nms-bot-server", ...}) = 0
brk(NULL)                               = 0x88e5000
brk(0x88e5d40)                          = 0x88e5d40
set_thread_area({entry_number:-1, base_addr:0x88e5840, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 (entry_number:6)
readlink("/proc/self/exe", "/home/myuser/githu"..., 4096) = 97
brk(0x8906d40)                          = 0x8906d40
brk(0x8907000)                          = 0x8907000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 13), ...}) = 0
write(1, "Hello World !", 13Hello World !)           = 13
exit_group(0)                           = ?
+++ exited with 0 +++

The above commands where we tried to run both executables with strace shows, dynamic linking has more system calls, which means dynamic linked executables will need more time for running/execution.

Android Android Commands Android Java Applications Application Libraries Bash / Shell Scripts Bluetooth driver Build Frameworks Commands and Packages Core Kernel C Programs Development Environment Setup Documents / Books Errors & Failures File Systems Framebuffer / Display Driver git Go Language Programs Hardware Platforms Home Kernel & Device Drivers Kernel Booting and Porting Linux, OS Concepts and Networking Linux Device Drivers Linux Host, Ubuntu, SysAdmin Linux Kernel Linux Networking Middleware Libraries, HAL NDK / Middleware / HAL Network Driver OS Concepts PHP Procfs Filesystem Programming Languages RaspberryPi Scripting and Automation Search Engine Optimisation ( SEO ) Social Media Socurce Code Management ( SCM ) System Administration, Security Testing and Debugging Uncategorized Userspace Utilities Web design and development Wordpress Yocto / Bitbake / Openembedded

Leave a Reply