From b0a11dbbbce592f4fbb93d9dbe2256cca27ae39d Mon Sep 17 00:00:00 2001 From: "mdevan.foobar" Date: Fri, 14 Nov 2008 18:38:19 +0000 Subject: [PATCH] Added llvm.core.load_library_permanently() (Issue #12). git-svn-id: http://llvm-py.googlecode.com/svn/trunk@46 8d1e9007-1d4e-0410-b67e-1979fd6579aa --- CHANGELOG | 1 + llvm/_core.c | 30 ++++++++++++++++++++++++++++++ llvm/core.py | 16 ++++++++++++++++ llvm/extra.cpp | 15 +++++++++++++++ llvm/extra.h | 2 ++ test/testall.py | 13 +++++++++++++ 6 files changed, 77 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 92c9915..d6ff008 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ 0.4, in progress: + * Added llvm.core.load_library_permanently() (Issue #12). * Fix comparison using != (Issue #11). * Instruction.is_terminator added. * Fix Builder.select (Paulo Silva). diff --git a/llvm/_core.c b/llvm/_core.c index 1fdfaa7..415df68 100644 --- a/llvm/_core.c +++ b/llvm/_core.c @@ -917,9 +917,37 @@ _wLLVMGenericValueToFloat(PyObject *self, PyObject *args) _wrap_obj2none(LLVMDisposeGenericValue, LLVMGenericValueRef) + +/*===----------------------------------------------------------------------===*/ +/* Misc */ +/*===----------------------------------------------------------------------===*/ + _wrap_objintlist2obj(LLVMGetIntrinsic, LLVMModuleRef, LLVMTypeRef, LLVMValueRef) +static PyObject * +_wLLVMLoadLibraryPermanently(PyObject *self, PyObject *args) +{ + const char *filename; + char *outmsg; + PyObject *ret; + + if (!PyArg_ParseTuple(args, "s", &filename)) + return NULL; + + outmsg = 0; + if (!LLVMLoadLibraryPermanently(filename, &outmsg)) { + if (outmsg) { + ret = PyString_FromString(outmsg); + LLVMDisposeMessage(outmsg); + return ret; + } + } + + /* note: success => None, failure => string with error message */ + Py_RETURN_NONE; +} + /*===----------------------------------------------------------------------===*/ /* Python member method table */ @@ -1359,7 +1387,9 @@ static PyMethodDef core_methods[] = { _method( LLVMGenericValueToFloat ) _method( LLVMDisposeGenericValue ) + /* Misc */ _method( LLVMGetIntrinsic ) + _method( LLVMLoadLibraryPermanently ) { NULL } }; diff --git a/llvm/core.py b/llvm/core.py index 1fada9b..bbc1676 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -2224,3 +2224,19 @@ class MemoryBuffer(object): def __del__(self): _core.LLVMDisposeMemoryBuffer(self.ptr) + +#===----------------------------------------------------------------------=== +# Misc +#===----------------------------------------------------------------------=== + +def load_library_permanently(filename): + """Load a shared library. + + Load the given shared library (filename argument specifies the full + path of the .so file) using LLVM. Symbols from these are available + from the execution engine thereafter.""" + + ret = _core.LLVMLoadLibraryPermanently(filename) + if isinstance(ret, str): + raise llvm.LLVMException, ret + diff --git a/llvm/extra.cpp b/llvm/extra.cpp index 26da903..cf5729f 100644 --- a/llvm/extra.cpp +++ b/llvm/extra.cpp @@ -21,6 +21,7 @@ #include "llvm/IntrinsicInst.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Assembly/Parser.h" +#include "llvm/System/DynamicLibrary.h" // +includes for passes #include "llvm/PassManager.h" #include "llvm/Analysis/LoopPass.h" @@ -198,6 +199,20 @@ unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef M, unsigned *Len) return bytes; } +/* Return 0 on failure (with ErrMsg filled in), 1 on success. */ +unsigned LLVMLoadLibraryPermanently(const char* filename, char **ErrMsg) +{ + std::string msg; + + /* Note: the LLVM API returns true on failure. Don't ask why. */ + if (sys::DynamicLibrary::LoadLibraryPermanently(filename, &msg)) { + *ErrMsg = strdup(msg.c_str()); + return 0; + } + + return 1; +} + /* passes */ #define define_pass(P) \ diff --git a/llvm/extra.h b/llvm/extra.h index 41f8fe1..5f10582 100644 --- a/llvm/extra.h +++ b/llvm/extra.h @@ -83,6 +83,8 @@ LLVMModuleRef LLVMGetModuleFromBitcode(const char *BC, unsigned Len, char **OutMessage); unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef M, unsigned *Len); +unsigned LLVMLoadLibraryPermanently(const char* filename, char **ErrMsg); + /* passes */ #define declare_pass(P) \ diff --git a/test/testall.py b/test/testall.py index 179696e..f13793e 100644 --- a/test/testall.py +++ b/test/testall.py @@ -29,10 +29,23 @@ def do_ownable(): pass +def do_misc(): + print " Testing miscellaneous functions" + try: + load_library_permanently("/usr/lib/libm.so") + except LLVMException: + pass + try: + load_library_permanently("no*such*so") + except LLVMException: + pass + + def do_llvm(): print " Testing module llvm" do_llvmexception() do_ownable() + do_misc() def do_module():