解耦编译和链接分为两个步骤

时间:2018-08-02 12:12:09

标签: linker segmentation-fault static-linking dynamic-linking

我有一个主文件,该文件调用了共享库中定义的函数。

// main.c
int main()
{
    int x[2] = {1, 2};
    int y[2] = {3, 4};
    int z[2];
    addvec(x, y, z, 2);
}

共享库是以下代码

// addvec.c

void addvec(int *x, int *y, int *z, int n)
{
    int i;
    for(i = 0; i < n; ++i)
         z[i] = x[i] + y[i];
}

我使用gcc -shared -fpic -nostdlib -o libevctor.so addvec.c来创建一个共享库。

然后我在不链接的情况下编译了main.c。

gcc -c main.c -o main.o

最后,我链接了这两部分:

ld -rpath=$PWD -dynamic-linker /lib/ld-linux.so.2 -m elf_i386 -e main main.o libvector.so -o prog

到目前为止,一切正常。但是,当我运行prog时,会发生分段错误。

此外,我将readelfprog并发现.dynsym中addvec的值为0:

symbol table '.dynsym' consists of 5 entries:
Num:  value:  Size   Type    Bind   Vis   Ndx   Name
0:   00000000   0     NOTYPE LOCAL  DEFAULT UND
1:   00000000   0     FUNC   GLOBAL DEFAULT UND addvec
2:   0804934c   0     FUNC   GLOBAL DEFAULT 10  __bss_start
....

我做错了什么吗?

1 个答案:

答案 0 :(得分:1)

通常,您不应显式使用ld(或gold或任何其他链接程序),因为调用行非常依赖于目标并且脆弱。只需链接gcc

gcc -Wl,-rpath=$PWD -m32 main.o libvector.so -o prog

在特定情况下,您可能会丢失处理程序启动和libc设置的crt对象文件(添加-v以查看实际的ld调用行)。