2017-10-24 4 views
0

내가 런타임에서 다음 LLVM의 IR을 생성하고 난 즉시LLVM IR는 간단한 프로그램 segfault의

;other declarations/functions 

define %gen__struct__81ty_struct.catch_val @gen__fun__115(void**) { 
entry: 
    %1 = getelementptr void*, void** %0, i32 0 
    %2 = load void*, void** %1, align 8 
    %3 = bitcast void* %2 to i64* 
    store i64 1, i64* %3, align 8 
    %4 = load i64, i64* %3, align 8 
    %5 = getelementptr void*, void** %0, i32 1 
    %6 = load void*, void** %5, align 8 
    %7 = bitcast void* %6 to i64* 
    store i64 1, i64* %7, align 8 
    %8 = load i64, i64* %7, align 8 
    %9 = getelementptr void*, void** %0, i32 2 
    %10 = load void*, void** %9, align 8 
    %11 = bitcast void* %10 to i64* 
    store i64 1, i64* %11, align 8 
    ret %gen__struct__81ty_struct.catch_val zeroinitializer 
} 

내가 다음 만화경 JIT를 사용하는 기능을 실행 찾고 있어요와 C 다음 ++ 코드를 컴파일 및 실행 제공 위의 기능을하지만 나는 계속 segfault를 얻는다.

Function* out = 0; 
    //code that generates the function ... 

    runFunc fptr = 0; 
    jit->addModule(std::move(gblDevice->lmod)); 
    fptr = (runFunc)jit->getPointerToFunction(out); 

    vector<void*> params; 
    uint64_t a = 0; 
    uint64_t b = 0; 
    uint64_t c = 0; 
    params.push_back(&a); 
    params.push_back(&b); 
    params.push_back(&c); 

    catch_val_pt cval = fptr(&params[0]); 

나는 위의 코드에 무엇이 잘못되었지만 모든 것이 체크 아웃되어 있는지 몇 시간 동안 시험해 보았습니다.

getPointerToFunction 함수는 다음과 같습니다.

class OrcJIT { 
// ... 
JITSymbol findSymbol(const std::string Name) { 
    std::string MangledName; 
    raw_string_ostream MangledNameStream(MangledName); 
    Mangler::getNameWithPrefix(MangledNameStream, Name, DL); 
    return CODLayer.findSymbol(MangledNameStream.str(), true); 
} 

inline void* getPointerToFunction(Function* F) { 
    return (void*)findSymbol(F->getName().data()).getAddress(); 
} 
//... 
} 
+0

https://stackoverflow.com/q/46884340의 사본 일 수 있습니다. 기본적으로 MCJIT에 대해'getPointerToFunction'가 사용되지 않는 이유가 있습니다. 대신에,'getFunctionAddress (functionName)'를 사용해주세요. 이것에 의해, 필요한 finalize가 자동적으로 행해집니다. – PaulR

+0

내가 너무 빠르면 LLVM의 어떤 버전을 사용하고 정확히 segfault를 얻을 수 있습니까? gdb와 같은 디버거에서 프로그램을 실행 해보십시오. 역 추적을 얻을 수 없다면 아마도 생성 된 코드에있을 것입니다. 주소를 함수 포인터와 비교하십시오. segfault가 첫 번째 명령에서 발생하면 이는 이전 질문에서 설명한 문제 일 수 있습니다. 포인터가 포인터를 사용하지 않는 함수를 생성하여 코드가 액세스하지 않아야하는 코드를 제외하도록 좁힐 수 있습니다. – PaulR

+1

저는 llvm-4.0.0, windows 64-bit, MinGW, g ++을 사용하고 있습니다. getPointerToFunction 함수에서 수행 한 작업에 대한 답변을보십시오. – ceorron

답변

0

결국 대답은 매우 간단합니다.

llvm이 값을 반환하는 방식과 gcc가 값을 반환하는 방식 사이에 이진 비 호환이 있어야합니다. 짧은 대답은 gen__struct__81ty_struct.catch_val 반환 값은 segfault가 발생합니다.

생성 된 함수에 간단하게 넣으면 생성 된 함수에 전달 된 포인터를 통해 copy to structure를 통해이를 반환해야합니다. 가장 단순한 경우 (int라고도 함)에서 일치하는 생성 된 함수의 반환 값에 의존 할 수 없습니다.