除非用 gcc -static
方式编译一个程序,否则,都会链接一些so。分析了下,大概过程是这样的:
首先程序被执行到肯定需要执行到execve系统调用,该系统调用会做
“#!”判断并最终调用到实际的可执行程序。execve在执行可执行程序的时候,会判断bin程序的类型,比如是ELF还是别的。
对于ELF来说内核会从ELF的.interp段中读到so
动态加载器,一般是ld.so;然后加载之。然后由这个ld.so来把所有需要的so都加载起来。所以关键就是ld.so,具体可以 man
ld.so。所有与so相关的环境变量,比如LD_LIBRARY,LD_DEBUG,以及加载次序等,都是与ld.so相关的。ld.so本身是
glibc的一部分。
也就是说程序启动的时候,会有某个阶段由ld.so接管,用来加载so或做一些别的事的。所以,运行“LD_DEBUG=help
ls”的时候,可以做到ls根本没有执行,反而只是打印了LD_DEBUG的帮助信息。
关于.interp段:
readelf
会看到一个程序一般都有一个.interp端,这里指定的就是动态加载器(/lib64/ld-linux-x86-64.so.2),内核正式从这里读到的。
【附】
1. http://blog.csdn.net/joker0910/article/details/7686836
ELF 文件加载过程
2. http://stackoverflow.com/questions/5130654/when-how-does-linux-load-shared-