[LLVMdev] [Proposal] Adding callback mechanism to Execution Engines

Yaron Keren yaron.keren at gmail.com
Thu Oct 31 23:45:15 PDT 2013


Hi Sumeeth,

You want to call machine code functions from a program running under some
EE.
Can't this be  implemented by directly mapping llvm::Function into an
address?

 Function* F = Function::Create(YourFunctionType, ExternalLinkage);
 JIT->addGlobalMapping(F, Addr);

You can either add the CustomCallback function or better yet add exactly
the functions you need with correct prototypes.

Yaron



2013/11/1 Sean Silva <chisophugis at gmail.com>

>
>
> On Thu, Oct 31, 2013 at 11:39 PM, sumeeth kc <sumeethkc at gmail.com> wrote:
>
>> Hello,
>>
>> I would like to have your opinions on this.
>>
>> *Problem:*
>>
>> Currently, there are no ways to perform hypercalls into LLVM (they
>> transfer execution from the program being executed to the LLVM
>> infrastructure to perform compilation).  The goal of this project is to
>> cleanly integrate an API into the LLVM code/execution engine to create
>> custom callbacks.  The “lli” executable should allow having a function be
>> registered as callback with the execution engines and the program being
>> compiled by LLVM should be able to make a callback into that function
>> inside lli during its execution.
>>
>
> What are you using lli for that you are running into this problem?
>
> -- Sean Silva
>
>
>>
>>
>> *Design:*
>>
>> 1.       The user programs link with a dummy library function called
>> PerformCustomCallback(const char* CallbackName, void *Args).
>>
>> 2.       LLVM ExecutionEngines (JIT and MCJIT) will implement this
>> function to perform the multiplexing of the various callbacks registered
>> with them.
>>
>> 3.       Whenever the user program calls PerformCustomCallback with
>> appropriate arguments, lli should experience a call to one of the
>> registered callbacks.
>>
>>
>>
>> *Methodology:*
>>
>> In JIT, the external symbols are resolved during the call to void
>> *JIT::getPointerToNamedFunction(const std::string &Name, bool
>> AbortOnFailure). So, the hypercall resolution can be done here.
>>
>> In MCJIT, during finalizeObject(), all the symbol relocations are
>> finalized. In the Memory Managers, the external symbols are resolved. So,
>> the hypercall resolution can be done in
>> LinkingMemoryManager::getSymbolAddress().
>>
>>
>>
>> In JIT::getPointerToNamedFunction(), check whether the function name is
>> PerformCustomCallback and store the address of the function
>> PerformCustomCallback in the global table. So the next time a call happens,
>> JIT will get the address directly from the table.
>>
>>
>>
>> In MCJIT, in LinkingMemoryManager::getSymbolAddress() do the same.
>>
>>
>>
>> The execution engines (JIT and MCJIT) will provide the concrete
>> implementation of PerformCustomCallback function. The PerformCustomCallback
>> function has to call the appropriate function with the callback name
>> provided by the user program and pass the arguments supplied by the user
>> program to the callback functions. It also passes an extra argument to the
>> callback functions which may contain the LLVM context as specified during
>> the registering of the callback.
>>
>>
>>
>> I propose to add a new API to the LLVM ExecutionEngine *int
>> registerCustomCallback(const char *CallbackName, void* (*)(), void
>> *LLVM_args)* to be used by llvm tools such as lli. This takes a
>> function’s name to be registered as a callback, the pointer to the function
>> and a placeholder for any extra arguments which the lli needs to pass to
>> the callback functions.  The ExecutionEngine will register the function
>> names as callbacks and calls them when it encounters a callback in the user
>> program.
>>
>>
>>
>> *Interface*:
>>
>> Whenever a new callback has to be registered, the following things are to
>> be done:
>>
>> 1.       The new callback has to be defined in lli (a function
>> definition).
>>
>> 2.       The callback has to be registered with the ExecutionEngine (JIT
>> or MCJIT) using the API registerCustomCallback(). Depending upon the flags
>> set during lli invocation, the call goes to JIT or MCJIT.
>>
>> 3.       In the user program, a call to PerformCustomCallback() with the
>> name and arguments will execute the registered callback.
>>
>>
>>
>> Example:
>>
>> Suppose, I want to register a function named Callback1 which takes two
>> integers as its parameters.
>>
>> In lli.cpp in main(), define the function Callback1 and register it as
>> follows:
>>
>> EE->registerCustomCallback("Callback1",
>> (reinterpret_cast<void*(*)()>(&Callback1)));
>>
>>
>>
>> The user programs have to include the header file of the dummy library to
>> get the PerformCustomCallback symbol. To make a hypercall to "Callback1",
>> do the following:
>>
>> struct arg {
>>
>>       int arg1;
>>
>>       int arg2;
>>
>>   }Arg;
>>
>>   Arg.arg1 = 10;
>>
>>   Arg.arg2 = 20;
>>
>>
>>
>> PerformCustomCallback("Callback1", &Arg);
>>
>>
>>
>> Compile the user program (test.cc) using clang as follows:
>>
>> # clang -c -emit-llvm `llvm-config --cppflags` -o test test.cc
>> `llvm-config --libs` `llvm-config --ldflags` -lLLVMCustomCallback
>>
>>
>>
>> *Usecases:*
>>
>> A typical usecase for this is to induce LLVM into Recompiling and
>> relinking a function on demand from the client. Also, if we want to find
>> the address of a function in a large module, we can get it using a
>> mechanism like this.
>>
>>
>>
>> Please let me know if there is a better design to achieve this. I am
>> attaching the diff of the implementation for your reference.
>>
>>
>>
>> Thanks,
>>
>> Sumeeth
>>
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>
>>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131101/b61f4a67/attachment.html>


More information about the llvm-dev mailing list