2017-03-02 15 views
2

저는 LLVM IR로 놀고 있는데, LLVM 인터프리터 lli이 명확하게 정의되지 않은 함수를 찾고있는 곳에서 (Google 및 doc의 도움으로) 해결할 수 없습니다. 기본 시스템 기능을 의미 함).LLVM 인터프리터가 외부 함수 (라이브러리?)를 찾고 있습니다.

@message = private constant [12 x i8] c"hello world\0A" 
define i32 @puts(i8* %s) { 
    call i32 asm sideeffect "movl $$0x2, %edi\0Amovl $$0xC, %edx\0Amovl$$1, %eax\0Asyscall\0A", "=A,{si}"(i8* %s) #1 
    ret i32 %1 
} 
define void @exit(i32 %c) { 
    call i32 asm sideeffect "movl $$60, %eax\0Asyscall\0A", "=A,{di}"(i32 %c) #1 
    ret void 
} 
define void @main() { 
    getelementptr [12 x i8], [12 x i8]* @message, i64 0, i64 0 
    call i32 @puts(i8* %1) 
    call void @exit(i32 0) 
    ret void 
} 
define void @_start() { 
    call void @main() 
    ret void 
} 

main_startldlli와 상호 호환성을위한 것입니다 : 예를 들어 내가 그런 일을 할 수있는 화면에 무언가를 작성합니다 리눅스에 종속되지 간단한 프로그램을 작성하려는 경우. 그래서 위 코드는 둘 다 동일하게 작동합니다. 이 코드는 lli이고 코드는 main 또는 llc이고 그 다음은 ld이 될 수 있으며 코드도 _start에서 시작됩니다. 내가 코드를 작성하는 경우 지금 : 그것은 또한 lli에서 작동

@formatString = private constant [4 x i8] c"%d\0A\00" 
declare i32 @printf(i8*, ...) 
define i32 @main() { 
    %d = shl i32 2, 3 
    %s = getelementptr [4 x i8], [4 x i8]* @formatString, i64 0, i64 0 
    %call = call i32 (i8*, ...) @printf(i8* %s, i32 %d) 
    ret i32 0 
} 

을하지만 난 수 없습니다 ld 그것은 ld 때문에도 예상된다 printf을 참조 모르겠어요. 그 코드가 작동하도록하기 위해 ld 매개 변수를 준비하거나, 단순히 gcc file.o -o file을 사용하는 것도 포함 할 수 있습니다. 그러나 이것은 제 요점이 아닙니다. 내 요점은 lli에 외부 라이브러리 (예 : libc)를 포함하지 않고 단지 내 코드 만 실행하고 내 자신의 진입 점을 정의하는 방법입니다. 준비된 libc 또는 다른 라이브러리를 포함시킬 수 있습니다. 함수의 이름을 덮어 쓰고 작동해야하지만, 무엇이 다시 작성되었는지 확신 할 수 없기 때문에 printf이 사용되었지만 정의되지 않은 경우 lli이 오류를 던집니다. 또는 내가 잘못한 점을 알고 lli 같은 환경에서 수행 할 수 없습니다.

+1

'lli -entry-function = _start file.ll'에서 어떤 진입 점을 선택할 수 있습니다. 그러나 미리로드 된 코드의 인터프리터를 제거하는 방법을 여전히 모릅니다. '-extra-object = '옵션이 있지만 기본적으로로드 된 모든 객체를 비활성화하는 옵션을 찾을 수 없습니다. – mucka

답변

2

TL; DR : JIT없이 lli 사용하고 아마 작동합니다

lli -force-interpreter main.bc 

상세 정보 : 일반적으로

, 그것은 (있는 경우 당신은 후드 아래에 사용 JIT 엔진의 종류에 따라 달라집니다).

내가 익숙하지이기 때문에 내가 MCJIT (-jit-kind=mcjit)에 대해 말할 수 없다,하지만 난 당신이 ORC JIT (-jit-kind=orc-mcjit 또는 -jit-kind=orc-lazy)를 사용하는 경우이 불가능하다고 말씀 드릴 수 있습니다. 그러나 이것은 ORC를 직접 사용하기로 결정한 경우에만 lli에 해당하며이 동작을 제어 할 수 있습니다.

lli의 컨텍스트에서 ORC는 모듈/외부 객체뿐만 아니라 전체 프로그램의 주소 공간도로드합니다. 이것은 모든 libc와 전체 LLVM 자체를 얻는다는 것을 의미합니다.

필요에 따라 lli을 진정으로 통역사로 사용해 볼 수도 있지만 더 이상 JIT가 포함되지 않으므로 속도가 느려집니다.

그냥 -force-interpreter 옵션을 추가하면 몇 가지 예외가 있습니다. 이 함수들은 여전히 ​​정상적으로 실행될 것입니다.

void Interpreter::initializeExternalFunctions() { 
    sys::ScopedLock Writer(*FunctionsLock); 
    (*FuncNames)["lle_X_atexit"]  = lle_X_atexit; 
    (*FuncNames)["lle_X_exit"]   = lle_X_exit; 
    (*FuncNames)["lle_X_abort"]  = lle_X_abort; 

    (*FuncNames)["lle_X_printf"]  = lle_X_printf; 
    (*FuncNames)["lle_X_sprintf"]  = lle_X_sprintf; 
    (*FuncNames)["lle_X_sscanf"]  = lle_X_sscanf; 
    (*FuncNames)["lle_X_scanf"]  = lle_X_scanf; 
    (*FuncNames)["lle_X_fprintf"]  = lle_X_fprintf; 
    (*FuncNames)["lle_X_memset"]  = lle_X_memset; 
    (*FuncNames)["lle_X_memcpy"]  = lle_X_memcpy; 
} 
+0

불행히도, 이미 시도해 보았습니다. 문제는 공식 LLVM 5.0.0svn'을 사용하고 있습니다.문제는 내가 인터프리터가 자체 기능을 위해 미리로드 한 모든 기능에 액세스 할 수 있다는 것입니다. 어쨌든, 답변 주셔서 감사합니다! – mucka

+0

"mcjit-remote-process"를 사용하여 환경을 더 좋게 만들 수는 있지만 "표준"원격 프로세스는 궁금합니다. https://github.com/llvm-mirror/llvm/blob/master/tools/lli/ChildTarget/ChildTarget.cpp'가 유망 해 보이지 않습니다. – mucka

+0

사용자 지정 JIT 스택을 설치하는 것이 좋습니다. 아주 기본적인 커스텀 UI는 다소 쉽고 작습니다. 도움이 필요하면 언제든지 저를 버리십시오. [email protected] – AlexDenisov