6

musl C 库只有符号版本控制的近似实现。这可能导致具有不同符号版本的符号绑定在一起,这在完整实现中不会发生。因此,希望使用 musl 构建的项目最好完全避免符号版本控制。(不支持符号版本控制本身对于工具链来说不一定是一个糟糕的选择;这完全取决于目标受众。)

然而,Alpine Linux 工具链编译 binutils 时具有完整的符号版本支持:GAS 支持.symver指令,链接编辑器处理版本脚本并分配符号版本(就像在 GNU/Linux 上一样)。一个简单的编译器/汇编器或链接器检查表明支持符号版本控制。结果,Alpine Linux 包含在发行版中的一些共享对象实际上使用了符号版本控制,尽管 musl 动态加载器会忽略这些数据。(数据只会使二进制文件膨胀。)

在某些情况下,软件无法运行(在构建良好之后),因为它以 musl 动态链接器不支持的方式使用兼容性符号(没有默认版本的符号)。这是一个不起作用的小例子:

cat > symver.c <<EOF
void
compat_function (void)
{
}
__asm__ (".symver compat_function,compat_function@SYMVER");

void
call_compat_function (void)
{
  return compat_function ();
}
EOF

echo "SYMVER { };" > symver.map

cat > main.c <<EOF
extern void call_compat_function (void);

int
main (void)
{
  call_compat_function ();
}
EOF

gcc -fpic -shared -o symver.so -Wl,--version-script=symver.map symver.c
gcc -Wl,--rpath=. -o main main.c symver.so
./main

执行失败,出现Error relocating ./symver.so: compat_function: symbol not found. 它在没有.symver指令的情况下成功运行。

这种 binutils 支持符号版本控制的组合与不支持它的动态链接器的组合如何在实践中工作?项目是否应该检查 *-musl目标三元组并禁用符号版本控制?

动态链接器支持的运行时检查可以完成这项工作,但它会破坏交叉编译。是否应该通过禁用 binutils 中的符号版本控制支持在 Alpine Linux 本身中解决此问题?

4

0 回答 0