summaryrefslogtreecommitdiff
path: root/src/lj_clib.c
diff options
context:
space:
mode:
authorMike Pall <mike>2011-03-01 12:31:16 +0100
committerMike Pall <mike>2011-03-01 12:31:16 +0100
commit6c43767c23ee46d28682f120b8e8bc817420fbd8 (patch)
treead109af013c515f14b28f06e02bea5588661992f /src/lj_clib.c
parente1aa8d0d9772aad198483cf9ac2794895ff07558 (diff)
downloadluajit-6c43767c23ee46d28682f120b8e8bc817420fbd8.tar.gz
luajit-6c43767c23ee46d28682f120b8e8bc817420fbd8.tar.bz2
luajit-6c43767c23ee46d28682f120b8e8bc817420fbd8.zip
FFI: Resolve ld script redirection in ffi.load().
Diffstat (limited to 'src/lj_clib.c')
-rw-r--r--src/lj_clib.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/src/lj_clib.c b/src/lj_clib.c
index d7721860..7b9b6c1a 100644
--- a/src/lj_clib.c
+++ b/src/lj_clib.c
@@ -22,6 +22,7 @@
22#if LJ_TARGET_DLOPEN 22#if LJ_TARGET_DLOPEN
23 23
24#include <dlfcn.h> 24#include <dlfcn.h>
25#include <stdio.h>
25 26
26#if defined(RTLD_DEFAULT) 27#if defined(RTLD_DEFAULT)
27#define CLIB_DEFHANDLE RTLD_DEFAULT 28#define CLIB_DEFHANDLE RTLD_DEFAULT
@@ -59,11 +60,41 @@ static const char *clib_extname(lua_State *L, const char *name)
59 return name; 60 return name;
60} 61}
61 62
63/* Quick and dirty solution to resolve shared library name from ld script. */
64static const char *clib_resolve_lds(lua_State *L, const char *name)
65{
66 FILE *fp = fopen(name, "r");
67 if (fp) {
68 char *p, *e, buf[256];
69 if (fgets(buf, sizeof(buf), fp) && !strncmp(buf, "/* GNU ld script", 16)) {
70 while (fgets(buf, sizeof(buf), fp)) {
71 if (!strncmp(buf, "GROUP", 5) && (p = strchr(buf, '('))) {
72 while (*++p == ' ') ;
73 for (e = p; *e && *e != ' ' && *e != ')'; e++) ;
74 fclose(fp);
75 return strdata(lj_str_new(L, p, e-p));
76 }
77 }
78 }
79 fclose(fp);
80 }
81 return NULL;
82}
83
62static void *clib_loadlib(lua_State *L, const char *name, int global) 84static void *clib_loadlib(lua_State *L, const char *name, int global)
63{ 85{
64 void *h = dlopen(clib_extname(L, name), 86 void *h = dlopen(clib_extname(L, name),
65 RTLD_LAZY | (global?RTLD_GLOBAL:RTLD_LOCAL)); 87 RTLD_LAZY | (global?RTLD_GLOBAL:RTLD_LOCAL));
66 if (!h) clib_error_(L); 88 if (!h) {
89 const char *e, *err = dlerror();
90 if (*err == '/' && (e = strchr(err, ':')) &&
91 (name = clib_resolve_lds(L, strdata(lj_str_new(L, err, e-err))))) {
92 h = dlopen(name, RTLD_LAZY | (global?RTLD_GLOBAL:RTLD_LOCAL));
93 if (h) return h;
94 err = dlerror();
95 }
96 lj_err_callermsg(L, err);
97 }
67 return h; 98 return h;
68} 99}
69 100