开发者

Problem with Link Time Optimization causing undefined symbols with ASM constants

开发者 https://www.devze.com 2023-02-17 04:55 出处:网络
I am compiling mplayer with llvm-gcc-4.2.1. With \'-O1\' (which disables link time optimization), the program successfully compiles and links.With \'-O2\' or \'-O1 -flto\', ld complains of undefined

I am compiling mplayer with llvm-gcc-4.2.1.

With '-O1' (which disables link time optimization), the program successfully compiles and links. With '-O2' or '-O1 -flto', ld complains of undefined symbols:

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 arch开发者_开发知识库itecture x86_64
collect2: ld returned 1 exit status

fyi, my version of ld:

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

I'll focus just on MM_FIX_0_707106781, as the other constants all follow the same procedure.

MM_FIX_0_707106781 is initialized with the macro:

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

which evaluates to:

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

These constants are used in asm code:

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

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

I had a similar (the same?) problem with asm functions that I was able to resolve by adding:

".globl "LABLE_MANGLE(functionnamehere)"\n\t"

before each label, but that knowledge has not helped me with these ASM constants.

That is as much information as I can provide, I'm afraid. Once again, with -O1 the code compiles, links, and runs. With -O2 the linker fails to find these asm constants.

Can anyone offer a solution to this problem? Thanks.


Thanks to all who took the time to consider my question, however I just realized that I screwed up my compile tools, and am now able to compile normally.

The issue was that the mplayer make scripts invoke 'cc' to compile, with the expectation that cc == gcc. This was not the case on my system; cc was symlinked to some different version of gcc. As soon as I symlinked cc to gcc, I got the project to compile with -O4 (as set in the default mplayer configure script).

In conclusion: improperly configured compiler tools were causing conflicts at link time. Resolved by using the same compiler at all stages of build.

Edit: Actually llvm-gcc still fails with -O4, but the other compilers (gcc-4.5.2 and gcc42, which is Apple's gcc version) succeed. Both other compilers do not accept the -flto flag, so link-time-optimization is still failing. I am at least happy that I can compile with -O2, -O3, etc, which is the main reason I was motivated to pose this question.

Naturally I would like to be able to use the llvm-gcc compiler if I wish (at a level above -O1), however you should consider this question semi-resolved, as the other two compilers are working properly with this code.


Well, this is definitely a bug. If you think, that this is compiler bug you have several options:

  1. Report to Apple's bugtracker, since it seems you're using llvm-gcc shipped with XCode
  2. Try to grab top-of-tree llvm & llvm-gcc (which is deprecated by now, btw) and try to reproduce the issue (or, alternatively, grab clang). If reproduces - then fill an LLVM PR.

This is how one normally would deal with compiler bugs :)

However, as it seems to me, the bug is in the source code. Here you're assuming that the name of the symbol corresponding to this static constant in the final object will be of some form. This is generally implementation defined stuff and compiler can change the name in arbitrary way (since it's static and thus - not externally visible).

Try to remove "static" and check whether there the problem still exists. Alternatively (and this is the proper way), you should fix your inline assembler and provide your constant via inline assembler operand.


There is a bug in llvm-link - it does not consider symbols from an embedded asm. I don't know of any decent workaround other than referencing the same symbol somewhere from the same module in C. If you're doing a separate compilation, it is not a problem, as a native linker is used. For the LTO an LLVM linker will be used, and it is flawed.

EDIT: I have not noticed static, which means that both inline asm and a symbol are in a same module, and it is a different bug.


The following allowed ffmpeg-0.8 to compile on my system:

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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号