gpt4 book ai didi

c - 如何将 LTO 与符号版本控制相结合

转载 作者:太空狗 更新时间:2023-10-29 17:11:43 26 4
gpt4 key购买 nike

我想使用符号版本控制和链接时优化 (LTO) 编译共享库。但是,一旦我打开 LTO,一些导出的符号就会消失。这是一个最小的例子:

首先定义函数 fun 的两个实现:

$ cat fun.c 
#include <stdio.h>

int fun1(void);
int fun2(void);

__asm__(".symver fun1,fun@v1");
int fun1() {
printf("fun1 called\n");
return 1;
}

__asm__(".symver fun2,fun@@v2");
int fun2() {
printf("fun2 called\n");
return 2;
}

创建版本脚本以确保只导出fun:

$ cat versionscript 
v1 {
global:
fun;
local:
*;
};
v2 {
global:
fun;
} v1;

第一次尝试,不使用 LTO 编译:

$ gcc -o fun.o -Wall -Wextra -O2 -fPIC -c fun.c
$ gcc -o libfun.so.1 -shared -fPIC -Wl,--version-script,versionscript fun.o
$ nm -D --with-symbol-versions libfun.so.1 | grep fun
00000000000006b0 T fun@@v2
0000000000000690 T fun@v1

.. 完全正确。但是如果我用 LTO 编译:

$ gcc -o fun.o -Wall -Wextra -flto -O2 -fPIC -c fun.c
$ gcc -o libfun.so.1 -flto -shared -fPIC -Wl,--version-script,versionscript fun.o
$ nm -D --with-symbol-versions libfun.so.1 | grep fun

..不再导出符号。

我做错了什么?

最佳答案

WHOPR Driver Design对正在发生的事情给出了一些强烈的暗示。函数定义 fun1fun2 未根据版本脚本导出。 LTO 插件能够使用此信息,并且由于 GCC 不查看 asm 指令,它对 .symver 指令一无所知,因此删除了函数定义.

目前,添加 __attribute__ ((externally_visible)) 是解决此问题的方法。您还需要使用 -flto-partition=none 进行构建,这样 .symver 指令就不会意外地出现在与函数定义不同的中间汇编程序文件中(其中它不会产生预期的效果)。

GCC PR 48200在编译器级别跟踪对符号版本控制的增强请求,这也可能解决此问题。

关于c - 如何将 LTO 与符号版本控制相结合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46304742/

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