pombreda / llvm-py

Automatically exported from code.google.com/p/llvm-py
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

Add dynamic library load capability #12

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. There is no way to load external dynamic libraries into the 
execution engine.

What is the expected output? What do you see instead?

If you link against an external dynamic library like librt.so, it is
possible to load this using lli with the -load=<plugin> command.  This is
useful if you function you want to call is in a dynamic library that is not
part of you llvm source input.  If the function is not available, 
then the interpreter says that it cannot resolve the function and quits.

e.g.:

ERROR: Program used external function 'clock_gettime' which could not be
resolved!
lli[0x862f1f4]
Abort

Using llvm-py with the execution engine object has the similar output.

There needs to be access made to the call:

sys::DynamicLibrary::LoadLibraryPermanently(filename, &msg)

I created added a call and exported it to the python, so I could do:

  load_library_permanently("/usr/lib/librt.so") 

It is not super sly and does not take advantage of the use of macros with
the code, but it is nonetheless useful.

I added these lines to extra.cpp

void LoadLibraryPermanently(const char* filename, char **ErrMsg) {
  std::string msg;

  if (!sys::DynamicLibrary::LoadLibraryPermanently(filename, &msg)) {
    *ErrMsg = strdup(msg.c_str());
  }
}

And exported the function name in extra.h and added code to _core.c to move
from python to LLVM.

static PyObject *
_wLoadLibraryPermanently(PyObject *self, PyObject *args)
{
  PyObject *obj, *ret;
  char *outmsg, *filename;
  outmsg = 0;

  if (!PyArg_ParseTuple(args, "O", &obj))
        return NULL;
  filename =  PyString_AsString(obj);

  LoadLibraryPermanently(filename, &outmsg);
  if (outmsg) {
    ret = PyString_FromString(outmsg);
    // ? dispose ??
    return ret;
  } else {
    Py_RETURN_NONE;
  }
}

Finally, core.py is modified to do:

def load_library_permanently(obj):
    ret = _core.LoadLibraryPermanently(obj)
    return ret

I don't know if this how you would do this, but having this capability is
very useful.

What version of the product are you using? On what operating system?

0.3 on Ubuntu 8.04

Please provide any additional information below.

Original issue reported on code.google.com by drjustin...@gmail.com on 12 Nov 2008 at 6:17

GoogleCodeExporter commented 9 years ago
Will either of the following work instead?

from ctypes import *
cdll.LoadLibrary("libc.so.6")

-or-

import dl
dl.open("/lib/libc.so.6")

Both dl and ctypes (2.5+) are standard Python modules, please have a look.

Original comment by mdevan.f...@gmail.com on 13 Nov 2008 at 4:25

GoogleCodeExporter commented 9 years ago
Sorry, that will load them into memory, but the LLVM call is loading it as well 
as
keeping track of the symbols for linking when necessary.  I definitely need the 
LLVM
call to be able to dynamically link within the execution engine.  Using the 
other
python modules loads the files, but llvm does not have any idea they are there. 

Using either of the approaches you suggest, I get:

 ERROR: Program used external function 'clock_gettime' which could not be resolved!
Abort

But using the code outlined above, it is not a problem.

Original comment by drjustin...@gmail.com on 13 Nov 2008 at 3:19

GoogleCodeExporter commented 9 years ago
Fixed in r46. New function llvm.core.load_library_permanently(). Please check.

Original comment by mdevan.f...@gmail.com on 14 Nov 2008 at 6:44