日期:2014-05-16  浏览次数:20847 次

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