先编写一个hello.c源程序
#include <stdio.h>
int main(){
printf("hello world\n");
return 0;
}
gcc -c hello.c
gcc -o hello hello.o
elf文件有两种视图,一种是链接视图,另一种是执行视图。hello.o是中间产物,还没有完成链接,不能执行。而hello是可以执行的,由于使用了函数库printf,所以hello是经过链接的。
计算机靠header中的type来区分到底是哪种。
readelf -h hello
可以看到其type为DYN,动态共享文件。
readelf -h hello.o
这时可以看到,hello.o是可重定位文件。
在头信息中可以看到,可执行文件的程序入口也是给定的,这是靠诉操作系统加载到指定的位置,而链接文件,地址是0。
符号表的结构体,源代码的位置在/usr/include/elf.h中。
typedef struct
{
Elf64_Word st_name; /* Symbol name (string tbl index) */
unsigned char st_info; /* Symbol type and binding */
unsigned char st_other; /* Symbol visibility */
Elf64_Section st_shndx; /* Section index */
Elf64_Addr st_value; /* Symbol value */
Elf64_Xword st_size; /* Symbol size */
} Elf64_Sym;
符号表中包括section的信息,因为多个elf文件在链接时,还会进行section的合并.
readelf -s hello.o
main函数的位置是0
动态符号表与静态符号表用的都是同一个结构体。其区别是,在链接完成后,静态符号表的值已经确定,比如上面的函数main,如图所示,其地址是ox63a,而动太符号表会在合适的时机才确定,所以其地址暂为0。而在链接之前,符号表中的值均为0。这样完成了静态链接部分。