linux下几种目标文件的分析
本文中用到的命令:
gcc -c addvec.c
生成可重定位目标文件addvec.o
readelf addvec.o -a
读取可重定位目标文件addvec.o
gcc -O2 -c main.c
生成可重定位目标文件main.o
gcc -static -o vecadd addvec.o main.o
链接目标文件addvec.o,生成可执行文件vecadd
gcc -shared -fPIC -o libvector.so addvec.c
从addvec.c生成共享目标文件libvector.so
gcc -o vecadd2 main.c ./libvector.so
链接共享目标文件libvector.so生成vecadd2.
正文:
目标文件分为可执行目标文件,可重定位目标文件和共享目标文件。
也有对应的成为可执行文件,目标文件,共享库。但是只是说法不同,指的都是同样的东西。
有不少资料介绍这些知识,我们这里看具体看看它们到底是什么样的。
首先写一个简单的函数:
void addvec(int *x, int *y, int *z, int n)
{
int i;
for(i = 0; i < n; i++)
{
z[i] = x[i] + y[i];
}
}
存放在addvec.c文件中。
使用gcc -c addvec.c命令,可以得到一个addvec.o文件。
这里的addvec.o文件就是可重定位目标文件。
这个文件里面到底有些什么。我们可以通过readelf命令来看下。
readelf是GNU Binutils这个工具包里的工具。如果输入readelf -v查看不了这个工具的版本,
可以使用命令sudo apt-get install binutils去安装。
readelf addvec.o -a
可以得到以下的输出:
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 344 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 64 (bytes)
Number of section headers: 11
Section header string table index: 8
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000000000000 00000040
000000