ELF文件格式
- 可重定位文件(relocatable)文件。用来和其他.o文件一期创建一个可执行文件或者共享文件
- 可执行文件(executable)文件。该文件指出了exec()如何来创建程序进程映像
- 一个共享object文件可被
- 连接编辑器(ld)——可以和其他可重定位和共享object文件来创建其他的object。
- 动态链接器——联合一个可执行文件和其他共享object文件来创建一个进程映像。
- readelf -h main可以查看ELF Header
可执行程序装载、动态链接
-
int execve(const char * filename, char * const argv[], char * const envp[]);——和fork一样,都是特殊一点的系统调用
-
exec_binprm(struct linux_bprm *bprm) -> ;load_elf_binary()
解析文件格式,并将文件内容映射到内存空间地址,总是映射到0x8048000
这个地址;如果是动态链接某个动态库的可执行程序话,会先加在连接器ld
,最后在start_thread(elf_entry)
的时候,此时elf_entry指向的是动态连接器ld。 -
gcc -shared xxx.c -0 libxxxx.so
-
编译mian时:
gcc main.c -o main -L /path/to/your/dir -lxxx -ldl
-
运行main
export LD_LIBRARY_PATH=&PWD
将当前目录加入默认路径,否则找不到库文件,或者将库文件copy到默认路径下
./main
-
装载时动态链接:
包含头文件后直接使用函数 -
运行时动态链接:
需要void * handle = dlopen("libxxx.so", RTLD_NOW)
-
-static 和 -l 参数可以同时使用,但它们的组合会产生一些特殊的效果。让我详细解释一下:
static 参数:
这个选项告诉编译器生成一个静态链接的可执行文件。
静态链接意味着所有的库函数都会被直接包含在最终的可执行文件中。
-l 参数:
这个选项用于指定要链接的库。
例如,-lm 表示链接数学库(libm)。
组合使用:
当同时使用 -static 和 -l 时,gcc 会尝试找到指定库的静态版本(.a 文件)而不是动态版本(.so 文件)。
如果找到了静态库,它会被完全包含在最终的可执行文件中。
如果只能找到动态库,gcc 会报错,因为 -static 要求所有链接都是静态的。