X86_thiscall

Hi everyone,

I have some problems with gettings the X86_thiscall calling convention to work. I am new to LLVM, so if this is the wrong place for this question then I appologise, please tell me where to go instead.

I am generating code to call a member function of a class compiled with Microsoft Visual C++ using the JIT compiler.

The following code is used to register the pointer to the function. as_ptr retrieves the address of a member function pointer. Yes, this is a bit of a hack, but it works (I have tested it in other situations).

vector<llvm::Type *> arguments;
arguments.push_back(interface_group_ptr);
arguments.push_back(any);
arguments.push_back(instance_ptr);

auto get_interface_type=FunctionType::get(any, arguments, false);
interface_group_get_interface=Function::Create(get_interface_type, Function::ExternalLinkage, “get_interface”, llvm_module);
interface_group_get_interface->setCallingConv(CallingConv::X86_ThisCall);
execution_engine->addGlobalMapping(interface_group_get_interface, (void *)as_ptr(&InterfaceGroup::get_interface));

The following call generates the code for the call:

vector<Value *> get_interface_args;
get_interface_args.push_back(interface_group_variable);
get_interface_args.push_back(requested_type);
get_interface_args.push_back(ptr_this);
auto result=llvm_builder.CreateCall(module->interface_group_get_interface, get_interface_args);

Now the problem is that the generated code does not actually seem to be using the thiscall calling convention specified for the called function:

0011001B mov dword ptr [esp+8],eax
0011001F mov eax,dword ptr [esp+14h]
00110023 mov dword ptr [esp+4],eax
00110027 mov dword ptr [esp],102594h
0011002E call Zeo::InterfaceGroup::get_interface (0151B133h)
00110033 add esp,10h

0x102594 is the address of the object that I am trying to call a member function on, and should be loaded into ecx by the code, instead of stored on the stack. The result is that the right function is called, but ‘this’ and the other parameters are incorrect.

From what I have been reading about it, this calling convention should be implemented, so either I am doing something wrong, or there is a bug in LLVM in general, or the JIT compiler specifically. The chance that I am doing something wrong is probably bigger, but I do not know what.

Any tips would be greatly appreciated. By the way, I am using a 3.3 release built with Visual Studio.

With kind regards,
Taco.

Hello

You have not specified the calling convention for the call.

Something like this:

auto result=llvm_builder.CreateCall(module->interface_group_get_interface,
get_interface_args);
result->setCallingConv(CallingConv::X86_ThisCall);

should do the trick