[LLVMdev] Lightweight code loader

Chris Lattner sabre at nondot.org
Wed Jun 1 23:21:08 PDT 2005


On Fri, 27 May 2005, Alexander Friedman wrote:
>> something that must be ported, please add it to lib/System
>
> Sure. What counts as a 'native call' ? :)

You are allowed to use anything in the *C++* standard library without 
fear.  This includes <cstdlib> and friends.  Anything not in the C++ 
standard must be dealt with by lib/System.

>> (3) Your patch should be an incremental add to LLVM, not removing any
>> existing JIT functionality.
>
> I was actually going to make something orthogonal to the JIT. It would
> not support nearly as much functionality as the JIT (though it would
> have similar code).

Yeah, that makes sense.

> Here is a very loose use case - does this seem reasonable?
>
> ****
>
>  #include modulecompiler
>
>  #include module_loader
>
>  char * countdown_function =
>    "int %countdown (int %AnArg) {\n"
>    " %result = call fastcc int %foo-int (int %AnArg) \n"
>    " ret int %result\n"
>    "}\n"
>    "fastcc int %foo-int (int %AnArg) {\n"
>    "EntryBlock:\n"
>    "  %cond = setle int %AnArg, 2\n"
>    "  br bool %cond, label %return, label %recur\n"
>    "return:\n"
>    "  ret int 1\n"
>    "recur:\n"
>    "  %sub1 = sub int %AnArg, 1\n"
>    "  %result = tail call fastcc int %foo-int (int %sub1)\n"
>    "  ret int %result\n"
>    "}\n"
>
>
>  Module * M = parseAsmText(countdown_function);
>
>  RelocatableCode * code = compileModule(M);
>
>  WriteRelocatableCodeToFile (code,"file");

Yes, something like this makes sense.


>  // now load. This part should be as light as possible - that is, very small
>  // in size of the compiled binary. The resulting "module" is fairly static, not like
>  // standard llvm modules.
>
>  // should be able to get pointers to functions and change value of
>  // global pointers.

What do you mean change the value of global pointers?  You mean external 
globals or the address of things defined in the module?  The first case 
shouldn't be hard, the later might be tougher (not sure).

>  NativeModule * mod = ReadAndRelocateCodeFromFile ("file");

Proba also needs some way to get information on the address of symbols.

>  int (* countdown) (int);
>
>  countdown = (int (*)(int)) GetPointerToFunction("countdown",mod);
>
>  printf("result of countdown: %d\n", countdown (1000000));

This makes sense.

> ***
>
> There are a few problems that I need some input on.
>
> First, I want the loader to be as tiny as possible. So, I don't want
> to link in VMcore and friends.  Is it possible to just link in
> selected object files instead of entire libraries?

No not really.

I think what you really want to do is write two things:

1. A traditional LLVM library that look similar to the JIT stuff that
    writes out the file.  This would write it out in some well-defined
    format that preserves the code and the relocations.
2. A very simple and light-weight library (maybe written in C?) that has
    no dependencies on the other llvm libraries, including VMCore, Support
    and maybe lib/system.

    This library just mmaps the well-defined file written by #1, applies
    the relocations, and away it goes.  The problems with this are: a) it
    will have to be ported to different platforms if it doesn't use
    lib/system.  b) it will have to be ported to different targets if it
    doesn't use the target-specific lib/Target support for relocations.

At this stage, the natural question is: why write #2 at all?

In particular, if your well-defined format written by #1 is something 
like, say, the ELF .so format, you just turn #2 into dlopen/dlsym and 
friends (which just mmaps and relocates).  This seems like the right way 
to go unless you have a strong reason not to.  This also solves the 
problems with #2 listed above.

> Second, there is functionality that the loader needs to have that
> depends on VMCore, but doesn't actually need it for my purposes. The
> main thing is the 'relocate' function in each (System)JITInfo.cpp
> file.

Yes, this is really a symptom of #2 above.  The harder part is the 
target-specific stuff that knows how to apply the target-specific 
relocations.

> I would like to be able to get the correct JITInfo object (really just 
> the function) without having to link in extra stuff, instantiate 
> modules,targets, etc. Ideally this would not require duplicating any 
> code :) How does one go about doing this?

No good way.  :(

-Chris

-- 
http://nondot.org/sabre/
http://llvm.cs.uiuc.edu/




More information about the llvm-dev mailing list