<HTML><HEAD></HEAD>
<BODY dir=ltr>
<DIV dir=ltr>
<DIV style="FONT-FAMILY: 'Calibri'; COLOR: #000000; FONT-SIZE: 12pt">
<DIV>Hello everyone, i’m using LLVM (updated to 3.1 after seeing that bug, but 
it’s the same with 3.0) for running a bitcode on a C++ program, and Clang for 
compiling it. My code work perfectly, as expected on x64, but crash on x86. I’m 
on Windows 7 x64 and LLVM + Clang was compiled using Visual Studio 2010 (tested 
in both Release and Debug build). Project was make using CMake.</DIV>
<DIV> </DIV>
<DIV>Here is my code:</DIV>
<DIV> </DIV>
<DIV>main.cpp:</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>#include "llvm/LLVMContext.h"</DIV>
<DIV>#include "llvm/Module.h"</DIV>
<DIV>//#include "llvm/Type.h"</DIV>
<DIV>//#include "llvm/ADT/Triple.h"</DIV>
<DIV>//#include "llvm/Bitcode/ReaderWriter.h"</DIV>
<DIV>#include "llvm/CodeGen/LinkAllCodegenComponents.h"</DIV>
<DIV>#include "llvm/ExecutionEngine/GenericValue.h"</DIV>
<DIV>//#include "llvm/ExecutionEngine/Interpreter.h"</DIV>
<DIV>#include "llvm/ExecutionEngine/JIT.h"</DIV>
<DIV>#include "llvm/ExecutionEngine/JITEventListener.h"</DIV>
<DIV>#include "llvm/ExecutionEngine/JITMemoryManager.h"</DIV>
<DIV>//#include "llvm/ExecutionEngine/MCJIT.h"</DIV>
<DIV>//#include "llvm/Support/CommandLine.h"</DIV>
<DIV>#include "llvm/Support/IRReader.h"</DIV>
<DIV>//#include "llvm/Support/ManagedStatic.h"</DIV>
<DIV>#include "llvm/Support/MemoryBuffer.h"</DIV>
<DIV>//#include "llvm/Support/PluginLoader.h"</DIV>
<DIV>#include "llvm/Support/PrettyStackTrace.h"</DIV>
<DIV>#include "llvm/Support/raw_ostream.h"</DIV>
<DIV>//#include "llvm/Support/Process.h"</DIV>
<DIV>#include "llvm/Support/Signals.h"</DIV>
<DIV>#include "llvm/Support/TargetSelect.h"</DIV>
<DIV>//#include <cerrno></DIV>
<DIV> </DIV>
<DIV>#include "llvm/DerivedTypes.h"</DIV>
<DIV>//#include "llvm/Support/DynamicLibrary.h"</DIV>
<DIV>#include "llvm/Linker.h"</DIV>
<DIV> </DIV>
<DIV>//using namespace llvm;</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>llvm::LLVMContext* LLVM_Context;</DIV>
<DIV>static llvm::ExecutionEngine* LLVM_ExecE = 0;</DIV>
<DIV>llvm::Module* LLVM_Module;</DIV>
<DIV>llvm::Type* LLVM_pointerType;</DIV>
<DIV> </DIV>
<DIV>bool loadChunk(void* chunk)</DIV>
<DIV>{</DIV>
<DIV>    llvm::Module* m = (llvm::Module*)chunk;</DIV>
<DIV>    std::string msg;</DIV>
<DIV> </DIV>
<DIV>    if (llvm::Linker::LinkModules(LLVM_Module, m, 
llvm::Function::ExternalLinkage, &msg))</DIV>
<DIV>    {</DIV>
<DIV>        printf("\nLINK ERROR - %s", 
&msg);</DIV>
<DIV>    }</DIV>
<DIV>    return true;</DIV>
<DIV>}</DIV>
<DIV>bool loadFile(const char* filename)</DIV>
<DIV>{</DIV>
<DIV>    // Load the bitcode...</DIV>
<DIV>    llvm::SMDiagnostic Err;</DIV>
<DIV>    llvm::Module* Mod = ParseIRFile(filename, Err, 
*LLVM_Context);</DIV>
<DIV>    if (!Mod) {</DIV>
<DIV>        Err.print("Error loading 
bitcode", llvm::errs());</DIV>
<DIV>        return 1;</DIV>
<DIV>    }</DIV>
<DIV>    printf("\nLink with main module.\n");</DIV>
<DIV>    loadChunk(Mod);</DIV>
<DIV> </DIV>
<DIV>    printf("\nDone loading %s", filename);</DIV>
<DIV>    return true;</DIV>
<DIV>}</DIV>
<DIV>void callFunction(const char* name, unsigned int argc, ...)</DIV>
<DIV>{</DIV>
<DIV>    llvm::Function *f = 
LLVM_Module->getFunction(name);</DIV>
<DIV>    if (f)</DIV>
<DIV>    {</DIV>
<DIV>        
std::vector<llvm::GenericValue> args;</DIV>
<DIV>        if (argc > 0) </DIV>
<DIV>        {</DIV>
<DIV>            va_list 
argv;</DIV>
<DIV> </DIV>
<DIV>            
va_start(argv, argc);</DIV>
<DIV>            for 
(unsigned int x = 0; x < argc; x++) {</DIV>
<DIV>                
llvm::GenericValue v;</DIV>
<DIV>                
v.DoubleVal = (va_arg(argv, double)); // this might not work for anything other 
than doubles!</DIV>
<DIV>                
args.push_back(v);</DIV>
<DIV>            }</DIV>
<DIV>            
va_end(argv);</DIV>
<DIV>        }</DIV>
<DIV>        LLVM_ExecE->runFunction(f, 
args);</DIV>
<DIV>    }</DIV>
<DIV>    else </DIV>
<DIV>    {</DIV>
<DIV>        printf("\nTried to execute 
non-existent function '%c'.\n", name);</DIV>
<DIV>    }</DIV>
<DIV>}</DIV>
<DIV> </DIV>
<DIV>template<typename T></DIV>
<DIV>const static void* void_cast(const T& object)</DIV>
<DIV>{</DIV>
<DIV>    union Retyper</DIV>
<DIV>    {</DIV>
<DIV>        const T object;</DIV>
<DIV>        void* pointer;</DIV>
<DIV>        Retyper(T obj) : object(obj) { 
}</DIV>
<DIV>    };</DIV>
<DIV> </DIV>
<DIV>    return Retyper(object).pointer;</DIV>
<DIV>}</DIV>
<DIV>template<typename T, typename M></DIV>
<DIV>const static void* getMethodPointer(const T* object, M method) // will work 
for virtual methods</DIV>
<DIV>{</DIV>
<DIV>    union MethodEntry</DIV>
<DIV>    {</DIV>
<DIV>        intptr_t offset;</DIV>
<DIV>        void* function;</DIV>
<DIV>    };</DIV>
<DIV> </DIV>
<DIV>    const MethodEntry* entry = static_cast<const 
MethodEntry*>(void_cast(&method));</DIV>
<DIV> </DIV>
<DIV>    if (entry->offset % sizeof(intptr_t) == 0) // looks 
like that's how the runtime guesses virtual from static</DIV>
<DIV>        return 
getMethodPointer(method);</DIV>
<DIV> </DIV>
<DIV>    const void* const* const vtable = 
*reinterpret_cast<const void* const* const* const>(object);</DIV>
<DIV>    return vtable[(entry->offset - 1) / 
sizeof(void*)];</DIV>
<DIV>}</DIV>
<DIV>template<typename M></DIV>
<DIV>const static void* getMethodPointer(M method) // will only work with 
non-virtual methods</DIV>
<DIV>{</DIV>
<DIV>    union MethodEntry</DIV>
<DIV>    {</DIV>
<DIV>        intptr_t offset;</DIV>
<DIV>        void* function;</DIV>
<DIV>    };</DIV>
<DIV> </DIV>
<DIV>    return static_cast<const 
MethodEntry*>(void_cast(&method))->function;</DIV>
<DIV>}</DIV>
<DIV> </DIV>
<DIV>static llvm::Type* voidptr_type = NULL;</DIV>
<DIV> </DIV>
<DIV>void registerSymbolFunction(const char* mangled_name, void* func)</DIV>
<DIV>{</DIV>
<DIV>    // This is the JIT way for register a function</DIV>
<DIV>    // Commented "sig.push_back" before defined function 
because they don't seem to need args</DIV>
<DIV>    std::vector<llvm::Type*> sig;</DIV>
<DIV>    llvm::FunctionType* FT = NULL;</DIV>
<DIV>    llvm::Function* F = NULL;</DIV>
<DIV> </DIV>
<DIV>    sig.clear();</DIV>
<DIV>    //sig.push_back(LLVM_pointerType);</DIV>
<DIV>    // Get the function type</DIV>
<DIV>    FT = llvm::FunctionType::get(voidptr_type, sig, 
false);</DIV>
<DIV>    // Create the function</DIV>
<DIV>    F = llvm::Function::Create(FT, 
llvm::Function::ExternalLinkage, mangled_name, LLVM_Module);</DIV>
<DIV>    // Register the function to the global module</DIV>
<DIV>    // This method register the function to the module and 
the ExecutionEngine</DIV>
<DIV>    LLVM_ExecE->addGlobalMapping(F, func);</DIV>
<DIV> </DIV>
<DIV>    // This also work, i don't know what method is better, 
addGlobalMapping seem to be for the JIT</DIV>
<DIV>    // and AddSymbol for the interpreter</DIV>
<DIV>    // This method register the function directly to 
LLVM</DIV>
<DIV>    //llvm::sys::DynamicLibrary::AddSymbol(mangled_name, 
func);</DIV>
<DIV>}</DIV>
<DIV> </DIV>
<DIV>std::string getPrintText()</DIV>
<DIV>{</DIV>
<DIV>    printf("\nRunning getPrintText()...\n");</DIV>
<DIV>    return std::string("Hello world from 
getPrintText()!");</DIV>
<DIV>}</DIV>
<DIV>class TestClass1</DIV>
<DIV>{</DIV>
<DIV>public:</DIV>
<DIV>    static void test1()</DIV>
<DIV>    {</DIV>
<DIV>        printf("\nHello World from 
TestClass1::test1()!\n");</DIV>
<DIV>    }</DIV>
<DIV>    void test2(std::string s)</DIV>
<DIV>    {</DIV>
<DIV>        printf("\nHello World from 
TestClass1::test2()! : %s\n",+s.data());</DIV>
<DIV>        //ConsoleM.newMsg(S+"Hello World 
from TestClass1::test2()! : "+s.data(), YELLOW);</DIV>
<DIV>    }</DIV>
<DIV>} testclass1;</DIV>
<DIV> </DIV>
<DIV>int main(int argc, char** argv, char* const* envp)</DIV>
<DIV>{</DIV>
<DIV>    printf("argc: %i ", argc);</DIV>
<DIV>    printf("argv: %c ", argv);</DIV>
<DIV>    printf("envp: %c ", envp);</DIV>
<DIV> </DIV>
<DIV>    llvm::sys::PrintStackTraceOnErrorSignal();</DIV>
<DIV>    llvm::PrettyStackTraceProgram X(argc, argv);</DIV>
<DIV> </DIV>
<DIV>    LLVM_Context = new llvm::LLVMContext();</DIV>
<DIV> </DIV>
<DIV>    // If we have a native target, initialize it to ensure 
it is linked in and</DIV>
<DIV>    // usable by the JIT.</DIV>
<DIV>    llvm::InitializeNativeTarget();</DIV>
<DIV>    llvm::InitializeNativeTargetAsmPrinter();</DIV>
<DIV> </DIV>
<DIV>    llvm::SMDiagnostic Err;</DIV>
<DIV>    LLVM_Module = new llvm::Module("LLVM Test", 
*LLVM_Context);</DIV>
<DIV>    if (!LLVM_Module) {</DIV>
<DIV>        Err.print(argv[0], 
llvm::errs());</DIV>
<DIV>        return 1;</DIV>
<DIV>    }</DIV>
<DIV> </DIV>
<DIV>    std::string ErrorMsg;</DIV>
<DIV>    llvm::EngineBuilder builder(LLVM_Module);</DIV>
<DIV>    builder.setErrorStr(&ErrorMsg);</DIV>
<DIV>    
builder.setJITMemoryManager(llvm::JITMemoryManager::CreateDefaultMemManager());</DIV>
<DIV>    builder.setEngineKind(llvm::EngineKind::JIT);</DIV>
<DIV> </DIV>
<DIV>    //CodeGenOpt::Level OLvl = CodeGenOpt::Default;</DIV>
<DIV> </DIV>
<DIV>    //builder.setOptLevel(OLvl);</DIV>
<DIV> </DIV>
<DIV>    llvm::TargetOptions Options;</DIV>
<DIV>    Options.JITExceptionHandling = false;</DIV>
<DIV>    Options.JITEmitDebugInfo = false;</DIV>
<DIV>    Options.JITEmitDebugInfoToDisk = false;</DIV>
<DIV>    builder.setTargetOptions(Options);</DIV>
<DIV> </DIV>
<DIV>    LLVM_ExecE = builder.create();</DIV>
<DIV>    if (!LLVM_ExecE) {</DIV>
<DIV>        if (!ErrorMsg.empty())</DIV>
<DIV>            
llvm::errs() << argv[0] << ": error creating ExecE: " << 
ErrorMsg << "\n";</DIV>
<DIV>        else</DIV>
<DIV>            
llvm::errs() << argv[0] << ": unknown error creating 
ExecE!\n";</DIV>
<DIV>        exit(1);</DIV>
<DIV>    }</DIV>
<DIV> </DIV>
<DIV>    // The following functions have no effect if their 
respective profiling</DIV>
<DIV>    // support wasn't enabled in the build 
configuration.</DIV>
<DIV>    LLVM_ExecE->RegisterJITEventListener(</DIV>
<DIV>        
llvm::JITEventListener::createOProfileJITEventListener());</DIV>
<DIV>    LLVM_ExecE->RegisterJITEventListener(</DIV>
<DIV>        
llvm::JITEventListener::createIntelJITEventListener());</DIV>
<DIV> </DIV>
<DIV>    LLVM_ExecE->DisableLazyCompilation(false);</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>    voidptr_type = llvm::IntegerType::get(*LLVM_Context, 
8)->getPointerTo();</DIV>
<DIV> </DIV>
<DIV>    LLVM_pointerType = 
(llvm::Type*)llvm::Type::getInt32Ty(*LLVM_Context);</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>    registerSymbolFunction("_Z12getPrintTextv", 
(void*)&getPrintText);</DIV>
<DIV> </DIV>
<DIV>    registerSymbolFunction("_ZdlPv", (void*)(void(*) 
(void*))operator delete);</DIV>
<DIV> </DIV>
<DIV>    registerSymbolFunction("_ZN10TestClass15test2ESs", 
(void*)getMethodPointer(&TestClass1::test2));</DIV>
<DIV> </DIV>
<DIV>    //registerSymbolFunction("_ZN10TestClass15test1Ev", 
(void *)TestClass1::test1);</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>    // Run static constructors.</DIV>
<DIV>    
LLVM_ExecE->runStaticConstructorsDestructors(LLVM_Module, false);</DIV>
<DIV> </DIV>
<DIV>    loadFile("engine_test.bc");</DIV>
<DIV> </DIV>
<DIV>    // Run main.</DIV>
<DIV>    std::vector<llvm::GenericValue> args;</DIV>
<DIV>    
LLVM_ExecE->runFunction(LLVM_Module->getFunction("_Z4Initv"), args);</DIV>
<DIV> </DIV>
<DIV>    // Run static destructors.</DIV>
<DIV>    
LLVM_ExecE->runStaticConstructorsDestructors(true);</DIV>
<DIV> </DIV>
<DIV>    return 1;</DIV>
<DIV>}</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>engine_test.cpp:</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>#include <string></DIV>
<DIV> </DIV>
<DIV>std::string getPrintText();</DIV>
<DIV> </DIV>
<DIV>class TestClass1</DIV>
<DIV>{</DIV>
<DIV>public:</DIV>
<DIV>    static void test1();</DIV>
<DIV>    void test2(std::string s);</DIV>
<DIV>} testclass1;</DIV>
<DIV> </DIV>
<DIV>bool Init()</DIV>
<DIV>{</DIV>
<DIV>    printf("\n\nStarting bitcode...\n");</DIV>
<DIV> </DIV>
<DIV>    //This work on x86 and x64 using LLVM in Release, but 
crash in x86 Debug</DIV>
<DIV>    printf("Result from getPrintText(): %s", 
getPrintText().data());</DIV>
<DIV>    printf("\ngetPrintText() finished!\n");</DIV>
<DIV> </DIV>
<DIV>    //This work on x64 using LLVM in Release, but crash in 
x86 both Release and Debug</DIV>
<DIV>    //testclass1.test2(std::string("HI! testclass1"));</DIV>
<DIV>    TestClass1 _testclass1;</DIV>
<DIV>    _testclass1.test2(std::string("Hello world!"));</DIV>
<DIV> </DIV>
<DIV>    printf("\nEnding bitcode...\n\n");</DIV>
<DIV>    return true;</DIV>
<DIV>}</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>And the command i’m using for compiling the bitcode:</DIV>
<DIV> </DIV>
<DIV>clang++ -v -O3 -I "../CodeHeaders/VS2010/include" -std=c++11 -emit-llvm 
"../engine_test.cpp" -c -o engine_test.bc</DIV>
<DIV> </DIV>
<DIV>From what i have see it could be a bug with the "getMethodPointer" function 
(i’m using it for getting the address of the function in a class). Or with the 
"delete" operator from what i could see on the Visual Studio call stack. 
Basicaly "_testclass1.test2" is executed, but crash just after, so probably when 
he get deleted.</DIV>
<DIV> </DIV>
<DIV>After trying to test my code with the x64 Debug build i have found that it 
also crash, but the call stack is different then the x86 Debug build.</DIV>
<DIV> </DIV>
<DIV>Call stack using LLVM in x86 Debug:</DIV>
<DIV> </DIV>
<DIV>     ntdll.dll!778515de()     
</DIV>
<DIV>     [Les frames ci-dessous sont peut-être incorrects 
et/ou manquants, aucun symbole chargé pour ntdll.dll]    </DIV>
<DIV>     ntdll.dll!778515de()     
</DIV>
<DIV>     ntdll.dll!7784014e()     
</DIV>
<DIV>>    msvcr100d.dll!_write(int fh, const void * buf, 
unsigned int cnt)  Ligne 83 + 0x9 octets    C</DIV>
<DIV>     msvcr100d.dll!_write(int fh, const void * buf, 
unsigned int cnt)  Ligne 82 + 0xc octets    C</DIV>
<DIV>     013df8f4()    </DIV>
<DIV>     
msvcp100d.dll!std::_Container_base12::_Orphan_all()  Ligne 
200    C++</DIV>
<DIV>     
LLVM_Test_Console.exe!std::_String_val<char,std::allocator<char> 
>::~_String_val<char,std::allocator<char> >()  Ligne 478 + 
0xb octets    C++</DIV>
<DIV>     
LLVM_Test_Console.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> 
>::~basic_string<char,std::char_traits<char>,std::allocator<char> 
>()  Ligne 754 + 0xf octets    C++</DIV>
<DIV>     
LLVM_Test_Console.exe!TestClass1::test2(std::basic_string<char,std::char_traits<char>,std::allocator<char> 
> s)  Ligne 172 + 0xf octets    C++</DIV>
<DIV>     001e0091()    </DIV>
<DIV>     
LLVM_Test_Console.exe!llvm::JIT::runFunction(llvm::Function * F, const 
std::vector<llvm::GenericValue,std::allocator<llvm::GenericValue> > 
& ArgValues)  Ligne 455 + 0x7 octets    C++</DIV>
<DIV>     LLVM_Test_Console.exe!main(int argc, char * * 
argv, char * const * envp)  Ligne 254 + 0x43 octets    
C++</DIV>
<DIV>     LLVM_Test_Console.exe!__tmainCRTStartup()  
Ligne 555 + 0x19 octets    C</DIV>
<DIV>     LLVM_Test_Console.exe!mainCRTStartup()  Ligne 
371    C</DIV>
<DIV>     kernel32.dll!76dd339a()     
</DIV>
<DIV>     ntdll.dll!77869ef2()     
</DIV>
<DIV>     ntdll.dll!77869ec5()     
</DIV>
<DIV> </DIV>
<DIV>Call stack using LLVM in x86 Release:</DIV>
<DIV> </DIV>
<DIV>     ntdll.dll!778515de()     
</DIV>
<DIV>     [Les frames ci-dessous sont peut-être incorrects 
et/ou manquants, aucun symbole chargé pour ntdll.dll]    </DIV>
<DIV>     ntdll.dll!778515de()     
</DIV>
<DIV>     ntdll.dll!7784014e()     
</DIV>
<DIV>     msvcr100.dll!56a7a5d0()     
</DIV>
<DIV>     msvcr100.dll!56a70949()     
</DIV>
<DIV>     msvcr100.dll!56a7f00d()     
</DIV>
<DIV>     kernel32.dll!76dd14dd()     
</DIV>
<DIV>     msvcr100.dll!56a7016a()     
</DIV>
<DIV>     
LLVM_Test_Console.exe!TestClass1::test2(std::basic_string<char,std::char_traits<char>,std::allocator<char> 
> s)  Ligne 172 + 0x10 octets    C++</DIV>
<DIV>     00160091()    </DIV>
<DIV>>    LLVM_Test_Console.exe!llvm::JIT::runFunction()  
+ 0x2ed octets    C++</DIV>
<DIV>     LLVM_Test_Console.exe!main(int argc, char * * 
argv, char * const * envp)  Ligne 254 + 0x41 octets    
C++</DIV>
<DIV>     msvcr100.dll!56a7263d()     
</DIV>
<DIV>     kernel32.dll!76dd339a()     
</DIV>
<DIV>     ntdll.dll!77869ef2()     
</DIV>
<DIV>     ntdll.dll!77869ec5()     
</DIV>
<DIV> </DIV>
<DIV>Call stack using LLVM in x64 Debug:</DIV>
<DIV> </DIV>
<DIV>>    msvcr100d.dll!_output_l(_iobuf * stream, const char 
* format, localeinfo_struct * plocinfo, char * argptr)  Ligne 1644 + 0x23 
octets    C++</DIV>
<DIV>     msvcr100d.dll!printf(const char * format, 
...)  Ligne 62 + 0x1e octets    C</DIV>
<DIV>     
LLVM_Test_Console.exe!TestClass1::test2(std::basic_string<char,std::char_traits<char>,std::allocator<char> 
> * s)  Ligne 170 + 0x1a octets    C++</DIV>
<DIV>     00000000003500c7()    </DIV>
<DIV>     00000000001eed78()    </DIV>
<DIV>     00000000001eed50()    </DIV>
<DIV>     00000000003e00d0()    </DIV>
<DIV> </DIV>
<DIV>Realy hope you could help me, since i don’t know if it’s bug in my code or 
in LLVM. :).</DIV>
<DIV> </DIV>
<DIV>Thanks you.</DIV>
<DIV> </DIV></DIV></DIV></BODY></HTML>