diff --git a/Interpreter.hs b/Interpreter.hs index f6096a0..3b3ecc8 100644 --- a/Interpreter.hs +++ b/Interpreter.hs @@ -1,14 +1,33 @@ module Main where -import System.Environment -import IServ.Remote.Message -import IServ.Remote.Interpreter +import IServ.Remote.Interpreter (startInterpreter') +import System.Environment (getArgs, getProgName) +import System.Exit (die) -verbose :: Bool -verbose = False +import Control.Monad (when) main :: IO () -main = do - [portStr, storagePath] <- getArgs - let port = read portStr - startInterpreter' verbose storagePath port +main = getArgs >>= startSlave + +dieWithUsage :: IO a +dieWithUsage = do + prog <- getProgName + die $ msg prog + where + msg name = "usage: " ++ name ++ " /path/to/storage PORT [-v] [--no-load-call]" + +startSlave :: [String] -> IO () +startSlave args0 + | "--help" `elem` args0 = dieWithUsage + | otherwise = do + (path, port, rest) <- case args0 of + arg0:arg1:rest -> return (arg0, read arg1, rest) + _ -> dieWithUsage + + let verbose = "-v" `elem` rest + noLoadCall = "--no-load-call" `elem` rest + + when (any (not . (`elem` ["-v", "--no-load-call"])) rest) + dieWithUsage + + startInterpreter' verbose noLoadCall path port diff --git a/Main.hs b/Main.hs index a4c0d04..42124d2 100644 --- a/Main.hs +++ b/Main.hs @@ -98,10 +98,11 @@ main = do return (wfd1, rfd2, ip, port, rest) _ -> dieWithUsage - verbose <- case rest of - ["-v"] -> return True - [] -> return False - _ -> dieWithUsage + let verbose = "-v" `elem` rest + noLoadCall = "--no-load-call" `elem` rest + + when (any (not . (`elem` ["-v", "--no-load-call"])) rest) + dieWithUsage when verbose $ printf "GHC iserv starting (in: %d; out: %d)\n" @@ -109,8 +110,12 @@ main = do inh <- getGhcHandle rfd2 outh <- getGhcHandle wfd1 installSignalHandlers +#if MIN_VERSION_ghci(9,13,0) + in_pipe <- mkPipeFromHandles inh outh +#else lo_ref <- newIORef Nothing let in_pipe = Pipe{pipeRead = inh, pipeWrite = outh, pipeLeftovers = lo_ref} +#endif when verbose $ trace ("Trying to connect to " ++ host_ip ++ ":" ++ (show port)) @@ -124,7 +129,7 @@ main = do when verbose $ trace "Starting proxy" - proxy verbose in_pipe out_pipe + proxy verbose noLoadCall in_pipe out_pipe -- | A hook, to transform outgoing (proxy -> interpreter) -- messages prior to sending them to the interpreter. @@ -141,8 +146,16 @@ hook = return -- fwdTHMsg :: (Binary a) => Pipe -> THMessage a -> IO a fwdTHMsg local msg = do - writePipe local (putTHMessage msg) - readPipe local get + writePipe local (putTHMessage (fixAddDep msg)) + readPipe local get + where + fixAddDep (AddDependentFile fp) = AddDependentFile $ fixZ (map fixSlash fp) + fixAddDep m = m + fixZ ('Z':':':rest) = rest + fixZ ('/':'/':'?':'/':'Z':':':rest) = rest + fixZ fp = fp + fixSlash '\\' = '/' + fixSlash c = c -- | Fowarard a @Message@ call and handle @THMessages@. fwdTHCall :: (Binary a) => Bool -> Pipe -> Pipe -> Message a -> IO a @@ -199,7 +212,7 @@ fwdLoadCall verbose _ remote msg = do writePipe remote (put m) loopLoad :: IO () loopLoad = do - when verbose $ trace "fwdLoadCall: reading remote pipe" + when verbose $ trace "fwdLoadCall: X reading remote pipe" SomeProxyMessage msg' <- readPipe remote getProxyMessage when verbose $ trace ("| Sl Msg: proxy <- interpreter: " ++ show msg') @@ -219,8 +232,8 @@ fwdLoadCall verbose _ remote msg = do -- | The actual proxy. Conntect local and remote pipe, -- and does some message handling. -proxy :: Bool -> Pipe -> Pipe -> IO () -proxy verbose local remote = loop +proxy :: Bool -> Bool -> Pipe -> Pipe -> IO () +proxy verbose noLoadCall local remote = loop where fwdCall :: (Binary a, Show a) => Message a -> IO a fwdCall msg = do @@ -275,7 +288,7 @@ proxy verbose local remote = loop -- that are referenced in C:\ these are usually system libraries. LoadDLL path@('C':':':_) -> do fwdCall msg' >>= reply >> loop - LoadDLL path | isAbsolute path -> do + LoadDLL path | isAbsolute path && not noLoadCall -> do resp <- fwdLoadCall verbose local remote msg' reply resp loop @@ -307,5 +320,9 @@ socketToPipe sock = do hdl <- socketToHandle sock ReadWriteMode hSetBuffering hdl NoBuffering +#if MIN_VERSION_ghci(9,13,0) + mkPipeFromHandles hdl hdl +#else lo_ref <- newIORef Nothing pure Pipe{ pipeRead = hdl, pipeWrite = hdl, pipeLeftovers = lo_ref } +#endif diff --git a/cbits/symbols.aarch64-android.c b/cbits/symbols.aarch64-android.c new file mode 100644 index 0000000..f8c2a8e --- /dev/null +++ b/cbits/symbols.aarch64-android.c @@ -0,0 +1,493 @@ +#ifdef __ANDROID__ +#define BIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +// #include // this includes too many overloaded items. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// fnctl stubs, see above +extern void open(void); +extern void openat(void); +extern void creat(void); +extern void eventfd(void); +extern void eventfd_write(void); + +extern void futimes(void); +extern void lutimes(void); +extern void statx(void); + +extern void __stack_chk_fail(void); +extern void __vsprintf_chk(void); +extern void __open_2(void); +extern void __memcpy_chk(void); +extern void __memset_chk(void); +extern void __memmove_chk(void); +// GCC stuff +extern void __addtf3(void); +extern void __divtf3(void); +extern void __extenddftf2(void); +extern void __fixtfsi(void); +extern void __floatditf(void); +extern void __floatsitf(void); +extern void __getf2(void); +extern void __gttf2(void); +extern void __lttf2(void); +extern void __multf3(void); +extern void __subtf3(void); +extern void __trunctfdf2(void); + +extern void flock(void); +extern void times(void); + +extern void uname(void); +extern void sem_post(void); +extern void __gnu_strerror_r(void); +extern void async_safe_format_buffer(void); +extern void sem_trywait(void); +extern void sem_wait(void); +extern void sem_unlink(void); +extern void sem_close(void); +extern void sem_open(void); +extern void sem_getvalue(void); +extern void dlclose(void); +extern void dlerror(void); +extern void dlsym(void); +extern void dlopen(void); +extern void fallocate(void); +extern void posix_fallocate(void); +extern void __fadvise64(void); +extern void posix_fadvise(void); +extern void async_safe_fatal_no_abort(void); +extern void __vsnprintf_chk(void); +extern void openpty(void); +extern void __getpriority(void); +extern void * _Unwind_Resume; +extern void __emutls_get_address(void); +//extern void __sF(void); +extern void __sflush(void); +extern void __eqtf2(void); +extern void __ldtoa(void); +extern void __vfprintf(void); +//extern void _Unwind_SetGR(void); +//extern void _Unwind_SetIP(void); +//extern void _Unwind_GetLanguageSpecificData(void); +//extern void _Unwind_GetIP(void); +//extern void _Unwind_GetRegionStart(void); +void * __gxx_personality_v0; +extern void __cxa_guard_acquire(void); +extern void __cxa_guard_release(void); +extern void __strncpy_chk(void); + +#define MISSING_FUN(f) void (f)(void) { printf("Unknown call to `%s'\n", #f); exit(1); } + +MISSING_FUN(c_format_unix_time) +MISSING_FUN(c_format_unix_time_gmt) +MISSING_FUN(c_parse_unix_time) +MISSING_FUN(c_parse_unix_time_gmt) +MISSING_FUN(abort_message) +//MISSING_FUN(__cxa_unexpected_handler) +MISSING_FUN(__cxa_begin_catch) +MISSING_FUN(_ZSt9terminatev) +//MISSING_FUN(_ZN10__cxxabiv130__aligned_malloc_with_fallbackEm) +//MISSING_FUN(_ZN10__cxxabiv119__getExceptionClassEPK17_Unwind_Exception) +//MISSING_FUN(_ZSt11__terminatePFvvE) +// MISSINF_FUN(__gxx_personality_v0) + +typedef void SymbolAddr; +typedef char SymbolName; + +typedef enum _SymStrength { + STRENGTH_NORMAL, + STRENGTH_WEAK, + STRENGTH_STRONG, +} SymStrength; + +typedef enum _SymType { + SYM_TYPE_CODE = 1 << 0, /* the symbol is a function and can be relocated via a jump island */ + SYM_TYPE_DATA = 1 << 1, /* the symbol is data */ + SYM_TYPE_INDIRECT_DATA = 1 << 2, /* see Note [_iob_func symbol] */ + SYM_TYPE_DUP_DISCARD = 1 << 3, /* the symbol is a symbol in a BFD import library + however if a duplicate is found with a mismatching + SymType then discard this one. */ +} SymType; + +typedef struct _RtsSymbolVal { + const SymbolName* lbl; + SymbolAddr* addr; + SymStrength strength; + SymType type; +} RtsSymbolVal; + +#define SYM(x) { #x, (void*)(&x), STRENGTH_NORMAL, 1 } +typedef mode_t (*umask_func_ptr_t)(mode_t); + +RtsSymbolVal my_iserv_syms[] = { + // arpa/inet.h + SYM(htons), + SYM(ntohs), + SYM(htonl), + SYM(ntohl), + // sys/random.h + SYM(getentropy), + SYM(getrandom), + // sys/auxv.h + SYM(getauxval), + // sys/mman.h + SYM(madvise),SYM(mlock),SYM(mmap),SYM(mprotect),SYM(munmap), + SYM(mremap), + SYM(munlock), + // select.h + SYM(__FD_SET_chk), + // sys/socket + SYM(accept),SYM(bind),SYM(connect),SYM(getsockopt),SYM(listen), + SYM(setsockopt),SYM(socket),SYM(getsockname),SYM(select), + SYM(getpeername),SYM(__cmsg_nxthdr),SYM(recv),SYM(recvfrom), + SYM(recvmsg),SYM(send),SYM(sendmsg),SYM(sendto),SYM(writev), + SYM(accept4), + // pthread.h + SYM(pthread_equal),SYM(pthread_getspecific),SYM(pthread_key_create), + SYM(pthread_key_delete),SYM(pthread_once),SYM(pthread_rwlock_destroy), + SYM(pthread_rwlock_init),SYM(pthread_rwlock_rdlock),SYM(pthread_rwlock_unlock), + SYM(pthread_rwlock_wrlock),SYM(pthread_self),SYM(pthread_setspecific), + SYM(pthread_create),SYM(pthread_join),SYM(pthread_mutex_destroy), + SYM(pthread_mutex_init),SYM(pthread_mutex_lock),SYM(pthread_mutex_trylock), + SYM(pthread_mutex_unlock),SYM(pthread_mutexattr_destroy), + SYM(pthread_mutexattr_init),SYM(pthread_mutexattr_settype), + // chk.h + SYM(__read_chk),SYM(__write_chk), + // netdb.h + SYM(freeaddrinfo),SYM(gai_strerror),SYM(getaddrinfo),SYM(getnameinfo), + SYM(gethostbyname), + // dirent.h + SYM(readdir_r),SYM(readdir), + SYM(opendir),SYM(closedir), + // time.h + SYM(clock),SYM(gmtime_r), + // sys/time.h + SYM(gettimeofday),SYM(clock_getres),SYM(clock_gettime),SYM(localtime_r),SYM(tzset), + // unistd.h + SYM(readlink), + SYM(rename), + SYM(rmdir), + SYM(chown), + SYM(realpath), + SYM(fchdir), + SYM(fdopendir), + SYM(rewinddir), + SYM(futimens),SYM(futimes),SYM(lutimes), + SYM(mknod), + SYM(lchown), + SYM(symlink), + SYM(endgrent),SYM(endpwent), + SYM(pathconf), + SYM(truncate), + SYM(utimensat), + SYM(statx), + SYM(seekdir), + SYM(telldir), + SYM(clearenv), + SYM(chdir), + SYM(sleep), + SYM(stdout), + SYM(strftime), + SYM(utimes), + SYM(times), + SYM(setenv), + SYM(fpathconf), + SYM(exit), + SYM(environ), + SYM(ftruncate), + SYM(getenv), + SYM(putenv), + SYM(unsetenv), + SYM(read), + SYM(write), + SYM(isatty), + SYM(link), + SYM(pipe), + SYM(unlink), + SYM(execv),SYM(execve),SYM(execvp),SYM(execvpe), + SYM(syscall),SYM(sysconf), + // errno.h + SYM(__errno), + // math.h + SYM(sinhf), SYM(sinh), SYM(sinf), SYM(sin), + SYM(coshf), SYM(cosh), SYM(cosf), SYM(cos), + SYM(atanhf), SYM(atanh), SYM(atanf), SYM(atan), + SYM(asinhf), SYM(asinh), SYM(asinf), SYM(asin), + SYM(acoshf), SYM(acosh), SYM(acosf), SYM(acos), + SYM(log1pf), SYM(log1p), SYM(logf), SYM(log), + SYM(expm1f), SYM(expm1), + SYM(expf), SYM(exp), + SYM(ldexp), + SYM(powf), SYM(pow), + SYM(sqrtf), SYM(sqrt), + SYM(tanhf), SYM(tanh), SYM(tanf), SYM(tan), + // assert.h + SYM(__assert2), + // signal.h + SYM(signal),SYM(sigaction), + SYM(raise), SYM(sigaddset), SYM(sigemptyset), SYM(sigprocmask), + // sys/eventfd.h + SYM(eventfd), SYM(eventfd_write), + // sys/stat.h + SYM(fstat), + SYM(lstat), + SYM(stat), + SYM(chmod), + SYM(mkfifo), + // SYM(umask), + { "umask", (umask_func_ptr_t)(&umask), STRENGTH_NORMAL, 1 }, + // sys/wait.h + SYM(waitpid), + // sym/epoll.h + SYM(epoll_create), SYM(epoll_ctl), SYM(epoll_wait), + // poll.h + SYM(poll), + // fcntl.h + SYM(open), SYM(creat), SYM(fcntl), SYM(ioctl), + SYM(openat),SYM(__open_2), + // string.h + SYM(strerror), + SYM(strerror_r), + SYM(strcmp), + SYM(memchr),SYM(strcpy),SYM(strchr),SYM(strncpy),SYM(strrchr), + SYM(strcat),SYM(strncmp),SYM(strdup), + SYM(strtoul),SYM(strspn),SYM(strtol),SYM(strstr),SYM(strcspn), + SYM(__strncpy_chk),SYM(__strncpy_chk2),SYM(__memcpy_chk), + // ctype.h + SYM(__ctype_get_mb_cur_max), + // wchar.h + SYM(mbrtowc), SYM(wcrtomb), + // stdlib.h + SYM(qsort), + // unistd.h + SYM(access), SYM(close), SYM(dup), SYM(dup2), SYM(fork), SYM(getpid), + SYM(lseek), + // utime.h + SYM(utime),SYM(time), + // ... + SYM(fileno), + SYM(__vsprintf_chk), + SYM(__strlen_chk), + SYM(__strchr_chk), + SYM(__memset_chk), + SYM(__memmove_chk), + SYM(__memchr_chk), + SYM(__stack_chk_fail), + SYM(memmove), + SYM(memcmp), + SYM(memcpy), + SYM(memset), + SYM(stderr), + SYM(realloc), + SYM(calloc), + SYM(malloc), + SYM(free), + SYM(fprintf), + SYM(vfprintf), + SYM(fopen), SYM(fclose), + SYM(flock), + SYM(getegid),SYM(getgid), + SYM(getpwent), + SYM(getgrent), + SYM(getgroups), + SYM(getlogin), + SYM(getuid), + SYM(getgrgid_r),SYM(getgrnam_r),SYM(getpwnam_r),SYM(getpwuid_r), + SYM(setegid),SYM(seteuid),SYM(setgid),SYM(setgrent),SYM(setgroups), + SYM(setpwent),SYM(setuid), + SYM(fread), + SYM(abort), + SYM(strlen), + SYM(fwrite), + SYM(feof), + SYM(ferror), + SYM(fflush), + SYM(fgets),SYM(fputc),SYM(fputs), + SYM(puts), + SYM(fseek),SYM(ftell), + SYM(sscanf), + SYM(shutdown), + SYM(atoi), + SYM(stdin), + SYM(atexit), + SYM(usleep), + SYM(fchmod), + SYM(fchown), + SYM(fsync), + SYM(getcwd), + SYM(geteuid), + SYM(localtime), + SYM(lseek64), + SYM(mkdir), + SYM(mktime), + SYM(fdopen), + SYM(c_format_unix_time), + SYM(c_format_unix_time_gmt), + SYM(c_parse_unix_time), + SYM(c_parse_unix_time_gmt), + SYM(__addtf3), + SYM(__divtf3), + SYM(__extenddftf2), + SYM(__fixtfsi), + SYM(__floatditf), + SYM(__floatsitf), + SYM(__getf2), + SYM(__gttf2), + SYM(__lttf2), + SYM(__multf3), + SYM(__subtf3), + SYM(__trunctfdf2), + SYM(getrusage), + SYM(tcsetattr), + SYM(tcgetattr), + SYM(setrlimit), + SYM(getrlimit), + SYM(uname), + SYM(fdatasync), + SYM(nanosleep), + SYM(kill), + SYM(killpg), + SYM(sigpending), + SYM(sigsuspend), + SYM(setitimer), + SYM(alarm), + SYM(sigismember), + SYM(sigfillset), + SYM(sigdelset), + SYM(__gnu_strerror_r), + SYM(async_safe_format_buffer), + SYM(android_get_application_target_sdk_version), + SYM(sem_post), + SYM(sem_trywait), + SYM(sem_wait), + SYM(sem_unlink), + SYM(sem_close), + SYM(sem_open), + SYM(sem_getvalue), + SYM(dlclose), + SYM(dlerror), + SYM(dlsym), + SYM(dlopen), + SYM(fallocate), + SYM(posix_fallocate), + SYM(__fadvise64), + SYM(posix_fadvise), + SYM(async_safe_fatal_no_abort), + SYM(arc4random_buf), + SYM(mkdtemp), + SYM(mkstemps), + SYM(mkstemp), + SYM(__vsnprintf_chk), + SYM(ttyname), + SYM(openpty), + SYM(ptsname), + SYM(ctermid), + SYM(getppid), + SYM(getpgid), + SYM(getpgrp), + SYM(setsid), + SYM(setpgid), + SYM(setpriority), + SYM(__getpriority), + SYM(getpriority), + SYM(tcgetpgrp), + SYM(tcsetpgrp), + SYM(tcflow), + SYM(tcflush), + SYM(tcdrain), + SYM(tcsendbreak), + SYM(cfsetospeed), + SYM(cfgetospeed), + SYM(cfsetispeed), + SYM(cfgetispeed), + SYM(_Unwind_Resume), +// SYM(posix_memalign), + SYM(__emutls_get_address), +// SYM(__sF), + SYM(__sflush), + SYM(__eqtf2), + SYM(__ldtoa), + SYM(__vfprintf), + SYM(vasprintf), + SYM(abort_message), +// SYM(__cxa_unexpected_handler), + SYM(_ZSt9terminatev), +// SYM(_ZN10__cxxabiv130__aligned_malloc_with_fallbackEm), + SYM(__cxa_begin_catch), +// SYM(_Unwind_SetGR), +// SYM(_Unwind_SetIP), +// SYM(_Unwind_GetLanguageSpecificData), +// SYM(_Unwind_GetIP), +// SYM(_Unwind_GetRegionStart), +// SYM(_ZN10__cxxabiv119__getExceptionClassEPK17_Unwind_Exception), +// SYM(_ZSt11__terminatePFvvE), + SYM(__gxx_personality_v0), + SYM(__fwrite_chk), + SYM(timezone), + SYM(sendmsg), + SYM(sendmmsg), + SYM(recvmmsg), + SYM(__strrchr_chk), +// SYM(__loader_add_thread_local_dtor), +// SYM(__cxa_thread_finalize), + SYM(pthread_exit), + SYM(__poll_chk), + SYM(pthread_cond_wait), + SYM(__cxa_guard_acquire), + SYM(__cxa_guard_release), + SYM(pthread_cond_signal), + SYM(pthread_cond_broadcast), + SYM(pthread_cond_init), + SYM(pthread_cond_timedwait), + SYM(pthread_cond_destroy), + SYM(pthread_attr_init), + SYM(pthread_attr_setdetachstate), + SYM(pthread_attr_destroy), + SYM(nice), + SYM(unlinkat), + SYM(fchmodat), + SYM(fstatat), + SYM(floor), + { 0, 0, STRENGTH_NORMAL, 1 } /* sentinel */ +}; + +RtsSymbolVal* iserv_syms() { + return my_iserv_syms; +} + +// Name used in GHC >=9.12 +RtsSymbolVal* rtsExtraSyms() { + return my_iserv_syms; +} +#endif diff --git a/cbits/symbols.aarch64-musl.c b/cbits/symbols.aarch64-musl.c new file mode 100644 index 0000000..a161cf5 --- /dev/null +++ b/cbits/symbols.aarch64-musl.c @@ -0,0 +1,57 @@ +#ifndef __ANDROID__ +#define SYM(s) extern void s(void); +#include "symbols.aarch64-musl.h" +#undef SYM + +extern void exit(int); +extern void printf(const char*, ...); + +#define MISSING_FUN(f) void (f)(void) { printf("Unknown call to `%s'\n", #f); exit(1); } + +MISSING_FUN(c_format_unix_time) +MISSING_FUN(c_format_unix_time_gmt) +MISSING_FUN(c_parse_unix_time) +MISSING_FUN(c_parse_unix_time_gmt) + +typedef void SymbolAddr; +typedef char SymbolName; + +typedef enum _SymStrength { + STRENGTH_NORMAL, + STRENGTH_WEAK, + STRENGTH_STRONG, +} SymStrength; + +typedef enum _SymType { + SYM_TYPE_CODE = 1 << 0, /* the symbol is a function and can be relocated via a jump island */ + SYM_TYPE_DATA = 1 << 1, /* the symbol is data */ + SYM_TYPE_INDIRECT_DATA = 1 << 2, /* see Note [_iob_func symbol] */ + SYM_TYPE_DUP_DISCARD = 1 << 3, /* the symbol is a symbol in a BFD import library + however if a duplicate is found with a mismatching + SymType then discard this one. */ +} SymType; + +typedef struct _RtsSymbolVal { + const SymbolName* lbl; + SymbolAddr* addr; + SymStrength strength; + SymType type; +} RtsSymbolVal; + +#define SYM(x) { #x, (void*)(&x), STRENGTH_NORMAL, 1 }, +// typedef mode_t (*umask_func_ptr_t)(mode_t); + +RtsSymbolVal my_iserv_syms[] = { +#include "symbols.aarch64-musl.h" + { 0, 0, STRENGTH_NORMAL, 1 } /* sentinel */ +}; + +RtsSymbolVal* iserv_syms() { + return my_iserv_syms; +} + +// Name used in GHC >=9.12 +RtsSymbolVal* rtsExtraSyms() { + return my_iserv_syms; +} +#endif diff --git a/cbits/symbols.aarch64-musl.h b/cbits/symbols.aarch64-musl.h new file mode 100644 index 0000000..b311a69 --- /dev/null +++ b/cbits/symbols.aarch64-musl.h @@ -0,0 +1,35 @@ +SYM(fprintf) +SYM(snprintf) +SYM(vsnprintf) +SYM(ptsname) +SYM(closure_sizeW_) +SYM(__addtf3) +SYM(__divtf3) +SYM(__extenddftf2) +SYM(__fixtfsi) +SYM(__floatditf) +SYM(__floatsitf) +SYM(__getf2) +SYM(__gttf2) +SYM(__lttf2) +SYM(__multf3) +SYM(__subtf3) +SYM(__trunctfdf2) +SYM(__trunctfsf2) +SYM(__floatunsitf) +SYM(__extendsftf2) +SYM(__eqtf2) +SYM(__netf2) +SYM(__letf2) +SYM(__fixunstfsi) +SYM(getauxval) +SYM(malloc) +SYM(free) +SYM(pipe) +SYM(fcntl) +SYM(posix_spawn_file_actions_init) +SYM(posix_spawnattr_init) +SYM(posix_spawn_file_actions_destroy) +SYM(posix_spawn_file_actions_addopen) +SYM(posix_spawn_file_actions_adddup2) +SYM(posix_spawn_file_actions_addclose) diff --git a/cbits/symbols.armv7a-android.c b/cbits/symbols.armv7a-android.c new file mode 100644 index 0000000..1420151 --- /dev/null +++ b/cbits/symbols.armv7a-android.c @@ -0,0 +1,795 @@ +#if defined(__ANDROID__) && defined(__arm__) +#include +#include +#include +#include +#include +#include + +extern void __aeabi_idiv(void); +extern void __aeabi_idivmod(void); +extern void __aeabi_memcpy(void); +extern void __aeabi_memclr(void); +extern void __aeabi_memclr4(void); +extern void __aeabi_ldivmod(void); +extern void __aeabi_memcpy4(void); +extern void __aeabi_memmove(void); +extern void __aeabi_memset4(void); +extern void __aeabi_uidiv(void); +extern void __aeabi_uidivmod(void); +extern void __aeabi_uldivmod(void); +extern void __aeabi_d2f(void); +extern void __aeabi_d2iz(void); +extern void __aeabi_dadd(void); +extern void __aeabi_dcmpeq(void); +extern void __aeabi_dcmpge(void); +extern void __aeabi_dcmpgt(void); +extern void __aeabi_dcmple(void); +extern void __aeabi_dcmplt(void); +extern void __aeabi_ddiv(void); +extern void __aeabi_dmul(void); +extern void __aeabi_f2d(void); +extern void __aeabi_fcmpeq(void); +extern void __aeabi_fcmpge(void); +extern void __aeabi_fcmpgt(void); +extern void __aeabi_fcmple(void); +extern void __aeabi_i2d(void); + +extern void eventfd_write(void); +extern void ioctl(void); +extern void close(void); +extern void epoll_wait(void); +// extern void expf(void); +extern void getpid(void); +extern void isatty(void); +extern void waitpid(void); + +extern void dup2(void); +extern void epoll_ctl(void); +extern void ftruncate64(void); +extern void link(void); +extern void pipe(void); + +extern void __assert2(void); +extern void dup(void); +extern void epoll_create(void); +extern void eventfd(void); +extern void fork(void); +extern void unlink(void); +extern void creat(void); +extern void fcntl(void); +extern void open(void); +extern void access(void); +extern void environ(void); +extern void lseek64(void); +extern void umask(void); +extern void poll(void); +extern void raise(void); +extern void mbrtowc(void); +extern void sigprocmask(void); +extern void sigaddset(void); +extern void sigemptyset(void); +extern void stat(void); +extern void utime(void); +extern void chmod(void); +extern void mkfifo(void); +extern void wcrtomb(void); +extern void lstat(void); +extern void fstat(void); +extern void write(void); +extern void read(void); +extern void __stack_chk_fail(void); +extern void __stack_chk_guard(void); +extern void __aeabi_memclr8(void); +extern void __aeabi_memcpy8(void); +extern void __aeabi_memmove4(void); +extern void __write_chk(void); +extern void time(void); +extern void uname(void); +extern void tzset(void); +extern void sysconf(void); +extern void socket(void); +extern void readdir(void); +extern void readdir_r(void); +extern void pthread_rwlock_init(void); +extern void __memset_chk(void); +extern void __memcpy_chk(void); +extern void gmtime_r(void); +extern void getauxval(void); +extern void clock_gettime(void); +extern void __aeabi_memset4(void); +extern void __aeabi_memset8(void); +extern void __aeabi_memset(void); +extern void __vsprintf_chk(void); +extern void usleep(void); +extern void setsockopt(void); +extern void __read_chk(void); +extern void opendir(void); +extern void mmap(void); +extern void pthread_rwlock_rdlock(void); +extern void __memmove_chk(void); +extern void localtime_r(void); +extern void getsockopt(void); +extern void getnameinfo(void); +extern void getentropy(void); +extern void clock_getres(void); +extern void __aeabi_d2lz(void); +extern void __aeabi_l2d(void); +extern void __aeabi_d2ulz(void); +extern void syscall(void); +extern void shutdown(void); +extern void pthread_rwlock_wrlock(void); +extern void mprotect(void); +extern void gettimeofday(void); +extern void gethostbyname(void); +extern void gai_strerror(void); +extern void fsync(void); +extern void connect(void); +extern void closedir(void); +extern void bind(void); +extern void sleep(void); +extern void pthread_rwlock_unlock(void); +extern void __open_2(void); +extern void mlock(void); +extern void listen(void); +extern void freeaddrinfo(void); +extern void clock(void); +extern void __aeabi_ul2d(void); +extern void accept(void); +extern void strftime(void); +extern void pthread_rwlock_destroy(void); +extern void madvise(void); +extern void getsockname(void); +extern void getaddrinfo(void); +extern void sigaction(void); +extern void pthread_once(void); +extern void munmap(void); +extern void __FD_SET_chk(void); +extern void __cmsg_nxthdr(void); +extern void pthread_key_create(void); +extern void select(void); +extern void sendmsg(void); +extern void signal(void); +extern void pthread_getspecific(void); +extern void pthread_setspecific(void); +extern void munlock(void); +extern void pthread_key_delete(void); +extern void pthread_key_create(void); +extern void pthread_mutexattr_init(void); +extern void pthread_self(void); +extern void pthread_mutexattr_settype(void); +extern void pthread_equal(void); +extern void pthread_mutex_init(void); +extern void pthread_mutexattr_destroy(void); +extern void pthread_mutex_destroy(void); +extern void pthread_mutex_lock(void); +extern void pthread_mutex_trylock(void); +extern void pthread_mutex_unlock(void); +extern void utimes(void); +extern void pthread_join(void); +extern void __aeabi_l2f(void); +extern void pthread_create(void); +extern void localtime(void); +extern void getcwd(void); +extern void fchmod(void); +extern void mkdir(void); +extern void rmdir(void); +extern void fchown(void); +extern void geteuid(void); +extern void mmap64(void); +extern void mremap(void); +extern void readlink(void); +extern void flock(void); +extern void times(void); +extern void getrusage(void); +extern void openat(void); +extern void futimes(void); +extern void lutimes(void); +extern void dlclose(void); +extern void dlerror(void); +extern void dlsym(void); +extern void dlopen(void); +extern void execv(void); +extern void execve(void); +extern void execvp(void); +extern void execvpe(void); +extern void setrlimit(void); +extern void sigpending(void); +extern void getrlimit(void); +extern void fallocate(void); +extern void rewinddir(void); +extern void seekdir(void); +extern void telldir(void); +void * __gxx_personality_v0; +void * _Unwind_Resume; +extern void __atomic_load_4(void); +extern void __atomic_store_4(void); +extern void pthread_cond_wait(void); +extern void pthread_cond_broadcast(void); +extern void __cxa_guard_acquire(void); +extern void __cxa_guard_release(void); +extern void getpeername(void); +extern void mktime(void); +extern void __poll_chk(void); +extern void pthread_attr_destroy(void); +extern void pthread_attr_init(void); +extern void pthread_attr_setdetachstate(void); +extern void pthread_cond_destroy(void); +extern void pthread_cond_init(void); +extern void pthread_cond_signal(void); +extern void pthread_cond_timedwait(void); +extern void pthread_exit(void); +extern void recvfrom(void); +extern void recvmmsg(void); +extern void sendmmsg(void); +extern void sendto(void); +extern void timezone(void); +extern void fdatasync(void); +extern void fdopendir(void); +extern void nanosleep(void); +extern void sigsuspend(void); +extern void __assert(void); +extern void _Z21__libc_shared_globalsv(void); +extern void __strcpy_chk(void); +extern void __cxa_thread_finalize(void); +extern void kill(void); +extern void sigismember(void); +extern void __vsnprintf_chk(void); +extern void setitimer(void); +extern void sigfillset(void); +extern void __readlink_chk(void); +extern void __libc_stdio_cleanup(void); +extern void sigdelset(void); +extern void writev(void); +extern void prctl(void); +extern void getuid(void); +extern void __fsetxattr(void); +extern void setxattr(void); +extern void setuid(void); +extern void setresuid(void); +extern void setgid(void); +extern void setresgid(void); +extern void getegid(void); +extern void getgid(void); +extern void setgroups(void); +extern void getgroups(void); +extern void chdir(void); +extern void __fstatfs64(void); +extern void __statfs64(void); +extern void fchownat(void); +extern void symlinkat(void); +extern void truncate64(void); +extern void mknodat(void); +extern void fallocate64(void); +extern void __arm_fadvise64_64(void); +extern void setsid(void); +extern void _exit(int) __attribute__((noreturn)); +extern void fchdir(void); +extern void utimensat(void); +extern void getppid(void); +extern void getpgid(void); +extern void setpgid(void); +extern void setpriority(void); +extern void __getpriority(void); +extern void __emutls_get_address(void); +extern void __cxa_guard_abort(void); +extern void killpg(void); +extern void alarm(void); +extern void sem_post(void); +extern void sem_trywait(void); +extern void sem_wait(void); +extern void sem_unlink(void); +extern void sem_close(void); +extern void sem_open(void); +extern void sem_getvalue(void); +extern void getlogin(void); +extern void getgrent(void); +extern void setgrent(void); +extern void endgrent(void); +extern void getpwent(void); +extern void setpwent(void); +extern void endpwent(void); +extern void seteuid(void); +extern void setegid(void); +extern void getpwnam_r(void); +extern void getpwuid_r(void); +extern void getgrnam_r(void); +extern void getgrgid_r(void); +extern void pathconf(void); +extern void chown(void); +extern void lchown(void); +extern void symlink(void); +extern void mknod(void); +extern void posix_fallocate64(void); +extern void posix_fadvise64(void); +extern void ttyname(void); +extern void openpty(void); +extern void fpathconf(void); +extern void futimens(void); +extern void getpgrp(void); +extern void getpriority(void); +extern void nice(void); +extern void tcgetpgrp(void); +extern void tcsetpgrp(void); +extern void unlinkat(void); +extern void fchmodat(void); +extern void fstatat(void); +extern void __strncpy_chk(void); + +#define MISSING_FUN(f) void (f)(void) { printf("Unknown call to %s\n", #f); exit(1); } + +MISSING_FUN(c_format_unix_time) +MISSING_FUN(c_format_unix_time_gmt) +MISSING_FUN(c_parse_unix_time) +MISSING_FUN(c_parse_unix_time_gmt) +MISSING_FUN(__cxa_begin_catch) +MISSING_FUN(_ZSt9terminatev) +MISSING_FUN(__loader_add_thread_local_dtor) +MISSING_FUN(__loader_remove_thread_local_dtor) +MISSING_FUN(__clang_call_terminate) + +typedef void SymbolAddr; +typedef char SymbolName; + +typedef enum _SymStrength { + STRENGTH_NORMAL, + STRENGTH_WEAK, + STRENGTH_STRONG, +} SymStrength; + +typedef enum _SymType { + SYM_TYPE_CODE = 1 << 0, /* the symbol is a function and can be relocated via a jump island */ + SYM_TYPE_DATA = 1 << 1, /* the symbol is data */ + SYM_TYPE_INDIRECT_DATA = 1 << 2, /* see Note [_iob_func symbol] */ + SYM_TYPE_DUP_DISCARD = 1 << 3, /* the symbol is a symbol in a BFD import library + however if a duplicate is found with a mismatching + SymType then discard this one. */ +} SymType; + +typedef struct _RtsSymbolVal { + const SymbolName* lbl; + SymbolAddr* addr; + SymStrength strength; + SymType type; +} RtsSymbolVal; + +// work around built-ins being referenced from libraries, and us not being able to &; instead +// wrap the built-in into a function. +//int32_t ___sync_val_compare_and_swap_1(volatile int32_t* ptr, int32_t oldval, int32_t newval) { +// return __sync_val_compare_and_swap_1(ptr, oldval, newval); +//} + +#define SYM(x) { #x, (void*)(&x), STRENGTH_NORMAL, 1 } +typedef mode_t (*umask_func_ptr_t)(mode_t); + +RtsSymbolVal my_iserv_syms[] = { + // { "__sync_val_compare_and_swap_1", (void*)(&___sync_val_compare_and_swap_1), STRENGTH_NORMAL, 1 }, + SYM(strlen), + SYM(__aeabi_idiv), + SYM(__aeabi_idivmod), + SYM(__aeabi_memcpy), + SYM(__aeabi_memclr), + SYM(__aeabi_memclr4), + SYM(__aeabi_ldivmod), + SYM(__aeabi_memcpy4), + SYM(__aeabi_memmove), + SYM(__aeabi_memset4), + SYM(__aeabi_uidiv), + SYM(__aeabi_uidivmod), + SYM(__aeabi_uldivmod), + SYM(calloc), + SYM(malloc), + SYM(free), + SYM(realloc), + SYM(abort), + SYM(close), + SYM(epoll_wait), + SYM(__errno), + SYM(eventfd_write), + SYM(expf), + SYM(fprintf), + SYM(getenv), + SYM(getpid), + SYM(ioctl), + SYM(isatty), + SYM(memcmp), + SYM(poll), + SYM(raise), + SYM(strcmp), + SYM(strerror), + SYM(setenv), + SYM(unsetenv), + SYM(waitpid), + SYM(dup2), + SYM(epoll_ctl), + SYM(ftruncate64), + SYM(ldexp), + SYM(link), + SYM(log1pf), + SYM(mbrtowc), + SYM(pipe), + SYM(putenv), + SYM(sigprocmask), + SYM(stderr), + SYM(__assert2), + SYM(dup), + SYM(epoll_create), + SYM(eventfd), + SYM(expm1f), + SYM(fork), + SYM(sigaddset), + SYM(stat), + SYM(wcrtomb), + SYM(__ctype_get_mb_cur_max), + SYM(fstat), + SYM(logf), + SYM(sigemptyset), + SYM(unlink), + SYM(creat), + SYM(lstat), + SYM(mkfifo), + SYM(qsort), + SYM(sinf), + SYM(chmod), + SYM(cosf), + SYM(fcntl), + SYM(open), + SYM(access), + SYM(environ), + SYM(tanf), + SYM(utime), + SYM(asinf), + SYM(lseek64), + SYM(umask), + SYM(acosf), + SYM(write), + SYM(atanf), + SYM(read), + SYM(sinhf), + SYM(coshf), + SYM(tanhf), + SYM(asinhf), + SYM(acoshf), + SYM(atanhf), + SYM(powf), + SYM(exp), + SYM(log1p), + SYM(expm1), + SYM(log), + SYM(sin), + SYM(cos), + SYM(tan), + SYM(asin), + SYM(acos), + SYM(atan), + SYM(sinh), + SYM(cosh), + SYM(tanh), + SYM(asinh), + SYM(acosh), + SYM(atanh), + SYM(pow), + SYM(__aeabi_memclr8), + SYM(__aeabi_memcpy8), + SYM(__aeabi_memmove4), + SYM(__aeabi_memset), + SYM(__aeabi_memset8), + SYM(clock_gettime), + SYM(fopen), + SYM(fwrite), + SYM(getauxval), + SYM(gmtime_r), + SYM(memchr), + SYM(__memcpy_chk), + SYM(memset), + SYM(__memset_chk), + SYM(pthread_rwlock_init), + SYM(readdir), + SYM(readdir_r), + SYM(socket), + SYM(__stack_chk_fail), + SYM(__stack_chk_guard), + SYM(strchr), + SYM(__strchr_chk), + SYM(strcpy), + SYM(strdup), + SYM(__strlen_chk), + SYM(strncmp), + SYM(strncpy), + SYM(__strncpy_chk), + SYM(__strncpy_chk2), + SYM(strrchr), + SYM(strspn), + SYM(strstr), + SYM(strtoul), + SYM(sysconf), + SYM(time), + SYM(tzset), + SYM(uname), + SYM(vfprintf), + SYM(__write_chk), + SYM(__aeabi_d2lz), + SYM(__aeabi_l2d), + SYM(atexit), + SYM(atoi), + SYM(clock_getres), + SYM(fclose), + SYM(fileno), + SYM(fread), + SYM(fseek), + SYM(getentropy), + SYM(getnameinfo), + SYM(getsockopt), + SYM(localtime_r), + SYM(__memmove_chk), + SYM(__memchr_chk), + SYM(mmap), + SYM(opendir), + SYM(pthread_rwlock_rdlock), + SYM(__read_chk), + SYM(setsockopt), + SYM(sscanf), + SYM(strcspn), + SYM(strtok), + SYM(strtol), + SYM(usleep), + SYM(__vsprintf_chk), + SYM(__aeabi_d2ulz), + SYM(bind), + SYM(closedir), + SYM(connect), + SYM(ferror), + SYM(fsync), + SYM(ftell), + SYM(gai_strerror), + SYM(gethostbyname), + SYM(gettimeofday), + SYM(mprotect), + SYM(pthread_rwlock_wrlock), + SYM(shutdown), + SYM(stdin), + SYM(syscall), + SYM(accept), + SYM(__aeabi_ul2d), + SYM(clock), + SYM(fgets), + SYM(fputs), + SYM(freeaddrinfo), + SYM(listen), + SYM(mlock), + SYM(__open_2), + SYM(pthread_rwlock_unlock), + SYM(sleep), + SYM(strcat), + SYM(feof), + SYM(fflush), + SYM(getaddrinfo), + SYM(getsockname), + SYM(madvise), + SYM(perror), + SYM(pthread_rwlock_destroy), + SYM(strftime), + SYM(__cmsg_nxthdr), + SYM(__FD_SET_chk), + SYM(fputc), + SYM(munmap), + SYM(pthread_once), + SYM(sigaction), + SYM(pthread_key_create), + SYM(select), + SYM(sendmsg), + SYM(signal), + SYM(stdout), + SYM(pthread_getspecific), + SYM(rename), + SYM(munlock), + SYM(pthread_setspecific), + SYM(pthread_key_delete), + SYM(pthread_mutexattr_init), + SYM(pthread_mutexattr_settype), + SYM(pthread_self), + SYM(pthread_equal), + SYM(pthread_mutex_init), + SYM(pthread_mutexattr_destroy), + SYM(pthread_mutex_destroy), + SYM(pthread_mutex_lock), + SYM(pthread_mutex_trylock), + SYM(pthread_mutex_unlock), + SYM(utimes), + SYM(pthread_join), + SYM(__aeabi_l2f), + SYM(pthread_create), + SYM(localtime), + SYM(getcwd), + SYM(fchmod), + SYM(mkdir), + SYM(rmdir), + SYM(fchown), + SYM(geteuid), + SYM(mmap64), + SYM(mremap), + SYM(readlink), + SYM(times), + SYM(strerror_r), + SYM(flock), + SYM(puts), + SYM(getrusage), + SYM(__aeabi_memclr8), + SYM(openat), + SYM(futimes), + SYM(lutimes), + SYM(android_get_application_target_sdk_version), + SYM(dlclose), + SYM(dlerror), + SYM(dlsym), + SYM(dlopen), + SYM(execv), + SYM(execve), + SYM(execvp), + SYM(execvpe), + SYM(setrlimit), + SYM(sigpending), + SYM(getrlimit), + SYM(fallocate), + SYM(rewinddir), + SYM(seekdir), + SYM(telldir), + SYM(__gxx_personality_v0), + SYM(__cxa_begin_catch), + SYM(_ZSt9terminatev), + SYM(_Unwind_Resume), + SYM(__aeabi_d2f), + SYM(__aeabi_d2iz), + SYM(__aeabi_dadd), + SYM(__aeabi_dcmpeq), + SYM(__aeabi_dcmpge), + SYM(__aeabi_dcmpgt), + SYM(__aeabi_dcmple), + SYM(__aeabi_dcmplt), + SYM(__aeabi_ddiv), + SYM(__aeabi_dmul), + SYM(__aeabi_f2d), + SYM(__aeabi_fcmpeq), + SYM(__aeabi_fcmpge), + SYM(__aeabi_fcmpgt), + SYM(__aeabi_fcmple), + SYM(__aeabi_i2d), + SYM(__atomic_load_4), + SYM(__atomic_store_4), + SYM(pthread_cond_wait), + SYM(vasprintf), + SYM(pthread_cond_broadcast), + SYM(__cxa_guard_acquire), + SYM(ceil), + SYM(__cxa_guard_release), + SYM(getpeername), + SYM(mktime), + SYM(__poll_chk), + SYM(pthread_attr_destroy), + SYM(pthread_attr_init), + SYM(pthread_attr_setdetachstate), + SYM(pthread_cond_destroy), + SYM(pthread_cond_init), + SYM(pthread_cond_signal), + SYM(pthread_cond_timedwait), + SYM(pthread_exit), + SYM(recvfrom), + SYM(recvmmsg), + SYM(sendmmsg), + SYM(sendto), + SYM(timezone), + SYM(fdatasync), + SYM(fdopendir), + SYM(nanosleep), + SYM(sigsuspend), + SYM(__assert), + SYM(__strlcpy_chk), + SYM(_Z21__libc_shared_globalsv), + SYM(__strcpy_chk), + SYM(getline), + SYM(__loader_add_thread_local_dtor), + SYM(__loader_remove_thread_local_dtor), + SYM(__cxa_thread_finalize), + SYM(kill), + SYM(sigismember), + SYM(__vsnprintf_chk), + SYM(ctermid), + SYM(setitimer), + SYM(sigfillset), + SYM(__readlink_chk), + SYM(__libc_stdio_cleanup), + SYM(sigdelset), + SYM(writev), + SYM(prctl), + SYM(getuid), + SYM(__fsetxattr), + SYM(setxattr), + SYM(setuid), + SYM(setresuid), + SYM(setgid), + SYM(setresgid), + SYM(getegid), + SYM(getgid), + SYM(setgroups), + SYM(getgroups), + SYM(chdir), + SYM(__fstatfs64), + SYM(__statfs64), + SYM(fchownat), + SYM(symlinkat), + SYM(truncate64), + SYM(mknodat), + SYM(fallocate64), + SYM(__arm_fadvise64_64), + SYM(setsid), + SYM(_exit), + SYM(fchdir), + SYM(utimensat), + SYM(getppid), + SYM(getpgid), + SYM(setpgid), + SYM(setpriority), + SYM(__getpriority), + SYM(__emutls_get_address), + SYM(__cxa_guard_abort), + SYM(__clang_call_terminate), + SYM(killpg), + SYM(alarm), + SYM(sem_post), + SYM(sem_trywait), + SYM(sem_wait), + SYM(sem_unlink), + SYM(sem_close), + SYM(sem_open), + SYM(sem_getvalue), + SYM(getlogin), + SYM(getgrent), + SYM(setgrent), + SYM(endgrent), + SYM(getpwent), + SYM(setpwent), + SYM(endpwent), + SYM(seteuid), + SYM(setegid), + SYM(getpwnam_r), + SYM(getpwuid_r), + SYM(getgrnam_r), + SYM(getgrgid_r), + SYM(pathconf), + SYM(chown), + SYM(lchown), + SYM(symlink), + SYM(mknod), + SYM(clearenv), + SYM(posix_fallocate64), + SYM(posix_fadvise64), + SYM(mkdtemp), + SYM(mkstemps), + SYM(mkstemp), + SYM(ttyname), + SYM(openpty), + SYM(ptsname), + SYM(fpathconf), + SYM(futimens), + SYM(getpgrp), + SYM(exit), + SYM(getpriority), + SYM(nice), + SYM(tcgetpgrp), + SYM(tcsetpgrp), + SYM(realpath), + SYM(unlinkat), + SYM(fchmodat), + SYM(fstatat), + { 0, 0, STRENGTH_NORMAL, 1 } /* sentinel */ +}; + +RtsSymbolVal* iserv_syms() { + return my_iserv_syms; +} + +// Name used in GHC >=9.12 +RtsSymbolVal* rtsExtraSyms() { + return my_iserv_syms; +} +#endif diff --git a/cbits/symbols.i386-musl.c b/cbits/symbols.i386-musl.c new file mode 100644 index 0000000..b82fb68 --- /dev/null +++ b/cbits/symbols.i386-musl.c @@ -0,0 +1,300 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +// #include // this includes too many overloaded items. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// fnctl stubs, see above +extern void eventfd(void); +extern void eventfd_write(void); + +extern void statx(void); + +extern void __stack_chk_fail(void); +// GCC stuff +extern void __addtf3(void); +extern void __divtf3(void); +extern void __extenddftf2(void); +extern void __fixtfsi(void); +extern void __floatditf(void); +extern void __floatsitf(void); +extern void __getf2(void); +extern void __gttf2(void); +extern void __lttf2(void); +extern void __multf3(void); +extern void __subtf3(void); +extern void __trunctfdf2(void); + +extern void __aio_close(void); +extern void __stack_chk_fail_local(void); + +#define MISSING_FUN(f) void (f)(void) { printf("Unknown call to `%s'\n", #f); exit(1); } + +MISSING_FUN(c_format_unix_time) +MISSING_FUN(c_format_unix_time_gmt) +MISSING_FUN(c_parse_unix_time) +MISSING_FUN(c_parse_unix_time_gmt) + +typedef void SymbolAddr; +typedef char SymbolName; + +typedef enum _SymStrength { + STRENGTH_NORMAL, + STRENGTH_WEAK, + STRENGTH_STRONG, +} SymStrength; + +typedef enum _SymType { + SYM_TYPE_CODE = 1 << 0, /* the symbol is a function and can be relocated via a jump island */ + SYM_TYPE_DATA = 1 << 1, /* the symbol is data */ + SYM_TYPE_INDIRECT_DATA = 1 << 2, /* see Note [_iob_func symbol] */ + SYM_TYPE_DUP_DISCARD = 1 << 3, /* the symbol is a symbol in a BFD import library + however if a duplicate is found with a mismatching + SymType then discard this one. */ +} SymType; + +typedef struct _RtsSymbolVal { + const SymbolName* lbl; + SymbolAddr* addr; + SymStrength strength; + SymType type; +} RtsSymbolVal; + +#define SYM(x) { #x, (void*)(&x), STRENGTH_NORMAL, 1 } +typedef mode_t (*umask_func_ptr_t)(mode_t); + +RtsSymbolVal my_iserv_syms[] = { + // arpa/inet.h + SYM(htons), + SYM(ntohs), + SYM(htonl), + SYM(ntohl), + // sys/random.h + SYM(getentropy), + SYM(getrandom), + // sys/auxv.h + SYM(getauxval), + // sys/mman.h + SYM(madvise),SYM(mlock),SYM(mmap),SYM(mprotect),SYM(munmap), + SYM(munlock), + // sys/socket + SYM(accept),SYM(bind),SYM(connect),SYM(getsockopt),SYM(listen), + SYM(setsockopt),SYM(socket),SYM(getsockname),SYM(select), + SYM(getpeername),SYM(recv),SYM(recvfrom), + SYM(recvmsg),SYM(send),SYM(sendmsg),SYM(sendto),SYM(writev), + SYM(accept4), + // pthread.h + SYM(pthread_equal),SYM(pthread_getspecific),SYM(pthread_key_create), + SYM(pthread_key_delete),SYM(pthread_once),SYM(pthread_rwlock_destroy), + SYM(pthread_rwlock_init),SYM(pthread_rwlock_rdlock),SYM(pthread_rwlock_unlock), + SYM(pthread_rwlock_wrlock),SYM(pthread_self),SYM(pthread_setspecific), + SYM(pthread_create),SYM(pthread_join),SYM(pthread_mutex_destroy), + SYM(pthread_mutex_init),SYM(pthread_mutex_lock),SYM(pthread_mutex_trylock), + SYM(pthread_mutex_unlock),SYM(pthread_mutexattr_destroy), + SYM(pthread_mutexattr_init),SYM(pthread_mutexattr_settype), + // netdb.h + SYM(freeaddrinfo),SYM(gai_strerror),SYM(getaddrinfo),SYM(getnameinfo), + SYM(gethostbyname), + // dirent.h + SYM(readdir_r),SYM(readdir), + SYM(opendir),SYM(closedir), + // time.h + SYM(clock),SYM(gmtime_r), + // sys/time.h + SYM(gettimeofday),SYM(clock_getres),SYM(clock_gettime),SYM(localtime_r),SYM(tzset), + // unistd.h + SYM(readlink), + SYM(rename), + SYM(rmdir), + SYM(chown), + SYM(realpath), + SYM(fchdir), + SYM(fdopendir), + SYM(rewinddir), + SYM(futimens), + SYM(mknod), + SYM(lchown), + SYM(symlink), + SYM(endgrent),SYM(endpwent), + SYM(pathconf), + SYM(truncate), + SYM(utimensat), + SYM(statx), + SYM(seekdir), + SYM(telldir), + SYM(clearenv), + SYM(chdir), + SYM(sleep), + SYM(strftime), + SYM(utimes), + SYM(setenv), + SYM(fpathconf), + SYM(exit), + SYM(ftruncate), + SYM(getenv), + SYM(putenv), + SYM(unsetenv), + SYM(read), + SYM(write), + SYM(isatty), + SYM(link), + SYM(pipe), + SYM(unlink), + SYM(execv),SYM(execve),SYM(execvp),SYM(execvpe), + SYM(syscall),SYM(sysconf), + // math.h + SYM(sinhf), SYM(sinh), SYM(sinf), SYM(sin), + SYM(coshf), SYM(cosh), SYM(cosf), SYM(cos), + SYM(atanhf), SYM(atanh), SYM(atanf), SYM(atan), + SYM(asinhf), SYM(asinh), SYM(asinf), SYM(asin), + SYM(acoshf), SYM(acosh), SYM(acosf), SYM(acos), + SYM(log1pf), SYM(log1p), SYM(logf), SYM(log), + SYM(expm1f), SYM(expm1), + SYM(expf), SYM(exp), + SYM(powf), SYM(pow), + SYM(sqrtf), SYM(sqrt), + SYM(tanhf), SYM(tanh), SYM(tanf), SYM(tan), + // signal.h + SYM(signal),SYM(sigaction), + SYM(raise), SYM(sigaddset), SYM(sigemptyset), SYM(sigprocmask), + // sys/eventfd.h + SYM(eventfd), SYM(eventfd_write), + // sys/stat.h + SYM(fstat), + SYM(lstat), + SYM(stat), + SYM(chmod), + SYM(mkfifo), + // SYM(umask), + { "umask", (umask_func_ptr_t)(&umask), STRENGTH_NORMAL, 1 }, + // sys/wait.h + SYM(waitpid), + // sym/epoll.h + SYM(epoll_create), SYM(epoll_ctl), SYM(epoll_wait), + // poll.h + SYM(poll), + // fcntl.h + SYM(fcntl), + // string.h + SYM(strerror), + SYM(strcmp), + SYM(memchr),SYM(strcpy),SYM(strchr),SYM(strncpy),SYM(strrchr), + SYM(strcat),SYM(strncmp),SYM(strdup), + SYM(strtoul),SYM(strspn),SYM(strtol),SYM(strstr),SYM(strcspn), + // ctype.h + SYM(__ctype_get_mb_cur_max), + // wchar.h + SYM(mbrtowc), SYM(wcrtomb), + // stdlib.h + SYM(qsort), + // unistd.h + SYM(access), SYM(close), SYM(dup), SYM(dup2), SYM(fork), SYM(getpid), + SYM(lseek), + // utime.h + SYM(utime),SYM(time), + // ... + SYM(fileno), + SYM(__stack_chk_fail), + SYM(memmove), + SYM(memcmp), + SYM(memcpy), + SYM(memset), + SYM(realloc), + SYM(calloc), + SYM(malloc), + SYM(free), + SYM(fprintf), + SYM(vfprintf), + SYM(fopen), SYM(fclose), + SYM(getegid),SYM(getgid), + SYM(getpwent), + SYM(getgrent), + SYM(getgroups), + SYM(getlogin), + SYM(getuid), + SYM(getgrgid_r),SYM(getgrnam_r),SYM(getpwnam_r),SYM(getpwuid_r), + SYM(setegid),SYM(seteuid),SYM(setgid),SYM(setgrent),SYM(setgroups), + SYM(setpwent),SYM(setuid), + SYM(fread), + SYM(abort), + SYM(strlen), + SYM(fwrite), + SYM(feof), + SYM(ferror), + SYM(fflush), + SYM(fgets),SYM(fputc),SYM(fputs), + SYM(fseek),SYM(ftell), + SYM(sscanf), + SYM(shutdown), + SYM(atoi), + SYM(atexit), + SYM(usleep), + SYM(fchmod), + SYM(fchown), + SYM(fsync), + SYM(getcwd), + SYM(geteuid), + SYM(localtime), + SYM(mkdir), + SYM(mktime), + SYM(fdopen), + SYM(c_format_unix_time), + SYM(c_format_unix_time_gmt), + SYM(c_parse_unix_time), + SYM(c_parse_unix_time_gmt), + SYM(__addtf3), + SYM(__divtf3), + SYM(__extenddftf2), + SYM(__fixtfsi), + SYM(__floatditf), + SYM(__floatsitf), + SYM(__getf2), + SYM(__gttf2), + SYM(__lttf2), + SYM(__multf3), + SYM(__subtf3), + SYM(__trunctfdf2), + SYM(scalbn), + SYM(fma), + SYM(fmaf), + SYM(puts), + SYM(__aio_close), + SYM(__stack_chk_fail_local), + { 0, 0, STRENGTH_NORMAL, 1 } /* sentinel */ +}; + +RtsSymbolVal* iserv_syms() { + return my_iserv_syms; +} + +// Name used in GHC >=9.12 +RtsSymbolVal* rtsExtraSyms() { + return my_iserv_syms; +} diff --git a/cbits/symbols.x86_64-musl.c b/cbits/symbols.x86_64-musl.c new file mode 100644 index 0000000..aa05b37 --- /dev/null +++ b/cbits/symbols.x86_64-musl.c @@ -0,0 +1,328 @@ +// It looks like this file is probably incorrect. +// TODO enable iserv-proxy for musl64 tests and update this +// file to fix unresolved external issues. +#if 0 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +// #include // this includes too many overloaded items. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// fnctl stubs, see above +extern void open(void); +extern void openat(void); +extern void creat(void); +extern void eventfd(void); +extern void eventfd_write(void); + +extern void futimes(void); +extern void lutimes(void); +extern void statx(void); + +extern void __stack_chk_fail(void); +extern void __vsprintf_chk(void); +extern void __open_2(void); +extern void __memcpy_chk(void); +extern void __memset_chk(void); +extern void __memmove_chk(void); +// GCC stuff +extern void __addtf3(void); +extern void __divtf3(void); +extern void __extenddftf2(void); +extern void __fixtfsi(void); +extern void __floatditf(void); +extern void __floatsitf(void); +extern void __getf2(void); +extern void __gttf2(void); +extern void __lttf2(void); +extern void __multf3(void); +extern void __subtf3(void); +extern void __trunctfdf2(void); + +#define MISSING_FUN(f) void (f)(void) { printf("Unknown call to `%s'\n", #f); exit(1); } + +MISSING_FUN(c_format_unix_time) +MISSING_FUN(c_format_unix_time_gmt) +MISSING_FUN(c_parse_unix_time) +MISSING_FUN(c_parse_unix_time_gmt) + +typedef void SymbolAddr; +typedef char SymbolName; + +typedef enum _SymStrength { + STRENGTH_NORMAL, + STRENGTH_WEAK, + STRENGTH_STRONG, +} SymStrength; + +typedef enum _SymType { + SYM_TYPE_CODE = 1 << 0, /* the symbol is a function and can be relocated via a jump island */ + SYM_TYPE_DATA = 1 << 1, /* the symbol is data */ + SYM_TYPE_INDIRECT_DATA = 1 << 2, /* see Note [_iob_func symbol] */ + SYM_TYPE_DUP_DISCARD = 1 << 3, /* the symbol is a symbol in a BFD import library + however if a duplicate is found with a mismatching + SymType then discard this one. */ +} SymType; + +typedef struct _RtsSymbolVal { + const SymbolName* lbl; + SymbolAddr* addr; + SymStrength strength; + SymType type; +} RtsSymbolVal; + +#define SYM(x) { #x, (void*)(&x), STRENGTH_NORMAL, 1 } +typedef mode_t (*umask_func_ptr_t)(mode_t); + +RtsSymbolVal my_iserv_syms[] = { + // arpa/inet.h + SYM(htons), + SYM(ntohs), + SYM(htonl), + SYM(ntohl), + // sys/random.h + SYM(getentropy), + SYM(getrandom), + // sys/auxv.h + SYM(getauxval), + // sys/mman.h + SYM(madvise),SYM(mlock),SYM(mmap),SYM(mprotect),SYM(munmap), + SYM(mremap), + SYM(munlock), + // select.h + SYM(__FD_SET_chk), + // sys/socket + SYM(accept),SYM(bind),SYM(connect),SYM(getsockopt),SYM(listen), + SYM(setsockopt),SYM(socket),SYM(getsockname),SYM(select), + SYM(getpeername),SYM(__cmsg_nxthdr),SYM(recv),SYM(recvfrom), + SYM(recvmsg),SYM(send),SYM(sendmsg),SYM(sendto),SYM(writev), + SYM(accept4), + // pthread.h + SYM(pthread_equal),SYM(pthread_getspecific),SYM(pthread_key_create), + SYM(pthread_key_delete),SYM(pthread_once),SYM(pthread_rwlock_destroy), + SYM(pthread_rwlock_init),SYM(pthread_rwlock_rdlock),SYM(pthread_rwlock_unlock), + SYM(pthread_rwlock_wrlock),SYM(pthread_self),SYM(pthread_setspecific), + SYM(pthread_create),SYM(pthread_join),SYM(pthread_mutex_destroy), + SYM(pthread_mutex_init),SYM(pthread_mutex_lock),SYM(pthread_mutex_trylock), + SYM(pthread_mutex_unlock),SYM(pthread_mutexattr_destroy), + SYM(pthread_mutexattr_init),SYM(pthread_mutexattr_settype), + // chk.h + SYM(__read_chk),SYM(__write_chk), + // netdb.h + SYM(freeaddrinfo),SYM(gai_strerror),SYM(getaddrinfo),SYM(getnameinfo), + SYM(gethostbyname), + // dirent.h + SYM(readdir_r),SYM(readdir), + SYM(opendir),SYM(closedir), + // time.h + SYM(clock),SYM(gmtime_r), + // sys/time.h + SYM(gettimeofday),SYM(clock_getres),SYM(clock_gettime),SYM(localtime_r),SYM(tzset), + // unistd.h + SYM(readlink), + SYM(rename), + SYM(rmdir), + SYM(chown), + SYM(realpath), + SYM(fchdir), + SYM(fdopendir), + SYM(rewinddir), + SYM(futimens),SYM(futimes),SYM(lutimes), + SYM(mknod), + SYM(lchown), + SYM(symlink), + SYM(endgrent),SYM(endpwent), + SYM(pathconf), + SYM(truncate), + SYM(utimensat), + SYM(statx), + SYM(seekdir), + SYM(telldir), + SYM(clearenv), + SYM(chdir), + SYM(sleep), + SYM(stdout), + SYM(strftime), + SYM(utimes), + SYM(setenv), + SYM(fpathconf), + SYM(exit), + SYM(environ), + SYM(ftruncate), + SYM(getenv), + SYM(putenv), + SYM(unsetenv), + SYM(read), + SYM(write), + SYM(isatty), + SYM(link), + SYM(pipe), + SYM(unlink), + SYM(execv),SYM(execve),SYM(execvp),SYM(execvpe), + SYM(syscall),SYM(sysconf), + // errno.h + SYM(__errno), + // math.h + SYM(sinhf), SYM(sinh), SYM(sinf), SYM(sin), + SYM(coshf), SYM(cosh), SYM(cosf), SYM(cos), + SYM(atanhf), SYM(atanh), SYM(atanf), SYM(atan), + SYM(asinhf), SYM(asinh), SYM(asinf), SYM(asin), + SYM(acoshf), SYM(acosh), SYM(acosf), SYM(acos), + SYM(log1pf), SYM(log1p), SYM(logf), SYM(log), + SYM(expm1f), SYM(expm1), + SYM(expf), SYM(exp), + SYM(ldexp), + SYM(powf), SYM(pow), + SYM(sqrtf), SYM(sqrt), + SYM(tanhf), SYM(tanh), SYM(tanf), SYM(tan), + // assert.h + SYM(__assert2), + // signal.h + SYM(signal),SYM(sigaction), + SYM(raise), SYM(sigaddset), SYM(sigemptyset), SYM(sigprocmask), + // sys/eventfd.h + SYM(eventfd), SYM(eventfd_write), + // sys/stat.h + SYM(fstat), + SYM(lstat), + SYM(stat), + SYM(chmod), + SYM(mkfifo), + // SYM(umask), + { "umask", (umask_func_ptr_t)(&umask), STRENGTH_NORMAL, 1 }, + // sys/wait.h + SYM(waitpid), + // sym/epoll.h + SYM(epoll_create), SYM(epoll_ctl), SYM(epoll_wait), + // poll.h + SYM(poll), + // fcntl.h + SYM(open), SYM(creat), SYM(fcntl), SYM(ioctl), + SYM(openat),SYM(__open_2), + // string.h + SYM(strerror), + SYM(strcmp), + SYM(memchr),SYM(strcpy),SYM(strchr),SYM(strncpy),SYM(strrchr), + SYM(strcat),SYM(strncmp),SYM(strdup), + SYM(strtoul),SYM(strspn),SYM(strtol),SYM(strstr),SYM(strcspn), + SYM(__strncpy_chk2),SYM(__memcpy_chk), + // ctype.h + SYM(__ctype_get_mb_cur_max), + // wchar.h + SYM(mbrtowc), SYM(wcrtomb), + // stdlib.h + SYM(qsort), + // unistd.h + SYM(access), SYM(close), SYM(dup), SYM(dup2), SYM(fork), SYM(getpid), + SYM(lseek), + // utime.h + SYM(utime),SYM(time), + // ... + SYM(fileno), + SYM(__vsprintf_chk), + SYM(__strlen_chk), + SYM(__strchr_chk), + SYM(__memset_chk), + SYM(__memmove_chk), + SYM(__stack_chk_fail), + SYM(memmove), + SYM(memcmp), + SYM(memcpy), + SYM(memset), + SYM(stderr), + SYM(realloc), + SYM(calloc), + SYM(malloc), + SYM(free), + SYM(fprintf), + SYM(vfprintf), + SYM(fopen), SYM(fclose), + SYM(getegid),SYM(getgid), + SYM(getpwent), + SYM(getgrent), + SYM(getgroups), + SYM(getlogin), + SYM(getuid), + SYM(getgrgid_r),SYM(getgrnam_r),SYM(getpwnam_r),SYM(getpwuid_r), + SYM(setegid),SYM(seteuid),SYM(setgid),SYM(setgrent),SYM(setgroups), + SYM(setpwent),SYM(setuid), + SYM(fread), + SYM(abort), + SYM(strlen), + SYM(fwrite), + SYM(feof), + SYM(ferror), + SYM(fflush), + SYM(fgets),SYM(fputc),SYM(fputs), + SYM(fseek),SYM(ftell), + SYM(sscanf), + SYM(shutdown), + SYM(atoi), + SYM(stdin), + SYM(atexit), + SYM(usleep), + SYM(fchmod), + SYM(fchown), + SYM(fsync), + SYM(getcwd), + SYM(geteuid), + SYM(localtime), + SYM(lseek64), + SYM(mkdir), + SYM(mktime), + SYM(fdopen), + SYM(c_format_unix_time), + SYM(c_format_unix_time_gmt), + SYM(c_parse_unix_time), + SYM(c_parse_unix_time_gmt), + SYM(__addtf3), + SYM(__divtf3), + SYM(__extenddftf2), + SYM(__fixtfsi), + SYM(__floatditf), + SYM(__floatsitf), + SYM(__getf2), + SYM(__gttf2), + SYM(__lttf2), + SYM(__multf3), + SYM(__subtf3), + SYM(__trunctfdf2), + { 0, 0, STRENGTH_NORMAL, 1 } /* sentinel */ +}; + +RtsSymbolVal* iserv_syms() { + return my_iserv_syms; +} + +// Name used in GHC >=9.12 +RtsSymbolVal* rtsExtraSyms() { + return my_iserv_syms; +} +#endif diff --git a/cbits/symbols.x86_64-windows.c b/cbits/symbols.x86_64-windows.c new file mode 100644 index 0000000..ef34cf4 --- /dev/null +++ b/cbits/symbols.x86_64-windows.c @@ -0,0 +1,44 @@ +#include + +#define MISSING_FUN(f) void (f)(void) { printf("Unknown call to `%s'\n", #f); exit(1); } + +typedef void SymbolAddr; +typedef char SymbolName; + +typedef enum _SymStrength { + STRENGTH_NORMAL, + STRENGTH_WEAK, + STRENGTH_STRONG, +} SymStrength; + +typedef enum _SymType { + SYM_TYPE_CODE = 1 << 0, /* the symbol is a function and can be relocated via a jump island */ + SYM_TYPE_DATA = 1 << 1, /* the symbol is data */ + SYM_TYPE_INDIRECT_DATA = 1 << 2, /* see Note [_iob_func symbol] */ + SYM_TYPE_DUP_DISCARD = 1 << 3, /* the symbol is a symbol in a BFD import library + however if a duplicate is found with a mismatching + SymType then discard this one. */ +} SymType; + +typedef struct _RtsSymbolVal { + const SymbolName* lbl; + SymbolAddr* addr; + SymStrength strength; + SymType type; +} RtsSymbolVal; + +#define SYM(x) { #x, (void*)(&x), STRENGTH_NORMAL, 1 } + +RtsSymbolVal my_iserv_syms[] = { + SYM(log1pf), SYM(log1p), SYM(logf), SYM(log), + { 0, 0, STRENGTH_NORMAL, 1 } /* sentinel */ +}; + +RtsSymbolVal* iserv_syms() { + return my_iserv_syms; +} + +// Name used in GHC >=9.12 +RtsSymbolVal* rtsExtraSyms() { + return my_iserv_syms; +} diff --git a/iserv-proxy.cabal b/iserv-proxy.cabal index 39e5cc6..81e5ab3 100644 --- a/iserv-proxy.cabal +++ b/iserv-proxy.cabal @@ -64,6 +64,12 @@ Description: Category: Development build-type: Simple cabal-version: >=1.10 +-- these aren't really headers. They are more like includable files. +extra-source-files: cbits/symbols.aarch64-musl.h + +flag threaded + default: True + manual: True Library Default-Language: Haskell2010 @@ -74,27 +80,31 @@ Library Build-Depends: array >= 0.5 && < 0.6, base >= 4 && < 5, binary >= 0.7 && < 0.9, - bytestring >= 0.10 && < 0.12, + bytestring >= 0.10 && < 0.13, containers >= 0.5 && < 0.8, - deepseq >= 1.4 && < 1.5, + deepseq >= 1.4 && < 1.6, directory >= 1.3 && < 1.4, network >= 2.6, - filepath >= 1.4 && < 1.5, - ghci == 9.3, - libiserv == 9.3 + filepath >= 1.4 && < 1.6, + ghci + if impl(ghc < 9.8) + Build-Depends: libiserv Executable iserv-proxy Default-Language: Haskell2010 Main-Is: Main.hs Build-Depends: base >= 4 && < 5, binary >= 0.7 && < 0.9, - bytestring >= 0.10 && < 0.12, + bytestring >= 0.10 && < 0.13, directory >= 1.3 && < 1.4, network >= 2.6, - filepath >= 1.4 && < 1.5, - ghci == 9.3, - libiserv == 9.3, + filepath >= 1.4 && < 1.6, + ghci, iserv-proxy + if impl(ghc < 9.8) + Build-Depends: libiserv + if flag(threaded) + ghc-options: -threaded Executable iserv-proxy-interpreter Default-Language: Haskell2010 @@ -102,6 +112,26 @@ Executable iserv-proxy-interpreter -- We need to pass -fkeep-cafs to ensure that the interpreter retains CAFs -- Iserv and GHC do something similar. ghc-options: -fkeep-cafs + + -- no idea how to check for musl :-/ + -- we only build a linux iserv-proxy for musl builds + -- also os(android) is not working (so using `#ifdef __ANDROID__` in the .c files) + if os(linux) || os(android) + if arch(aarch64) + c-sources: cbits/symbols.aarch64-musl.c + c-sources: cbits/symbols.aarch64-android.c + if arch(x86_64) + c-sources: cbits/symbols.x86_64-musl.c + if arch(i386) + c-sources: cbits/symbols.i386-musl.c + c-sources: cbits/symbols.armv7a-android.c + + if os(windows) + if arch(x86_64) + c-sources: cbits/symbols.x86_64-windows.c + Build-Depends: base >= 4 && < 5, iserv-proxy + if flag(threaded) + ghc-options: -threaded diff --git a/src/IServ/Remote/Interpreter.hs b/src/IServ/Remote/Interpreter.hs index 9f8f88f..8ee56a1 100644 --- a/src/IServ/Remote/Interpreter.hs +++ b/src/IServ/Remote/Interpreter.hs @@ -1,9 +1,15 @@ -{-# LANGUAGE ForeignFunctionInterface, GADTs, LambdaCase #-} +{-# LANGUAGE CPP, ForeignFunctionInterface, GADTs, LambdaCase #-} module IServ.Remote.Interpreter where import Network.Socket +#if MIN_VERSION_ghci(9,8,0) +import GHCi.Server (serv) +#elif MIN_VERSION_ghci(9,4,1) import IServ (serv) +#else +import Lib (serv) +#endif import IServ.Remote.Message import System.IO @@ -16,8 +22,11 @@ import System.FilePath (takeDirectory, (), dropTrailingPathSeparator, import GHCi.ResolvedBCO import Data.IORef -import GHCi.Message (Pipe(..), Msg(..), Message(..), readPipe, writePipe) - +import GHCi.Message (Pipe(..), Msg(..), Message(..), readPipe, writePipe +#if MIN_VERSION_ghci(9,13,0) + , mkPipeFromHandles +#endif + ) import Foreign.C.String import Data.Binary @@ -50,14 +59,14 @@ startInterpreter :: Bool -> Int -> CString -> IO () startInterpreter verbose port s = do base_path <- peekCString s trace $ "DocRoot: " ++ base_path - _ <- forkIO $ startInterpreter' verbose base_path (toEnum port) + _ <- forkIO $ startInterpreter' verbose True base_path (toEnum port) return () -- | @startInterpreter'@ provdes a blocking haskell interface, that -- the hosting application on the target can use to start the -- interpreter process. -startInterpreter' :: Bool -> String -> PortNumber -> IO () -startInterpreter' verbose base_path port = do +startInterpreter' :: Bool -> Bool -> String -> PortNumber -> IO () +startInterpreter' verbose noLoadCall base_path port = do hSetBuffering stdin LineBuffering hSetBuffering stdout LineBuffering @@ -79,7 +88,7 @@ startInterpreter' verbose base_path port = do when verbose $ trace "Opening socket" pipe <- acceptSocket sock >>= socketToPipe when verbose $ trace "Starting serv" - uninterruptibleMask $ serv verbose (hook verbose base_path pipe) pipe + uninterruptibleMask $ serv verbose (hook verbose noLoadCall base_path pipe) pipe when verbose $ trace "serv ended" return () @@ -118,8 +127,8 @@ handleLoad pipe path localPath = do -- | The hook we install in the @serv@ function from the -- iserv library, to request archives over the wire. -hook :: Bool -> String -> Pipe -> Msg -> IO Msg -hook verbose base_path pipe m = case m of +hook :: Bool -> Bool -> String -> Pipe -> Msg -> IO Msg +hook verbose noLoadCall base_path pipe m = case m of Msg (AddLibrarySearchPath p) -> do when verbose $ putStrLn ("Need Path: " ++ (base_path p)) createDirectoryIfMissing True (base_path p) @@ -139,7 +148,10 @@ hook verbose base_path pipe m = case m of -- system libraries. Msg (LoadDLL path@('C':':':_)) -> do return m - Msg (LoadDLL path) | isAbsolute path -> do + -- When building on nix the /nix/store paths use Z: + Msg (LoadDLL path@('Z':':':_)) -> do + return m + Msg (LoadDLL path) | isAbsolute path && not noLoadCall -> do when verbose $ trace ("Need DLL: " ++ (base_path path)) handleLoad pipe path (base_path path) return $ Msg (LoadDLL (base_path path)) @@ -151,9 +163,12 @@ socketToPipe :: Socket -> IO Pipe socketToPipe sock = do hdl <- socketToHandle sock ReadWriteMode hSetBuffering hdl NoBuffering - +#if MIN_VERSION_ghci(9,13,0) + mkPipeFromHandles hdl hdl +#else lo_ref <- newIORef Nothing pure Pipe{ pipeRead = hdl, pipeWrite = hdl, pipeLeftovers = lo_ref } +#endif acceptSocket :: Socket -> IO Socket acceptSocket = fmap fst . accept