diff options
| author | Mike Pall <mike> | 2011-03-01 12:31:16 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2011-03-01 12:31:16 +0100 |
| commit | 6c43767c23ee46d28682f120b8e8bc817420fbd8 (patch) | |
| tree | ad109af013c515f14b28f06e02bea5588661992f | |
| parent | e1aa8d0d9772aad198483cf9ac2794895ff07558 (diff) | |
| download | luajit-6c43767c23ee46d28682f120b8e8bc817420fbd8.tar.gz luajit-6c43767c23ee46d28682f120b8e8bc817420fbd8.tar.bz2 luajit-6c43767c23ee46d28682f120b8e8bc817420fbd8.zip | |
FFI: Resolve ld script redirection in ffi.load().
| -rw-r--r-- | src/lj_clib.c | 33 |
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. */ | ||
| 64 | static 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 | |||
| 62 | static void *clib_loadlib(lua_State *L, const char *name, int global) | 84 | static 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 | ||
