gpt4 book ai didi

我可以修改共享库文件以与我的可执行文件一起正常工作吗

转载 作者:太空宇宙 更新时间:2023-11-04 00:06:13 25 4
gpt4 key购买 nike

我有共享库文件 say abc.so 是使用 say (a.c, b.c, c.c >) 文件。现在我已经通过可执行文件 say target.out

我的疑问是...我可以删除 abc.so 并再次从 (a.c, 单独构建 abc.so b.c, c.c) 并将其粘贴到我之前的 abc.so 所在的位置。但是我的 target.out 是旧的。

现在,如果我运行 target.out,它可以与新的 abc.so 一起正常工作吗??

最佳答案

是的,它会起作用,但你必须小心。

让我们以 libtest.c 为例:

int my_global_var = 42;

int sum(int a, int b)
{
return a + b;
}

它可以用:

gcc -fPIC -shared -o libtest.so libtest.c

通过 readelf -s libtest.so 我们可以看到函数和全局变量被公开为公共(public)符号:

$ readelf -s libtest.so
42: 0000000000200950 4 OBJECT GLOBAL DEFAULT 21 my_global_var
...
47: 0000000000000665 42 FUNC GLOBAL DEFAULT 11 sum
...

重要的是要注意 .so 文件没有指定这些符号的类型或原型(prototype)。

现在让我们编写一个使用该库的程序:

#include <stdio.h>

/* provided by libtest */
int sum(int, int);
extern int my_global_var;

int main()
{
printf("5 + 2 = %d and my_global_var = %d\n", sum(5, 2), my_global_var);

return 0;
}

并构建它:

gcc -L. -ltest -o program program.c

有效:

$ ./program 
5 + 2 = 7 and my_global_var = 42

我们可以看到program动态链接到libtest.so:

$ ldd program
...
libtest.so (0x00007f1138c70000)
...

符号 summy_global_var 再次在没有类型或原型(prototype)的程序头中被引用:

$ objdump --dynamic-reloc program 
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
0000000000600b00 R_X86_64_GLOB_DAT __gmon_start__
0000000000600b50 R_X86_64_COPY my_global_var
0000000000600b20 R_X86_64_JUMP_SLOT printf
0000000000600b28 R_X86_64_JUMP_SLOT __libc_start_main
0000000000600b30 R_X86_64_JUMP_SLOT __gmon_start__
0000000000600b38 R_X86_64_JUMP_SLOT sum

这就是它的工作原理,只要库文件存在并且它包含程序引用的符号,动态链接器就会很高兴并将这些符号的地址写入程序内存中的特殊间接表中。

如果我们将 my_global_var 更改为 43,重建库,并在不重建的情况下运行程序:

$ ./program 
5 + 2 = 7 and my_global_var = 43

如果我们从库中删除 my_global_var,符号就会消失,程序无法启动,因为动态链接器不满意:

$ ./program 
./program: symbol lookup error: ./program: undefined symbol: my_global_var

现在是棘手的部分,让我们尝试更改sum 的原型(prototype):

int my_global_var = 43;

float sum(float a, float b)
{
return a + b;
}

我们重建库,并运行程序:

$ ./program 
5 + 2 = 791621423 and my_global_var = 43

动态链接器没有提示,但结果是垃圾,因为程序将 int 传递给需要 float 的函数。

总结一下:只要类型和原型(prototype)保持绝对不变,它就可以工作。如果它们发生变化,链接器就不会提示,奇怪的事情就会开始发生。

为了解决最后一个问题,大型图书馆使用符号版本控制。这是一个相当复杂的主题,这里有一篇关于它的详细文章:http://www.trevorpounds.com/blog/?p=33

关于我可以修改共享库文件以与我的可执行文件一起正常工作吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23260316/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com