2011-03-17 5 views
3

llvm-gcc-4.2.1을 사용하여 mplayer를 컴파일 중입니다.ASM 상수가있는 정의되지 않은 기호를 유발하는 링크 시간 최적화 문제

'-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 

, 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는 매크로로 초기화된다

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

이러한 상수는 ASM 코드에 사용되는 : 평가

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

 
#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 링커가 사용되며 결함이 있습니다.

EDIT : 나는 static을 알아 차리지 못했습니다. 즉, 인라인 asm과 심볼이 동일한 모듈에 있고 다른 버그라는 것을 의미합니다.

+0

. 여기서 상수는 명시 적으로 "used"로 표시되어 있으므로 사용 된 장소와 상관없이 옵티 마이저에 의해 보존되어야합니다. –

+0

@Anton Korobeynikov, 전체 모듈이 링크되지 않았으므로 도움이되지 않는 것 같습니다. 포함 된 asm의 참조는 뒤 따르지 않습니다. '__asm__'이 한 모듈에 있고 상수가 다른 모듈에 있고, 후자가 첫 모듈 다음에 연결되어있을 때 일어납니다. –

+0

이것은 의도 된 동작이므로 컴파일러는 어셈블러를 텍스트로 취급하므로 내부에서 이상한 일을하고 있다는 것을주의 깊게 알려야합니다. 정적 변수의 사용 (외부 가시성이 없으므로)은 컴파일러에게 반드시 알려야합니다 (이 경우 피연산자를 통해). –

0

글쎄, 이것은 분명히 버그입니다. 당신이 생각한다면, 이것은 컴파일러의 버그가 있음을 당신은 몇 가지 옵션이 있습니다 : 당신이 잡아

  • 시도 엑스 코드와 함께 제공 LLVM-GCC를 사용하는 것 때문에, 애플의 bugtracker에

    1. 보고서 상단의 트리 LLVM & llvm-gcc (지금까지는 btw로 더 이상 사용되지 않음) 문제를 재현하려고합니다 (또는 clang을 사용). 재생산되는 경우 LLVM PR을 채 웁니다.

    이 하나 일반적으로 컴파일러 버그를 처리 할 방법입니다 :)

    그러나, 그것은 나에게 보인다, 버그 소스 코드입니다. 여기에서는 최종 객체에서이 정적 상수에 해당하는 심볼의 이름이 어떤 형태인지 추측합니다. 이것은 일반적으로 구현 정의 된 것들이며 컴파일러는 임의적 인 방식으로 이름을 변경할 수 있습니다 (정적이어서 외부에서 볼 수 없기 때문에).

    "정적"을 제거하고 문제가 아직 있는지 확인하십시오. 또는 (적절한 방법입니다) 인라인 어셈블러를 수정하고 인라인 어셈블러 피연산자를 통해 상수를 제공해야합니다.

  • 1

    내 질문을 고려하는 데 시간을내어 주신 모든 분들께 감사드립니다. 그러나 저는 지금 제 컴파일 도구를 망쳐 놓았으며 이제는 정상적으로 컴파일 할 수있게되었습니다.

    문제는 mplayer가 cc == gcc를 기대하면서 'cc'를 호출하여 컴파일하는 것이 문제였습니다. 이것은 내 시스템의 경우가 아니 었습니다. cc는 gcc의 다른 버전으로 심볼릭 링크되었습니다. ccc를 gcc에 심볼릭 링크하자마자 -O4 (기본 mplayer 구성 스크립트에서 설정된대로)로 컴파일 할 프로젝트가 생겼습니다.

    결론 : 부적절하게 구성된 컴파일러 도구로 인해 링크 시간에 충돌이 발생했습니다. 빌드의 모든 단계에서 동일한 컴파일러를 사용하여 해결되었습니다.

    편집 : 실제로 llvm-gcc는 여전히 -O4와 함께 실패하지만 다른 컴파일러 (gcc-4.5.2 및 gcc42, Apple의 gcc 버전)는 성공합니다. 두 컴파일러는 모두 -flto 플래그를 허용하지 않으므로 링크 최적화가 여전히 실패합니다. 나는 적어도 내가이 질문을하는 동기가 된 주된 원인 인 -O2, -O3 등으로 컴파일 할 수 있다는 것에 행복하다.

    필자가 원한다면 llvm-gcc 컴파일러를 사용하고 싶습니다. (-O1 이상의 레벨에서) 당연히이 두 가지 컴파일러가 제대로 작동하고 있기 때문에이 질문을 준결승으로 간주해야합니다. 암호.

    0

    다음는 FFmpeg-0.8 내 시스템에 컴파일 할 수 : 이것은 사실이 아니다

    ./configure --cc=i686-apple-darwin10-gcc-4.2.1 --enable-gpl --enable-nonfree 
    
    관련 문제