supported mach-o/dyld loader
This commit is contained in:
parent
2aaff1b317
commit
8459db3adc
128
lib/main.c
128
lib/main.c
@ -73,6 +73,14 @@
|
||||
# define sys_dl_openext(x) dlopen(x,RTLD_NOW)
|
||||
# define sys_dl_close(x) dlclose(x)
|
||||
# define sys_dl_getsym(x,n) dlsym(x,n)
|
||||
# elif defined(__APPLE__) || defined(__MACOSX__)
|
||||
# define USE_MACH_O
|
||||
# include <mach-o/dyld.h>
|
||||
# define sys_dl_error() mach_dlerror()
|
||||
# define sys_dl_open(x) mach_dlopen(x)
|
||||
# define sys_dl_openext(x) mach_dlopen(x)
|
||||
# define sys_dl_close(x) mach_dlclose(x)
|
||||
# define sys_dl_getsym(x,n) mach_dlsym(x,n)
|
||||
# else
|
||||
# error UNSUPPORTED DYNAMIC LINKER
|
||||
# endif
|
||||
@ -97,6 +105,10 @@
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(HCL_DEFAULT_PFMODDIR)
|
||||
# define HCL_DEFAULT_PFMODDIR ""
|
||||
#endif
|
||||
|
||||
#if !defined(HCL_DEFAULT_PFMODPREFIX)
|
||||
# if defined(_WIN32)
|
||||
# define HCL_DEFAULT_PFMODPREFIX "hcl-"
|
||||
@ -119,6 +131,8 @@
|
||||
# else
|
||||
# if defined(USE_DLFCN)
|
||||
# define HCL_DEFAULT_PFMODPOSTFIX ".so"
|
||||
# elif defined(USE_MACH_O)
|
||||
# define HCL_DEFAULT_PFMODPOSTFIX ".dylib"
|
||||
# else
|
||||
# define HCL_DEFAULT_PFMODPOSTFIX ""
|
||||
# endif
|
||||
@ -762,10 +776,84 @@ static void syserrstrb (hcl_t* hcl, int syserr, hcl_bch_t* buf, hcl_oow_t len)
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
#if defined(USE_MACH_O)
|
||||
static const char* mach_dlerror_str = "";
|
||||
|
||||
static void* mach_dlopen (const char* path)
|
||||
{
|
||||
NSObjectFileImage image;
|
||||
NSObjectFileImageReturnCode rc;
|
||||
void* handle;
|
||||
|
||||
mach_dlerror_str = "";
|
||||
if ((rc = NSCreateObjectFileImageFromFile(path, &image)) != NSObjectFileImageSuccess)
|
||||
{
|
||||
switch (rc)
|
||||
{
|
||||
case NSObjectFileImageFailure:
|
||||
case NSObjectFileImageFormat:
|
||||
mach_dlerror_str = "unable to crate object file image";
|
||||
break;
|
||||
|
||||
case NSObjectFileImageInappropriateFile:
|
||||
mach_dlerror_str = "inappropriate file";
|
||||
break;
|
||||
|
||||
case NSObjectFileImageArch:
|
||||
mach_dlerror_str = "incompatible architecture";
|
||||
break;
|
||||
|
||||
case NSObjectFileImageAccess:
|
||||
mach_dlerror_str = "inaccessible file";
|
||||
break;
|
||||
|
||||
default:
|
||||
mach_dlerror_str = "unknown error";
|
||||
break;
|
||||
}
|
||||
return HCL_NULL;
|
||||
}
|
||||
handle = (void*)NSLinkModule(image, path, NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR);
|
||||
NSDestroyObjectFileImage (image);
|
||||
return handle;
|
||||
}
|
||||
|
||||
static HCL_INLINE void mach_dlclose (void* handle)
|
||||
{
|
||||
mach_dlerror_str = "";
|
||||
NSUnLinkModule (handle, NSUNLINKMODULE_OPTION_NONE);
|
||||
}
|
||||
|
||||
static HCL_INLINE void* mach_dlsym (void* handle, const char* name)
|
||||
{
|
||||
mach_dlerror_str = "";
|
||||
return (void*)NSAddressOfSymbol(NSLookupSymbolInModule(handle, name));
|
||||
}
|
||||
|
||||
static const char* mach_dlerror (void)
|
||||
{
|
||||
int err_no;
|
||||
const char* err_file;
|
||||
NSLinkEditErrors err;
|
||||
|
||||
if (mach_dlerror_str[0] == '\0')
|
||||
NSLinkEditError (&err, &err_no, &err_file, &mach_dlerror_str);
|
||||
|
||||
return mach_dlerror_str;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_WIN32) || defined(__DOS__) || defined(__OS2__)
|
||||
/* TODO: handle drive letter and UNC notations? */
|
||||
# define IS_PATH_ABSOLUTE(x) (x[0] == '/' || x[0] == '\\')
|
||||
#else
|
||||
# define IS_PATH_ABSOLUTE(x) (x[0] == '/')
|
||||
#endif
|
||||
|
||||
static void* dl_open (hcl_t* hcl, const hcl_ooch_t* name, int flags)
|
||||
{
|
||||
#if defined(USE_LTDL) || defined(USE_DLFCN)
|
||||
#if defined(USE_LTDL) || defined(USE_DLFCN) || defined(USE_MACH_O)
|
||||
hcl_bch_t stabuf[128], * bufptr;
|
||||
hcl_oow_t ucslen, bcslen, bufcapa;
|
||||
void* handle;
|
||||
@ -778,7 +866,7 @@ static void* dl_open (hcl_t* hcl, const hcl_ooch_t* name, int flags)
|
||||
#else
|
||||
bufcapa = hcl_count_bcstr(name);
|
||||
#endif
|
||||
bufcapa += HCL_COUNTOF(HCL_DEFAULT_PFMODPREFIX) + HCL_COUNTOF(HCL_DEFAULT_PFMODPOSTFIX) + 1;
|
||||
bufcapa += HCL_COUNTOF(HCL_DEFAULT_PFMODDIR) + HCL_COUNTOF(HCL_DEFAULT_PFMODPREFIX) + HCL_COUNTOF(HCL_DEFAULT_PFMODPOSTFIX) + 1;
|
||||
|
||||
if (bufcapa <= HCL_COUNTOF(stabuf)) bufptr = stabuf;
|
||||
else
|
||||
@ -789,10 +877,14 @@ static void* dl_open (hcl_t* hcl, const hcl_ooch_t* name, int flags)
|
||||
|
||||
if (flags & HCL_VMPRIM_DLOPEN_PFMOD)
|
||||
{
|
||||
hcl_oow_t len, i, xlen;
|
||||
hcl_oow_t len, i, xlen, dlen;
|
||||
|
||||
/* opening a primitive function module - mostly libhcl-xxxx */
|
||||
/* opening a primitive function module - mostly libhcl-xxxx.
|
||||
* if PFMODPREFIX is absolute, never use PFMODDIR */
|
||||
dlen = IS_PATH_ABSOLUTE(HCL_DEFAULT_PFMODPREFIX)?
|
||||
0: hcl_copy_bcstr(bufptr, bufcapa, HCL_DEFAULT_PFMODDIR);
|
||||
len = hcl_copy_bcstr(bufptr, bufcapa, HCL_DEFAULT_PFMODPREFIX);
|
||||
len += dlen;
|
||||
|
||||
bcslen = bufcapa - len;
|
||||
#if defined(HCL_OOCH_IS_UCH)
|
||||
@ -801,7 +893,7 @@ static void* dl_open (hcl_t* hcl, const hcl_ooch_t* name, int flags)
|
||||
bcslen = hcl_copy_bcstr(&bufptr[len], bcslen, name);
|
||||
#endif
|
||||
|
||||
/* length including the prefix and the name. but excluding the postfix */
|
||||
/* length including the directory, the prefix and the name. but excluding the postfix */
|
||||
xlen = len + bcslen;
|
||||
|
||||
for (i = len; i < xlen; i++)
|
||||
@ -817,7 +909,14 @@ static void* dl_open (hcl_t* hcl, const hcl_ooch_t* name, int flags)
|
||||
handle = sys_dl_openext(bufptr);
|
||||
if (!handle)
|
||||
{
|
||||
HCL_DEBUG3 (hcl, "Failed to open(ext) DL %hs[%js] - %hs\n", bufptr, name, sys_dl_error());
|
||||
HCL_DEBUG3 (hcl, "Unable to open(ext) PFMOD %hs[%js] - %hs\n", &bufptr[dlen], name, sys_dl_error());
|
||||
|
||||
if (dlen > 0)
|
||||
{
|
||||
handle = sys_dl_openext(&bufptr[0]);
|
||||
if (handle) goto pfmod_open_ok;
|
||||
HCL_DEBUG3 (hcl, "Unable to open(ext) PFMOD %hs[%js] - %hs\n", &bufptr[0], name, sys_dl_error());
|
||||
}
|
||||
|
||||
/* try without prefix and postfix */
|
||||
bufptr[xlen] = '\0';
|
||||
@ -827,8 +926,8 @@ static void* dl_open (hcl_t* hcl, const hcl_ooch_t* name, int flags)
|
||||
hcl_bch_t* dash;
|
||||
const hcl_bch_t* dl_errstr;
|
||||
dl_errstr = sys_dl_error();
|
||||
HCL_DEBUG3 (hcl, "Failed to open(ext) DL %hs[%js] - %hs\n", &bufptr[len], name, dl_errstr);
|
||||
hcl_seterrbfmt (hcl, HCL_ESYSERR, "unable to open(ext) DL %js - %hs", name, dl_errstr);
|
||||
HCL_DEBUG3 (hcl, "Unable to open(ext) PFMOD %hs[%js] - %hs\n", &bufptr[len], name, dl_errstr);
|
||||
hcl_seterrbfmt (hcl, HCL_ESYSERR, "unable to open(ext) PFMOD %js - %hs", name, dl_errstr);
|
||||
|
||||
dash = hcl_rfind_bchar(bufptr, hcl_count_bcstr(bufptr), '-');
|
||||
if (dash)
|
||||
@ -843,12 +942,13 @@ static void* dl_open (hcl_t* hcl, const hcl_ooch_t* name, int flags)
|
||||
}
|
||||
else
|
||||
{
|
||||
HCL_DEBUG3 (hcl, "Opened(ext) DL %hs[%js] handle %p\n", &bufptr[len], name, handle);
|
||||
HCL_DEBUG3 (hcl, "Opened(ext) PFMOD %hs[%js] handle %p\n", &bufptr[len], name, handle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HCL_DEBUG3 (hcl, "Opened(ext) DL %hs[%js] handle %p\n", bufptr, name, handle);
|
||||
pfmod_open_ok:
|
||||
HCL_DEBUG3 (hcl, "Opened(ext) PFMOD %hs[%js] handle %p\n", &bufptr[dlen], name, handle);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -868,7 +968,7 @@ static void* dl_open (hcl_t* hcl, const hcl_ooch_t* name, int flags)
|
||||
{
|
||||
const hcl_bch_t* dl_errstr;
|
||||
dl_errstr = sys_dl_error();
|
||||
HCL_DEBUG2 (hcl, "Failed to open DL %hs - %hs\n", bufptr, dl_errstr);
|
||||
HCL_DEBUG2 (hcl, "Unable to open DL %hs - %hs\n", bufptr, dl_errstr);
|
||||
hcl_seterrbfmt (hcl, HCL_ESYSERR, "unable to open DL %js - %hs", name, dl_errstr);
|
||||
}
|
||||
else HCL_DEBUG2 (hcl, "Opened DL %hs handle %p\n", bufptr, handle);
|
||||
@ -880,7 +980,7 @@ static void* dl_open (hcl_t* hcl, const hcl_ooch_t* name, int flags)
|
||||
{
|
||||
const hcl_bch_t* dl_errstr;
|
||||
dl_errstr = sys_dl_error();
|
||||
HCL_DEBUG2 (hcl, "Failed to open(ext) DL %hs - %s\n", bufptr, dl_errstr);
|
||||
HCL_DEBUG2 (hcl, "Unable to open(ext) DL %hs - %s\n", bufptr, dl_errstr);
|
||||
hcl_seterrbfmt (hcl, HCL_ESYSERR, "unable to open(ext) DL %js - %hs", name, dl_errstr);
|
||||
}
|
||||
else HCL_DEBUG2 (hcl, "Opened(ext) DL %hs handle %p\n", bufptr, handle);
|
||||
@ -902,7 +1002,7 @@ static void* dl_open (hcl_t* hcl, const hcl_ooch_t* name, int flags)
|
||||
|
||||
static void dl_close (hcl_t* hcl, void* handle)
|
||||
{
|
||||
#if defined(USE_LTDL) || defined(USE_DLFCN)
|
||||
#if defined(USE_LTDL) || defined(USE_DLFCN) || defined(USE_MACH_O)
|
||||
HCL_DEBUG1 (hcl, "Closed DL handle %p\n", handle);
|
||||
sys_dl_close (handle);
|
||||
|
||||
@ -914,7 +1014,7 @@ static void dl_close (hcl_t* hcl, void* handle)
|
||||
|
||||
static void* dl_getsym (hcl_t* hcl, void* handle, const hcl_ooch_t* name)
|
||||
{
|
||||
#if defined(USE_LTDL) || defined(USE_DLFCN)
|
||||
#if defined(USE_LTDL) || defined(USE_DLFCN) || defined(USE_MACH_O)
|
||||
hcl_bch_t stabuf[64], * bufptr;
|
||||
hcl_oow_t bufcapa, ucslen, bcslen, i;
|
||||
const hcl_bch_t* symname;
|
||||
|
Loading…
x
Reference in New Issue
Block a user