链接时间优化问题导致ASM常量的未定义符号

时间:2011-03-17 10:58:27

标签: assembly constants undefined llvm symbols

我正在使用llvm-gcc-4.2.1编译mplayer。

使用'-O1'(禁用链接时间优化),程序成功编译并链接。使用'-O2'或'-O1 -flto'时,ld会抱怨未定义的符号:

Undefined symbols for architecture x86_64:
  "_MM_FIX_0_707106781", referenced from:
      _filter in vf_fspp.o
  "_MM_FIX_0_541196100", referenced from:
      _filter in vf_fspp.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

fyi,我的ld版本:

@(#)PROGRAM:ld  PROJECT:ld64-123.2
llvm version 2.9svn, from Apple Clang 2.0 (build 137)

我将只关注MM_FIX_0_707106781,因为其他常量都遵循相同的程序。

MM_FIX_0_707106781使用宏初始化:

DECLARE_ASM_CONST(8, uint64_t, MM_FIX_0_707106781)=FIX64(0.707106781, 14);

评估为:

static const uint64_t __attribute__((used, aligned (8))) MM_FIX_0_707106781=0x2d412d412d412d41;

这些常量用于asm代码:

#define MANGLE(a) "_" #a "(%%rip)"

__asm__ volatile(
...
  "pmulhw "MANGLE(MM_FIX_0_707106781)", %%mm7 \n\t"
...
);

我有asm函数的类似(相同?)问题,我可以通过添加以下来解决:
".globl "LABLE_MANGLE(functionnamehere)"\n\t"
在每个标签之前,但这些知识并没有帮助我使用这些ASM常量。

这是我能提供的尽可能多的信息,我很害怕。再一次,使用-O1代码编译,链接和运行。使用-O2时,链接器无法找到这些asm常量。

有人能提供这个问题的解决方案吗?感谢。

4 个答案:

答案 0 :(得分:1)

答案 1 :(得分:0)

llvm-link中存在一个错误 - 它不考虑嵌入式asm中的符号。除了在C中的同一模块的某处引用相同的符号之外,我不知道任何体面的解决方法。如果您正在进行单独的编译,那么这不是问题,因为使用了本机链接器。对于LTO,将使用LLVM链接器,并且它存在缺陷。

编辑:我没有注意到static,这意味着内联asm和符号都在同一个模块中,这是一个不同的错误。

答案 2 :(得分:0)

嗯,这绝对是一个错误。如果您认为这是编译器错误,您有几个选择:

  1. 向Apple的bugtracker报告,因为您似乎正在使用随XCode一起提供的llvm-gcc
  2. 尝试抓住树顶上的llvm& llvm-gcc(现在已弃用,顺便说一句)并试图重现问题(或者,抓住clang)。如果重现 - 然后填写LLVM PR。
  3. 这就是人们通常会处理编译器错误的方法:)

    但是,在我看来,这个错误在源代码中。在这里,您假设最终对象中与此静态常量对应的符号名称将具有某种形式。这通常是实现定义的东西,编译器可以以任意方式更改名称(因为它是静态的,因此 - 不是外部可见的)。

    尝试删除“静态”并检查问题是否仍然存在。或者(这是正确的方法),您应该修复内联汇编程序并通过内联汇编程序操作数提供常量。

答案 3 :(得分:0)

以下允许在我的系统上编译ffmpeg-0.8:

./configure --cc=i686-apple-darwin10-gcc-4.2.1 --enable-gpl --enable-nonfree