2011-03-17 42 views
3

我正在用llvm-gcc-4.2.1编译mplayer。链接时间优化的问题导致带有ASM常量的未定义符号

使用'-O1'(禁用链接时间优化),程序成功编译和链接。随着 '-02' 或 '-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 

仅供参考,我的版本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; 

这些常数在汇编代码用于:

 
#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常量。

任何人都可以提供解决这个问题?谢谢。

回答

0

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

编辑:我还没有发现static,这意味着这两个内联汇编和符号是同一模块中,它是一个不同的错误。

+0

这是不正确的。这里常量被明确标记为“used”,所以它应该被优化器保存,而不管它被使用的地方。 – 2011-03-17 14:24:57

+0

@Anton Korobeynikov,它似乎没有帮助,因为整个模块没有链接 - 从嵌入式asm的引用没有遵循。如果'__asm__'在一个模块中,并且常量在另一个模块中,并且后者在第一个模块之后被链接,就会发生这种情况。 – 2011-03-17 14:33:38

+0

这是意图行为,编译器会像汇编文件一样对待汇编程序,所以您应该仔细通知它,您正在做一些奇怪的事情。使用静态变量(因为它没有外部可见性)是你肯定应该通知编译器的东西(在这种情况下 - 通过操作数)。 – 2011-03-20 19:26:11

0

嗯,这绝对是一个错误。如果你觉得,这是编译器错误,你有几种选择:

  1. 报告苹果的错误追踪系统,因为它似乎你使用LLVM-GCC附带的XCode
  2. 试图抓住顶级树LLVM & llvm-gcc(现在不推荐使用,顺便说一句),并尝试重现问题(或者,也可以抓取clang)。如果再现 - 然后填写LLVM PR。

这是一个多么通常会处理编译器错误:)

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

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

1

感谢所有花时间考虑我的问题的人,但是我意识到我搞砸了我的编译工具,现在可以正常编译了。

问题是,mplayer使脚本调用'cc'进行编译,期望cc == gcc。我的系统中并非如此; cc被符号链接到一些不同版本的gcc。只要我将cc链接到gcc,我就可以使用-O4编译项目(如在默认的mplayer配置脚本中设置)。

总之:错误配置的编译器工具在链接时造成冲突。通过在构建的所有阶段使用相同的编译器解决。

编辑:实际上llvm-gcc仍然失败-O4,但其他编译器(gcc-4.5.2和gcc42,这是苹果的gcc版本)成功。其他两个编译器都不接受-flto标志,所以链接时间优化仍然失败。我至少很高兴能用-O2,-O3等进行编译,这是我被激发提出这个问题的主要原因。

当然,我希望能够使用llvm-gcc编译器(如果我希望的话)(在-O1以上的级别),但是应该考虑将此问题半分解,因为其他两个编译器可以正常使用码。

0

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

./configure --cc=i686-apple-darwin10-gcc-4.2.1 --enable-gpl --enable-nonfree 
相关问题