/ghc-7.0.4/rts/Linker.c
C | 1526 lines | 1199 code | 117 blank | 210 comment | 94 complexity | a6888914a5d23ce40b8b99dfcf181f56 MD5 | raw file
Possible License(s): BSD-3-Clause, BSD-2-Clause
- /* -----------------------------------------------------------------------------
- *
- * (c) The GHC Team, 2000-2004
- *
- * RTS Object Linker
- *
- * ---------------------------------------------------------------------------*/
- #if 0
- #include "PosixSource.h"
- #endif
- /* Linux needs _GNU_SOURCE to get RTLD_DEFAULT from <dlfcn.h> and
- MREMAP_MAYMOVE from <sys/mman.h>.
- */
- #ifdef __linux__
- #define _GNU_SOURCE
- #endif
- #include "Rts.h"
- #include "HsFFI.h"
- #include "sm/Storage.h"
- #include "Stats.h"
- #include "Hash.h"
- #include "LinkerInternals.h"
- #include "RtsUtils.h"
- #include "Trace.h"
- #include "StgPrimFloat.h" // for __int_encodeFloat etc.
- #include "Stable.h"
- #if !defined(mingw32_HOST_OS)
- #include "posix/Signals.h"
- #endif
- // get protos for is*()
- #include <ctype.h>
- #ifdef HAVE_SYS_TYPES_H
- #include <sys/types.h>
- #endif
- #include <inttypes.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- #include <assert.h>
- #ifdef HAVE_SYS_STAT_H
- #include <sys/stat.h>
- #endif
- #if defined(HAVE_DLFCN_H)
- #include <dlfcn.h>
- #endif
- #if defined(cygwin32_HOST_OS)
- #ifdef HAVE_DIRENT_H
- #include <dirent.h>
- #endif
- #ifdef HAVE_SYS_TIME_H
- #include <sys/time.h>
- #endif
- #include <regex.h>
- #include <sys/fcntl.h>
- #include <sys/termios.h>
- #include <sys/utime.h>
- #include <sys/utsname.h>
- #include <sys/wait.h>
- #endif
- #if defined(linux_HOST_OS ) || defined(freebsd_HOST_OS) || \
- defined(dragonfly_HOST_OS) || defined(netbsd_HOST_OS ) || \
- defined(openbsd_HOST_OS ) || \
- ( defined(darwin_HOST_OS ) && !defined(powerpc_HOST_ARCH) )
- /* Don't use mmap on powerpc-apple-darwin as mmap doesn't support
- * reallocating but we need to allocate jump islands just after each
- * object images. Otherwise relative branches to jump islands can fail
- * due to 24-bits displacement overflow.
- */
- #define USE_MMAP
- #include <fcntl.h>
- #include <sys/mman.h>
- #ifdef HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #endif
- #if defined(linux_HOST_OS) || defined(solaris2_HOST_OS) || defined(freebsd_HOST_OS) || defined(dragonfly_HOST_OS) || defined(netbsd_HOST_OS) || defined(openbsd_HOST_OS)
- # define OBJFORMAT_ELF
- # include <regex.h> // regex is already used by dlopen() so this is OK
- // to use here without requiring an additional lib
- #elif defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
- # define OBJFORMAT_PEi386
- # include <windows.h>
- # include <math.h>
- #elif defined(darwin_HOST_OS)
- # define OBJFORMAT_MACHO
- # include <regex.h>
- # include <mach-o/loader.h>
- # include <mach-o/nlist.h>
- # include <mach-o/reloc.h>
- #if !defined(HAVE_DLFCN_H)
- # include <mach-o/dyld.h>
- #endif
- #if defined(powerpc_HOST_ARCH)
- # include <mach-o/ppc/reloc.h>
- #endif
- #if defined(x86_64_HOST_ARCH)
- # include <mach-o/x86_64/reloc.h>
- #endif
- #endif
- #if defined(x86_64_HOST_ARCH) && defined(darwin_HOST_OS)
- #define ALWAYS_PIC
- #endif
- /* Hash table mapping symbol names to Symbol */
- static /*Str*/HashTable *symhash;
- /* Hash table mapping symbol names to StgStablePtr */
- static /*Str*/HashTable *stablehash;
- /* List of currently loaded objects */
- ObjectCode *objects = NULL; /* initially empty */
- static HsInt loadOc( ObjectCode* oc );
- static ObjectCode* mkOc( char *path, char *image, int imageSize,
- char *archiveMemberName
- #ifndef USE_MMAP
- #ifdef darwin_HOST_OS
- , int misalignment
- #endif
- #endif
- );
- #if defined(OBJFORMAT_ELF)
- static int ocVerifyImage_ELF ( ObjectCode* oc );
- static int ocGetNames_ELF ( ObjectCode* oc );
- static int ocResolve_ELF ( ObjectCode* oc );
- #if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
- static int ocAllocateSymbolExtras_ELF ( ObjectCode* oc );
- #endif
- #elif defined(OBJFORMAT_PEi386)
- static int ocVerifyImage_PEi386 ( ObjectCode* oc );
- static int ocGetNames_PEi386 ( ObjectCode* oc );
- static int ocResolve_PEi386 ( ObjectCode* oc );
- static void *lookupSymbolInDLLs ( unsigned char *lbl );
- static void zapTrailingAtSign ( unsigned char *sym );
- #elif defined(OBJFORMAT_MACHO)
- static int ocVerifyImage_MachO ( ObjectCode* oc );
- static int ocGetNames_MachO ( ObjectCode* oc );
- static int ocResolve_MachO ( ObjectCode* oc );
- #ifndef USE_MMAP
- static int machoGetMisalignment( FILE * );
- #endif
- #if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
- static int ocAllocateSymbolExtras_MachO ( ObjectCode* oc );
- #endif
- #ifdef powerpc_HOST_ARCH
- static void machoInitSymbolsWithoutUnderscore( void );
- #endif
- #endif
- /* on x86_64 we have a problem with relocating symbol references in
- * code that was compiled without -fPIC. By default, the small memory
- * model is used, which assumes that symbol references can fit in a
- * 32-bit slot. The system dynamic linker makes this work for
- * references to shared libraries by either (a) allocating a jump
- * table slot for code references, or (b) moving the symbol at load
- * time (and copying its contents, if necessary) for data references.
- *
- * We unfortunately can't tell whether symbol references are to code
- * or data. So for now we assume they are code (the vast majority
- * are), and allocate jump-table slots. Unfortunately this will
- * SILENTLY generate crashing code for data references. This hack is
- * enabled by X86_64_ELF_NONPIC_HACK.
- *
- * One workaround is to use shared Haskell libraries. This is
- * coming. Another workaround is to keep the static libraries but
- * compile them with -fPIC, because that will generate PIC references
- * to data which can be relocated. The PIC code is still too green to
- * do this systematically, though.
- *
- * See bug #781
- * See thread http://www.haskell.org/pipermail/cvs-ghc/2007-September/038458.html
- *
- * Naming Scheme for Symbol Macros
- *
- * SymI_*: symbol is internal to the RTS. It resides in an object
- * file/library that is statically.
- * SymE_*: symbol is external to the RTS library. It might be linked
- * dynamically.
- *
- * Sym*_HasProto : the symbol prototype is imported in an include file
- * or defined explicitly
- * Sym*_NeedsProto: the symbol is undefined and we add a dummy
- * default proto extern void sym(void);
- */
- #define X86_64_ELF_NONPIC_HACK 1
- /* Link objects into the lower 2Gb on x86_64. GHC assumes the
- * small memory model on this architecture (see gcc docs,
- * -mcmodel=small).
- *
- * MAP_32BIT not available on OpenBSD/amd64
- */
- #if defined(x86_64_HOST_ARCH) && defined(MAP_32BIT)
- #define TRY_MAP_32BIT MAP_32BIT
- #else
- #define TRY_MAP_32BIT 0
- #endif
- /*
- * Due to the small memory model (see above), on x86_64 we have to map
- * all our non-PIC object files into the low 2Gb of the address space
- * (why 2Gb and not 4Gb? Because all addresses must be reachable
- * using a 32-bit signed PC-relative offset). On Linux we can do this
- * using the MAP_32BIT flag to mmap(), however on other OSs
- * (e.g. *BSD, see #2063, and also on Linux inside Xen, see #2512), we
- * can't do this. So on these systems, we have to pick a base address
- * in the low 2Gb of the address space and try to allocate memory from
- * there.
- *
- * We pick a default address based on the OS, but also make this
- * configurable via an RTS flag (+RTS -xm)
- */
- #if !defined(ALWAYS_PIC) && defined(x86_64_HOST_ARCH)
- #if defined(MAP_32BIT)
- // Try to use MAP_32BIT
- #define MMAP_32BIT_BASE_DEFAULT 0
- #else
- // A guess: 1Gb.
- #define MMAP_32BIT_BASE_DEFAULT 0x40000000
- #endif
- static void *mmap_32bit_base = (void *)MMAP_32BIT_BASE_DEFAULT;
- #endif
- /* MAP_ANONYMOUS is MAP_ANON on some systems, e.g. OpenBSD */
- #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
- #define MAP_ANONYMOUS MAP_ANON
- #endif
- /* -----------------------------------------------------------------------------
- * Built-in symbols from the RTS
- */
- typedef struct _RtsSymbolVal {
- char *lbl;
- void *addr;
- } RtsSymbolVal;
- #define Maybe_Stable_Names SymI_HasProto(stg_mkWeakzh) \
- SymI_HasProto(stg_mkWeakForeignEnvzh) \
- SymI_HasProto(stg_makeStableNamezh) \
- SymI_HasProto(stg_finalizzeWeakzh)
- #if !defined (mingw32_HOST_OS)
- #define RTS_POSIX_ONLY_SYMBOLS \
- SymI_HasProto(__hscore_get_saved_termios) \
- SymI_HasProto(__hscore_set_saved_termios) \
- SymI_HasProto(shutdownHaskellAndSignal) \
- SymI_HasProto(lockFile) \
- SymI_HasProto(unlockFile) \
- SymI_HasProto(signal_handlers) \
- SymI_HasProto(stg_sig_install) \
- SymI_HasProto(rtsTimerSignal) \
- SymI_NeedsProto(nocldstop)
- #endif
- #if defined (cygwin32_HOST_OS)
- #define RTS_MINGW_ONLY_SYMBOLS /**/
- /* Don't have the ability to read import libs / archives, so
- * we have to stupidly list a lot of what libcygwin.a
- * exports; sigh.
- */
- #define RTS_CYGWIN_ONLY_SYMBOLS \
- SymI_HasProto(regfree) \
- SymI_HasProto(regexec) \
- SymI_HasProto(regerror) \
- SymI_HasProto(regcomp) \
- SymI_HasProto(__errno) \
- SymI_HasProto(access) \
- SymI_HasProto(chmod) \
- SymI_HasProto(chdir) \
- SymI_HasProto(close) \
- SymI_HasProto(creat) \
- SymI_HasProto(dup) \
- SymI_HasProto(dup2) \
- SymI_HasProto(fstat) \
- SymI_HasProto(fcntl) \
- SymI_HasProto(getcwd) \
- SymI_HasProto(getenv) \
- SymI_HasProto(lseek) \
- SymI_HasProto(open) \
- SymI_HasProto(fpathconf) \
- SymI_HasProto(pathconf) \
- SymI_HasProto(stat) \
- SymI_HasProto(pow) \
- SymI_HasProto(tanh) \
- SymI_HasProto(cosh) \
- SymI_HasProto(sinh) \
- SymI_HasProto(atan) \
- SymI_HasProto(acos) \
- SymI_HasProto(asin) \
- SymI_HasProto(tan) \
- SymI_HasProto(cos) \
- SymI_HasProto(sin) \
- SymI_HasProto(exp) \
- SymI_HasProto(log) \
- SymI_HasProto(sqrt) \
- SymI_HasProto(localtime_r) \
- SymI_HasProto(gmtime_r) \
- SymI_HasProto(mktime) \
- SymI_NeedsProto(_imp___tzname) \
- SymI_HasProto(gettimeofday) \
- SymI_HasProto(timezone) \
- SymI_HasProto(tcgetattr) \
- SymI_HasProto(tcsetattr) \
- SymI_HasProto(memcpy) \
- SymI_HasProto(memmove) \
- SymI_HasProto(realloc) \
- SymI_HasProto(malloc) \
- SymI_HasProto(free) \
- SymI_HasProto(fork) \
- SymI_HasProto(lstat) \
- SymI_HasProto(isatty) \
- SymI_HasProto(mkdir) \
- SymI_HasProto(opendir) \
- SymI_HasProto(readdir) \
- SymI_HasProto(rewinddir) \
- SymI_HasProto(closedir) \
- SymI_HasProto(link) \
- SymI_HasProto(mkfifo) \
- SymI_HasProto(pipe) \
- SymI_HasProto(read) \
- SymI_HasProto(rename) \
- SymI_HasProto(rmdir) \
- SymI_HasProto(select) \
- SymI_HasProto(system) \
- SymI_HasProto(write) \
- SymI_HasProto(strcmp) \
- SymI_HasProto(strcpy) \
- SymI_HasProto(strncpy) \
- SymI_HasProto(strerror) \
- SymI_HasProto(sigaddset) \
- SymI_HasProto(sigemptyset) \
- SymI_HasProto(sigprocmask) \
- SymI_HasProto(umask) \
- SymI_HasProto(uname) \
- SymI_HasProto(unlink) \
- SymI_HasProto(utime) \
- SymI_HasProto(waitpid)
- #elif !defined(mingw32_HOST_OS)
- #define RTS_MINGW_ONLY_SYMBOLS /**/
- #define RTS_CYGWIN_ONLY_SYMBOLS /**/
- #else /* defined(mingw32_HOST_OS) */
- #define RTS_POSIX_ONLY_SYMBOLS /**/
- #define RTS_CYGWIN_ONLY_SYMBOLS /**/
- #if HAVE_GETTIMEOFDAY
- #define RTS_MINGW_GETTIMEOFDAY_SYM SymI_NeedsProto(gettimeofday)
- #else
- #define RTS_MINGW_GETTIMEOFDAY_SYM /**/
- #endif
- #if HAVE___MINGW_VFPRINTF
- #define RTS___MINGW_VFPRINTF_SYM SymI_HasProto(__mingw_vfprintf)
- #else
- #define RTS___MINGW_VFPRINTF_SYM /**/
- #endif
- /* These are statically linked from the mingw libraries into the ghc
- executable, so we have to employ this hack. */
- #define RTS_MINGW_ONLY_SYMBOLS \
- SymI_HasProto(stg_asyncReadzh) \
- SymI_HasProto(stg_asyncWritezh) \
- SymI_HasProto(stg_asyncDoProczh) \
- SymI_HasProto(memset) \
- SymI_HasProto(inet_ntoa) \
- SymI_HasProto(inet_addr) \
- SymI_HasProto(htonl) \
- SymI_HasProto(recvfrom) \
- SymI_HasProto(listen) \
- SymI_HasProto(bind) \
- SymI_HasProto(shutdown) \
- SymI_HasProto(connect) \
- SymI_HasProto(htons) \
- SymI_HasProto(ntohs) \
- SymI_HasProto(getservbyname) \
- SymI_HasProto(getservbyport) \
- SymI_HasProto(getprotobynumber) \
- SymI_HasProto(getprotobyname) \
- SymI_HasProto(gethostbyname) \
- SymI_HasProto(gethostbyaddr) \
- SymI_HasProto(gethostname) \
- SymI_HasProto(strcpy) \
- SymI_HasProto(strncpy) \
- SymI_HasProto(abort) \
- SymI_NeedsProto(_alloca) \
- SymI_HasProto(isxdigit) \
- SymI_HasProto(isupper) \
- SymI_HasProto(ispunct) \
- SymI_HasProto(islower) \
- SymI_HasProto(isspace) \
- SymI_HasProto(isprint) \
- SymI_HasProto(isdigit) \
- SymI_HasProto(iscntrl) \
- SymI_HasProto(isalpha) \
- SymI_HasProto(isalnum) \
- SymI_HasProto(isascii) \
- RTS___MINGW_VFPRINTF_SYM \
- SymI_HasProto(strcmp) \
- SymI_HasProto(memmove) \
- SymI_HasProto(realloc) \
- SymI_HasProto(malloc) \
- SymI_HasProto(pow) \
- SymI_HasProto(tanh) \
- SymI_HasProto(cosh) \
- SymI_HasProto(sinh) \
- SymI_HasProto(atan) \
- SymI_HasProto(acos) \
- SymI_HasProto(asin) \
- SymI_HasProto(tan) \
- SymI_HasProto(cos) \
- SymI_HasProto(sin) \
- SymI_HasProto(exp) \
- SymI_HasProto(log) \
- SymI_HasProto(sqrt) \
- SymI_HasProto(powf) \
- SymI_HasProto(tanhf) \
- SymI_HasProto(coshf) \
- SymI_HasProto(sinhf) \
- SymI_HasProto(atanf) \
- SymI_HasProto(acosf) \
- SymI_HasProto(asinf) \
- SymI_HasProto(tanf) \
- SymI_HasProto(cosf) \
- SymI_HasProto(sinf) \
- SymI_HasProto(expf) \
- SymI_HasProto(logf) \
- SymI_HasProto(sqrtf) \
- SymI_HasProto(erf) \
- SymI_HasProto(erfc) \
- SymI_HasProto(erff) \
- SymI_HasProto(erfcf) \
- SymI_HasProto(memcpy) \
- SymI_HasProto(rts_InstallConsoleEvent) \
- SymI_HasProto(rts_ConsoleHandlerDone) \
- SymI_NeedsProto(mktime) \
- SymI_NeedsProto(_imp___timezone) \
- SymI_NeedsProto(_imp___tzname) \
- SymI_NeedsProto(_imp__tzname) \
- SymI_NeedsProto(_imp___iob) \
- SymI_NeedsProto(_imp___osver) \
- SymI_NeedsProto(localtime) \
- SymI_NeedsProto(gmtime) \
- SymI_NeedsProto(opendir) \
- SymI_NeedsProto(readdir) \
- SymI_NeedsProto(rewinddir) \
- SymI_NeedsProto(_imp____mb_cur_max) \
- SymI_NeedsProto(_imp___pctype) \
- SymI_NeedsProto(__chkstk) \
- RTS_MINGW_GETTIMEOFDAY_SYM \
- SymI_NeedsProto(closedir)
- #endif
- #if defined(darwin_HOST_OS) && HAVE_PRINTF_LDBLSTUB
- #define RTS_DARWIN_ONLY_SYMBOLS \
- SymI_NeedsProto(asprintf$LDBLStub) \
- SymI_NeedsProto(err$LDBLStub) \
- SymI_NeedsProto(errc$LDBLStub) \
- SymI_NeedsProto(errx$LDBLStub) \
- SymI_NeedsProto(fprintf$LDBLStub) \
- SymI_NeedsProto(fscanf$LDBLStub) \
- SymI_NeedsProto(fwprintf$LDBLStub) \
- SymI_NeedsProto(fwscanf$LDBLStub) \
- SymI_NeedsProto(printf$LDBLStub) \
- SymI_NeedsProto(scanf$LDBLStub) \
- SymI_NeedsProto(snprintf$LDBLStub) \
- SymI_NeedsProto(sprintf$LDBLStub) \
- SymI_NeedsProto(sscanf$LDBLStub) \
- SymI_NeedsProto(strtold$LDBLStub) \
- SymI_NeedsProto(swprintf$LDBLStub) \
- SymI_NeedsProto(swscanf$LDBLStub) \
- SymI_NeedsProto(syslog$LDBLStub) \
- SymI_NeedsProto(vasprintf$LDBLStub) \
- SymI_NeedsProto(verr$LDBLStub) \
- SymI_NeedsProto(verrc$LDBLStub) \
- SymI_NeedsProto(verrx$LDBLStub) \
- SymI_NeedsProto(vfprintf$LDBLStub) \
- SymI_NeedsProto(vfscanf$LDBLStub) \
- SymI_NeedsProto(vfwprintf$LDBLStub) \
- SymI_NeedsProto(vfwscanf$LDBLStub) \
- SymI_NeedsProto(vprintf$LDBLStub) \
- SymI_NeedsProto(vscanf$LDBLStub) \
- SymI_NeedsProto(vsnprintf$LDBLStub) \
- SymI_NeedsProto(vsprintf$LDBLStub) \
- SymI_NeedsProto(vsscanf$LDBLStub) \
- SymI_NeedsProto(vswprintf$LDBLStub) \
- SymI_NeedsProto(vswscanf$LDBLStub) \
- SymI_NeedsProto(vsyslog$LDBLStub) \
- SymI_NeedsProto(vwarn$LDBLStub) \
- SymI_NeedsProto(vwarnc$LDBLStub) \
- SymI_NeedsProto(vwarnx$LDBLStub) \
- SymI_NeedsProto(vwprintf$LDBLStub) \
- SymI_NeedsProto(vwscanf$LDBLStub) \
- SymI_NeedsProto(warn$LDBLStub) \
- SymI_NeedsProto(warnc$LDBLStub) \
- SymI_NeedsProto(warnx$LDBLStub) \
- SymI_NeedsProto(wcstold$LDBLStub) \
- SymI_NeedsProto(wprintf$LDBLStub) \
- SymI_NeedsProto(wscanf$LDBLStub)
- #else
- #define RTS_DARWIN_ONLY_SYMBOLS
- #endif
- #ifndef SMP
- # define MAIN_CAP_SYM SymI_HasProto(MainCapability)
- #else
- # define MAIN_CAP_SYM
- #endif
- #if !defined(mingw32_HOST_OS)
- #define RTS_USER_SIGNALS_SYMBOLS \
- SymI_HasProto(setIOManagerControlFd) \
- SymI_HasProto(setIOManagerWakeupFd) \
- SymI_HasProto(ioManagerWakeup) \
- SymI_HasProto(blockUserSignals) \
- SymI_HasProto(unblockUserSignals)
- #else
- #define RTS_USER_SIGNALS_SYMBOLS \
- SymI_HasProto(ioManagerWakeup) \
- SymI_HasProto(sendIOManagerEvent) \
- SymI_HasProto(readIOManagerEvent) \
- SymI_HasProto(getIOManagerEvent) \
- SymI_HasProto(console_handler)
- #endif
- #define RTS_LIBFFI_SYMBOLS \
- SymE_NeedsProto(ffi_prep_cif) \
- SymE_NeedsProto(ffi_call) \
- SymE_NeedsProto(ffi_type_void) \
- SymE_NeedsProto(ffi_type_float) \
- SymE_NeedsProto(ffi_type_double) \
- SymE_NeedsProto(ffi_type_sint64) \
- SymE_NeedsProto(ffi_type_uint64) \
- SymE_NeedsProto(ffi_type_sint32) \
- SymE_NeedsProto(ffi_type_uint32) \
- SymE_NeedsProto(ffi_type_sint16) \
- SymE_NeedsProto(ffi_type_uint16) \
- SymE_NeedsProto(ffi_type_sint8) \
- SymE_NeedsProto(ffi_type_uint8) \
- SymE_NeedsProto(ffi_type_pointer)
- #ifdef TABLES_NEXT_TO_CODE
- #define RTS_RET_SYMBOLS /* nothing */
- #else
- #define RTS_RET_SYMBOLS \
- SymI_HasProto(stg_enter_ret) \
- SymI_HasProto(stg_gc_fun_ret) \
- SymI_HasProto(stg_ap_v_ret) \
- SymI_HasProto(stg_ap_f_ret) \
- SymI_HasProto(stg_ap_d_ret) \
- SymI_HasProto(stg_ap_l_ret) \
- SymI_HasProto(stg_ap_n_ret) \
- SymI_HasProto(stg_ap_p_ret) \
- SymI_HasProto(stg_ap_pv_ret) \
- SymI_HasProto(stg_ap_pp_ret) \
- SymI_HasProto(stg_ap_ppv_ret) \
- SymI_HasProto(stg_ap_ppp_ret) \
- SymI_HasProto(stg_ap_pppv_ret) \
- SymI_HasProto(stg_ap_pppp_ret) \
- SymI_HasProto(stg_ap_ppppp_ret) \
- SymI_HasProto(stg_ap_pppppp_ret)
- #endif
- /* Modules compiled with -ticky may mention ticky counters */
- /* This list should marry up with the one in $(TOP)/includes/stg/Ticky.h */
- #define RTS_TICKY_SYMBOLS \
- SymI_NeedsProto(ticky_entry_ctrs) \
- SymI_NeedsProto(top_ct) \
- \
- SymI_HasProto(ENT_VIA_NODE_ctr) \
- SymI_HasProto(ENT_STATIC_THK_ctr) \
- SymI_HasProto(ENT_DYN_THK_ctr) \
- SymI_HasProto(ENT_STATIC_FUN_DIRECT_ctr) \
- SymI_HasProto(ENT_DYN_FUN_DIRECT_ctr) \
- SymI_HasProto(ENT_STATIC_CON_ctr) \
- SymI_HasProto(ENT_DYN_CON_ctr) \
- SymI_HasProto(ENT_STATIC_IND_ctr) \
- SymI_HasProto(ENT_DYN_IND_ctr) \
- SymI_HasProto(ENT_PERM_IND_ctr) \
- SymI_HasProto(ENT_PAP_ctr) \
- SymI_HasProto(ENT_AP_ctr) \
- SymI_HasProto(ENT_AP_STACK_ctr) \
- SymI_HasProto(ENT_BH_ctr) \
- SymI_HasProto(UNKNOWN_CALL_ctr) \
- SymI_HasProto(SLOW_CALL_v_ctr) \
- SymI_HasProto(SLOW_CALL_f_ctr) \
- SymI_HasProto(SLOW_CALL_d_ctr) \
- SymI_HasProto(SLOW_CALL_l_ctr) \
- SymI_HasProto(SLOW_CALL_n_ctr) \
- SymI_HasProto(SLOW_CALL_p_ctr) \
- SymI_HasProto(SLOW_CALL_pv_ctr) \
- SymI_HasProto(SLOW_CALL_pp_ctr) \
- SymI_HasProto(SLOW_CALL_ppv_ctr) \
- SymI_HasProto(SLOW_CALL_ppp_ctr) \
- SymI_HasProto(SLOW_CALL_pppv_ctr) \
- SymI_HasProto(SLOW_CALL_pppp_ctr) \
- SymI_HasProto(SLOW_CALL_ppppp_ctr) \
- SymI_HasProto(SLOW_CALL_pppppp_ctr) \
- SymI_HasProto(SLOW_CALL_OTHER_ctr) \
- SymI_HasProto(ticky_slow_call_unevald) \
- SymI_HasProto(SLOW_CALL_ctr) \
- SymI_HasProto(MULTI_CHUNK_SLOW_CALL_ctr) \
- SymI_HasProto(MULTI_CHUNK_SLOW_CALL_CHUNKS_ctr) \
- SymI_HasProto(KNOWN_CALL_ctr) \
- SymI_HasProto(KNOWN_CALL_TOO_FEW_ARGS_ctr) \
- SymI_HasProto(KNOWN_CALL_EXTRA_ARGS_ctr) \
- SymI_HasProto(SLOW_CALL_FUN_TOO_FEW_ctr) \
- SymI_HasProto(SLOW_CALL_FUN_CORRECT_ctr) \
- SymI_HasProto(SLOW_CALL_FUN_TOO_MANY_ctr) \
- SymI_HasProto(SLOW_CALL_PAP_TOO_FEW_ctr) \
- SymI_HasProto(SLOW_CALL_PAP_CORRECT_ctr) \
- SymI_HasProto(SLOW_CALL_PAP_TOO_MANY_ctr) \
- SymI_HasProto(SLOW_CALL_UNEVALD_ctr) \
- SymI_HasProto(UPDF_OMITTED_ctr) \
- SymI_HasProto(UPDF_PUSHED_ctr) \
- SymI_HasProto(CATCHF_PUSHED_ctr) \
- SymI_HasProto(UPDF_RCC_PUSHED_ctr) \
- SymI_HasProto(UPDF_RCC_OMITTED_ctr) \
- SymI_HasProto(UPD_SQUEEZED_ctr) \
- SymI_HasProto(UPD_CON_IN_NEW_ctr) \
- SymI_HasProto(UPD_CON_IN_PLACE_ctr) \
- SymI_HasProto(UPD_PAP_IN_NEW_ctr) \
- SymI_HasProto(UPD_PAP_IN_PLACE_ctr) \
- SymI_HasProto(ALLOC_HEAP_ctr) \
- SymI_HasProto(ALLOC_HEAP_tot) \
- SymI_HasProto(ALLOC_FUN_ctr) \
- SymI_HasProto(ALLOC_FUN_adm) \
- SymI_HasProto(ALLOC_FUN_gds) \
- SymI_HasProto(ALLOC_FUN_slp) \
- SymI_HasProto(UPD_NEW_IND_ctr) \
- SymI_HasProto(UPD_NEW_PERM_IND_ctr) \
- SymI_HasProto(UPD_OLD_IND_ctr) \
- SymI_HasProto(UPD_OLD_PERM_IND_ctr) \
- SymI_HasProto(UPD_BH_UPDATABLE_ctr) \
- SymI_HasProto(UPD_BH_SINGLE_ENTRY_ctr) \
- SymI_HasProto(UPD_CAF_BH_UPDATABLE_ctr) \
- SymI_HasProto(UPD_CAF_BH_SINGLE_ENTRY_ctr) \
- SymI_HasProto(GC_SEL_ABANDONED_ctr) \
- SymI_HasProto(GC_SEL_MINOR_ctr) \
- SymI_HasProto(GC_SEL_MAJOR_ctr) \
- SymI_HasProto(GC_FAILED_PROMOTION_ctr) \
- SymI_HasProto(ALLOC_UP_THK_ctr) \
- SymI_HasProto(ALLOC_SE_THK_ctr) \
- SymI_HasProto(ALLOC_THK_adm) \
- SymI_HasProto(ALLOC_THK_gds) \
- SymI_HasProto(ALLOC_THK_slp) \
- SymI_HasProto(ALLOC_CON_ctr) \
- SymI_HasProto(ALLOC_CON_adm) \
- SymI_HasProto(ALLOC_CON_gds) \
- SymI_HasProto(ALLOC_CON_slp) \
- SymI_HasProto(ALLOC_TUP_ctr) \
- SymI_HasProto(ALLOC_TUP_adm) \
- SymI_HasProto(ALLOC_TUP_gds) \
- SymI_HasProto(ALLOC_TUP_slp) \
- SymI_HasProto(ALLOC_BH_ctr) \
- SymI_HasProto(ALLOC_BH_adm) \
- SymI_HasProto(ALLOC_BH_gds) \
- SymI_HasProto(ALLOC_BH_slp) \
- SymI_HasProto(ALLOC_PRIM_ctr) \
- SymI_HasProto(ALLOC_PRIM_adm) \
- SymI_HasProto(ALLOC_PRIM_gds) \
- SymI_HasProto(ALLOC_PRIM_slp) \
- SymI_HasProto(ALLOC_PAP_ctr) \
- SymI_HasProto(ALLOC_PAP_adm) \
- SymI_HasProto(ALLOC_PAP_gds) \
- SymI_HasProto(ALLOC_PAP_slp) \
- SymI_HasProto(ALLOC_TSO_ctr) \
- SymI_HasProto(ALLOC_TSO_adm) \
- SymI_HasProto(ALLOC_TSO_gds) \
- SymI_HasProto(ALLOC_TSO_slp) \
- SymI_HasProto(RET_NEW_ctr) \
- SymI_HasProto(RET_OLD_ctr) \
- SymI_HasProto(RET_UNBOXED_TUP_ctr) \
- SymI_HasProto(RET_SEMI_loads_avoided)
- // On most platforms, the garbage collector rewrites references
- // to small integer and char objects to a set of common, shared ones.
- //
- // We don't do this when compiling to Windows DLLs at the moment because
- // it doesn't support cross package data references well.
- //
- #if defined(__PIC__) && defined(mingw32_HOST_OS)
- #define RTS_INTCHAR_SYMBOLS
- #else
- #define RTS_INTCHAR_SYMBOLS \
- SymI_HasProto(stg_CHARLIKE_closure) \
- SymI_HasProto(stg_INTLIKE_closure)
- #endif
- #define RTS_SYMBOLS \
- Maybe_Stable_Names \
- RTS_TICKY_SYMBOLS \
- SymI_HasProto(StgReturn) \
- SymI_HasProto(stg_enter_info) \
- SymI_HasProto(stg_gc_void_info) \
- SymI_HasProto(__stg_gc_enter_1) \
- SymI_HasProto(stg_gc_noregs) \
- SymI_HasProto(stg_gc_unpt_r1_info) \
- SymI_HasProto(stg_gc_unpt_r1) \
- SymI_HasProto(stg_gc_unbx_r1_info) \
- SymI_HasProto(stg_gc_unbx_r1) \
- SymI_HasProto(stg_gc_f1_info) \
- SymI_HasProto(stg_gc_f1) \
- SymI_HasProto(stg_gc_d1_info) \
- SymI_HasProto(stg_gc_d1) \
- SymI_HasProto(stg_gc_l1_info) \
- SymI_HasProto(stg_gc_l1) \
- SymI_HasProto(__stg_gc_fun) \
- SymI_HasProto(stg_gc_fun_info) \
- SymI_HasProto(stg_gc_gen) \
- SymI_HasProto(stg_gc_gen_info) \
- SymI_HasProto(stg_gc_gen_hp) \
- SymI_HasProto(stg_gc_ut) \
- SymI_HasProto(stg_gen_yield) \
- SymI_HasProto(stg_yield_noregs) \
- SymI_HasProto(stg_yield_to_interpreter) \
- SymI_HasProto(stg_gen_block) \
- SymI_HasProto(stg_block_noregs) \
- SymI_HasProto(stg_block_1) \
- SymI_HasProto(stg_block_takemvar) \
- SymI_HasProto(stg_block_putmvar) \
- MAIN_CAP_SYM \
- SymI_HasProto(MallocFailHook) \
- SymI_HasProto(OnExitHook) \
- SymI_HasProto(OutOfHeapHook) \
- SymI_HasProto(StackOverflowHook) \
- SymI_HasProto(addDLL) \
- SymI_HasProto(__int_encodeDouble) \
- SymI_HasProto(__word_encodeDouble) \
- SymI_HasProto(__2Int_encodeDouble) \
- SymI_HasProto(__int_encodeFloat) \
- SymI_HasProto(__word_encodeFloat) \
- SymI_HasProto(stg_atomicallyzh) \
- SymI_HasProto(barf) \
- SymI_HasProto(debugBelch) \
- SymI_HasProto(errorBelch) \
- SymI_HasProto(sysErrorBelch) \
- SymI_HasProto(stg_getMaskingStatezh) \
- SymI_HasProto(stg_maskAsyncExceptionszh) \
- SymI_HasProto(stg_maskUninterruptiblezh) \
- SymI_HasProto(stg_catchzh) \
- SymI_HasProto(stg_catchRetryzh) \
- SymI_HasProto(stg_catchSTMzh) \
- SymI_HasProto(stg_checkzh) \
- SymI_HasProto(closure_flags) \
- SymI_HasProto(cmp_thread) \
- SymI_HasProto(createAdjustor) \
- SymI_HasProto(stg_decodeDoublezu2Intzh) \
- SymI_HasProto(stg_decodeFloatzuIntzh) \
- SymI_HasProto(defaultsHook) \
- SymI_HasProto(stg_delayzh) \
- SymI_HasProto(stg_deRefWeakzh) \
- SymI_HasProto(stg_deRefStablePtrzh) \
- SymI_HasProto(dirty_MUT_VAR) \
- SymI_HasProto(stg_forkzh) \
- SymI_HasProto(stg_forkOnzh) \
- SymI_HasProto(forkProcess) \
- SymI_HasProto(forkOS_createThread) \
- SymI_HasProto(freeHaskellFunctionPtr) \
- SymI_HasProto(getOrSetTypeableStore) \
- SymI_HasProto(getOrSetGHCConcSignalSignalHandlerStore) \
- SymI_HasProto(getOrSetGHCConcWindowsPendingDelaysStore) \
- SymI_HasProto(getOrSetGHCConcWindowsIOManagerThreadStore) \
- SymI_HasProto(getOrSetGHCConcWindowsProddingStore) \
- SymI_HasProto(getOrSetSystemEventThreadEventManagerStore) \
- SymI_HasProto(getOrSetSystemEventThreadIOManagerThreadStore) \
- SymI_HasProto(genSymZh) \
- SymI_HasProto(genericRaise) \
- SymI_HasProto(getProgArgv) \
- SymI_HasProto(getFullProgArgv) \
- SymI_HasProto(getStablePtr) \
- SymI_HasProto(hs_init) \
- SymI_HasProto(hs_exit) \
- SymI_HasProto(hs_set_argv) \
- SymI_HasProto(hs_add_root) \
- SymI_HasProto(hs_perform_gc) \
- SymI_HasProto(hs_free_stable_ptr) \
- SymI_HasProto(hs_free_fun_ptr) \
- SymI_HasProto(hs_hpc_rootModule) \
- SymI_HasProto(hs_hpc_module) \
- SymI_HasProto(initLinker) \
- SymI_HasProto(stg_unpackClosurezh) \
- SymI_HasProto(stg_getApStackValzh) \
- SymI_HasProto(stg_getSparkzh) \
- SymI_HasProto(stg_numSparkszh) \
- SymI_HasProto(stg_isCurrentThreadBoundzh) \
- SymI_HasProto(stg_isEmptyMVarzh) \
- SymI_HasProto(stg_killThreadzh) \
- SymI_HasProto(loadArchive) \
- SymI_HasProto(loadObj) \
- SymI_HasProto(insertStableSymbol) \
- SymI_HasProto(insertSymbol) \
- SymI_HasProto(lookupSymbol) \
- SymI_HasProto(stg_makeStablePtrzh) \
- SymI_HasProto(stg_mkApUpd0zh) \
- SymI_HasProto(stg_myThreadIdzh) \
- SymI_HasProto(stg_labelThreadzh) \
- SymI_HasProto(stg_newArrayzh) \
- SymI_HasProto(stg_newBCOzh) \
- SymI_HasProto(stg_newByteArrayzh) \
- SymI_HasProto_redirect(newCAF, newDynCAF) \
- SymI_HasProto(stg_newMVarzh) \
- SymI_HasProto(stg_newMutVarzh) \
- SymI_HasProto(stg_newTVarzh) \
- SymI_HasProto(stg_noDuplicatezh) \
- SymI_HasProto(stg_atomicModifyMutVarzh) \
- SymI_HasProto(stg_newPinnedByteArrayzh) \
- SymI_HasProto(stg_newAlignedPinnedByteArrayzh) \
- SymI_HasProto(newSpark) \
- SymI_HasProto(performGC) \
- SymI_HasProto(performMajorGC) \
- SymI_HasProto(prog_argc) \
- SymI_HasProto(prog_argv) \
- SymI_HasProto(stg_putMVarzh) \
- SymI_HasProto(stg_raisezh) \
- SymI_HasProto(stg_raiseIOzh) \
- SymI_HasProto(stg_readTVarzh) \
- SymI_HasProto(stg_readTVarIOzh) \
- SymI_HasProto(resumeThread) \
- SymI_HasProto(resolveObjs) \
- SymI_HasProto(stg_retryzh) \
- SymI_HasProto(rts_apply) \
- SymI_HasProto(rts_checkSchedStatus) \
- SymI_HasProto(rts_eval) \
- SymI_HasProto(rts_evalIO) \
- SymI_HasProto(rts_evalLazyIO) \
- SymI_HasProto(rts_evalStableIO) \
- SymI_HasProto(rts_eval_) \
- SymI_HasProto(rts_getBool) \
- SymI_HasProto(rts_getChar) \
- SymI_HasProto(rts_getDouble) \
- SymI_HasProto(rts_getFloat) \
- SymI_HasProto(rts_getInt) \
- SymI_HasProto(rts_getInt8) \
- SymI_HasProto(rts_getInt16) \
- SymI_HasProto(rts_getInt32) \
- SymI_HasProto(rts_getInt64) \
- SymI_HasProto(rts_getPtr) \
- SymI_HasProto(rts_getFunPtr) \
- SymI_HasProto(rts_getStablePtr) \
- SymI_HasProto(rts_getThreadId) \
- SymI_HasProto(rts_getWord) \
- SymI_HasProto(rts_getWord8) \
- SymI_HasProto(rts_getWord16) \
- SymI_HasProto(rts_getWord32) \
- SymI_HasProto(rts_getWord64) \
- SymI_HasProto(rts_lock) \
- SymI_HasProto(rts_mkBool) \
- SymI_HasProto(rts_mkChar) \
- SymI_HasProto(rts_mkDouble) \
- SymI_HasProto(rts_mkFloat) \
- SymI_HasProto(rts_mkInt) \
- SymI_HasProto(rts_mkInt8) \
- SymI_HasProto(rts_mkInt16) \
- SymI_HasProto(rts_mkInt32) \
- SymI_HasProto(rts_mkInt64) \
- SymI_HasProto(rts_mkPtr) \
- SymI_HasProto(rts_mkFunPtr) \
- SymI_HasProto(rts_mkStablePtr) \
- SymI_HasProto(rts_mkString) \
- SymI_HasProto(rts_mkWord) \
- SymI_HasProto(rts_mkWord8) \
- SymI_HasProto(rts_mkWord16) \
- SymI_HasProto(rts_mkWord32) \
- SymI_HasProto(rts_mkWord64) \
- SymI_HasProto(rts_unlock) \
- SymI_HasProto(rts_unsafeGetMyCapability) \
- SymI_HasProto(rtsSupportsBoundThreads) \
- SymI_HasProto(rts_isProfiled) \
- SymI_HasProto(setProgArgv) \
- SymI_HasProto(startupHaskell) \
- SymI_HasProto(shutdownHaskell) \
- SymI_HasProto(shutdownHaskellAndExit) \
- SymI_HasProto(stable_ptr_table) \
- SymI_HasProto(stackOverflow) \
- SymI_HasProto(stg_CAF_BLACKHOLE_info) \
- SymI_HasProto(stg_BLACKHOLE_info) \
- SymI_HasProto(__stg_EAGER_BLACKHOLE_info) \
- SymI_HasProto(stg_BLOCKING_QUEUE_CLEAN_info) \
- SymI_HasProto(stg_BLOCKING_QUEUE_DIRTY_info) \
- SymI_HasProto(startTimer) \
- SymI_HasProto(stg_MVAR_CLEAN_info) \
- SymI_HasProto(stg_MVAR_DIRTY_info) \
- SymI_HasProto(stg_IND_STATIC_info) \
- SymI_HasProto(stg_ARR_WORDS_info) \
- SymI_HasProto(stg_MUT_ARR_PTRS_DIRTY_info) \
- SymI_HasProto(stg_MUT_ARR_PTRS_FROZEN_info) \
- SymI_HasProto(stg_MUT_ARR_PTRS_FROZEN0_info) \
- SymI_HasProto(stg_WEAK_info) \
- SymI_HasProto(stg_ap_v_info) \
- SymI_HasProto(stg_ap_f_info) \
- SymI_HasProto(stg_ap_d_info) \
- SymI_HasProto(stg_ap_l_info) \
- SymI_HasProto(stg_ap_n_info) \
- SymI_HasProto(stg_ap_p_info) \
- SymI_HasProto(stg_ap_pv_info) \
- SymI_HasProto(stg_ap_pp_info) \
- SymI_HasProto(stg_ap_ppv_info) \
- SymI_HasProto(stg_ap_ppp_info) \
- SymI_HasProto(stg_ap_pppv_info) \
- SymI_HasProto(stg_ap_pppp_info) \
- SymI_HasProto(stg_ap_ppppp_info) \
- SymI_HasProto(stg_ap_pppppp_info) \
- SymI_HasProto(stg_ap_0_fast) \
- SymI_HasProto(stg_ap_v_fast) \
- SymI_HasProto(stg_ap_f_fast) \
- SymI_HasProto(stg_ap_d_fast) \
- SymI_HasProto(stg_ap_l_fast) \
- SymI_HasProto(stg_ap_n_fast) \
- SymI_HasProto(stg_ap_p_fast) \
- SymI_HasProto(stg_ap_pv_fast) \
- SymI_HasProto(stg_ap_pp_fast) \
- SymI_HasProto(stg_ap_ppv_fast) \
- SymI_HasProto(stg_ap_ppp_fast) \
- SymI_HasProto(stg_ap_pppv_fast) \
- SymI_HasProto(stg_ap_pppp_fast) \
- SymI_HasProto(stg_ap_ppppp_fast) \
- SymI_HasProto(stg_ap_pppppp_fast) \
- SymI_HasProto(stg_ap_1_upd_info) \
- SymI_HasProto(stg_ap_2_upd_info) \
- SymI_HasProto(stg_ap_3_upd_info) \
- SymI_HasProto(stg_ap_4_upd_info) \
- SymI_HasProto(stg_ap_5_upd_info) \
- SymI_HasProto(stg_ap_6_upd_info) \
- SymI_HasProto(stg_ap_7_upd_info) \
- SymI_HasProto(stg_exit) \
- SymI_HasProto(stg_sel_0_upd_info) \
- SymI_HasProto(stg_sel_10_upd_info) \
- SymI_HasProto(stg_sel_11_upd_info) \
- SymI_HasProto(stg_sel_12_upd_info) \
- SymI_HasProto(stg_sel_13_upd_info) \
- SymI_HasProto(stg_sel_14_upd_info) \
- SymI_HasProto(stg_sel_15_upd_info) \
- SymI_HasProto(stg_sel_1_upd_info) \
- SymI_HasProto(stg_sel_2_upd_info) \
- SymI_HasProto(stg_sel_3_upd_info) \
- SymI_HasProto(stg_sel_4_upd_info) \
- SymI_HasProto(stg_sel_5_upd_info) \
- SymI_HasProto(stg_sel_6_upd_info) \
- SymI_HasProto(stg_sel_7_upd_info) \
- SymI_HasProto(stg_sel_8_upd_info) \
- SymI_HasProto(stg_sel_9_upd_info) \
- SymI_HasProto(stg_upd_frame_info) \
- SymI_HasProto(stg_bh_upd_frame_info) \
- SymI_HasProto(suspendThread) \
- SymI_HasProto(stg_takeMVarzh) \
- SymI_HasProto(stg_threadStatuszh) \
- SymI_HasProto(stg_tryPutMVarzh) \
- SymI_HasProto(stg_tryTakeMVarzh) \
- SymI_HasProto(stg_unmaskAsyncExceptionszh) \
- SymI_HasProto(unloadObj) \
- SymI_HasProto(stg_unsafeThawArrayzh) \
- SymI_HasProto(stg_waitReadzh) \
- SymI_HasProto(stg_waitWritezh) \
- SymI_HasProto(stg_writeTVarzh) \
- SymI_HasProto(stg_yieldzh) \
- SymI_NeedsProto(stg_interp_constr_entry) \
- SymI_HasProto(stg_arg_bitmaps) \
- SymI_HasProto(alloc_blocks_lim) \
- SymI_HasProto(g0) \
- SymI_HasProto(allocate) \
- SymI_HasProto(allocateExec) \
- SymI_HasProto(freeExec) \
- SymI_HasProto(getAllocations) \
- SymI_HasProto(revertCAFs) \
- SymI_HasProto(RtsFlags) \
- SymI_NeedsProto(rts_breakpoint_io_action) \
- SymI_NeedsProto(rts_stop_next_breakpoint) \
- SymI_NeedsProto(rts_stop_on_exception) \
- SymI_HasProto(stopTimer) \
- SymI_HasProto(n_capabilities) \
- SymI_HasProto(stg_traceCcszh) \
- SymI_HasProto(stg_traceEventzh) \
- RTS_USER_SIGNALS_SYMBOLS \
- RTS_INTCHAR_SYMBOLS
- // 64-bit support functions in libgcc.a
- #if defined(__GNUC__) && SIZEOF_VOID_P <= 4
- #define RTS_LIBGCC_SYMBOLS \
- SymI_NeedsProto(__divdi3) \
- SymI_NeedsProto(__udivdi3) \
- SymI_NeedsProto(__moddi3) \
- SymI_NeedsProto(__umoddi3) \
- SymI_NeedsProto(__muldi3) \
- SymI_NeedsProto(__ashldi3) \
- SymI_NeedsProto(__ashrdi3) \
- SymI_NeedsProto(__lshrdi3)
- #else
- #define RTS_LIBGCC_SYMBOLS
- #endif
- #if defined(darwin_HOST_OS) && defined(powerpc_HOST_ARCH)
- // Symbols that don't have a leading underscore
- // on Mac OS X. They have to receive special treatment,
- // see machoInitSymbolsWithoutUnderscore()
- #define RTS_MACHO_NOUNDERLINE_SYMBOLS \
- SymI_NeedsProto(saveFP) \
- SymI_NeedsProto(restFP)
- #endif
- /* entirely bogus claims about types of these symbols */
- #define SymI_NeedsProto(vvv) extern void vvv(void);
- #if defined(__PIC__) && defined(mingw32_HOST_OS)
- #define SymE_HasProto(vvv) SymE_HasProto(vvv);
- #define SymE_NeedsProto(vvv) extern void _imp__ ## vvv (void);
- #else
- #define SymE_NeedsProto(vvv) SymI_NeedsProto(vvv);
- #define SymE_HasProto(vvv) SymI_HasProto(vvv)
- #endif
- #define SymI_HasProto(vvv) /**/
- #define SymI_HasProto_redirect(vvv,xxx) /**/
- RTS_SYMBOLS
- RTS_RET_SYMBOLS
- RTS_POSIX_ONLY_SYMBOLS
- RTS_MINGW_ONLY_SYMBOLS
- RTS_CYGWIN_ONLY_SYMBOLS
- RTS_DARWIN_ONLY_SYMBOLS
- RTS_LIBGCC_SYMBOLS
- RTS_LIBFFI_SYMBOLS
- #undef SymI_NeedsProto
- #undef SymI_HasProto
- #undef SymI_HasProto_redirect
- #undef SymE_HasProto
- #undef SymE_NeedsProto
- #ifdef LEADING_UNDERSCORE
- #define MAYBE_LEADING_UNDERSCORE_STR(s) ("_" s)
- #else
- #define MAYBE_LEADING_UNDERSCORE_STR(s) (s)
- #endif
- #define SymI_HasProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
- (void*)(&(vvv)) },
- #define SymE_HasProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
- (void*)DLL_IMPORT_DATA_REF(vvv) },
- #define SymI_NeedsProto(vvv) SymI_HasProto(vvv)
- #define SymE_NeedsProto(vvv) SymE_HasProto(vvv)
- // SymI_HasProto_redirect allows us to redirect references to one symbol to
- // another symbol. See newCAF/newDynCAF for an example.
- #define SymI_HasProto_redirect(vvv,xxx) \
- { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
- (void*)(&(xxx)) },
- static RtsSymbolVal rtsSyms[] = {
- RTS_SYMBOLS
- RTS_RET_SYMBOLS
- RTS_POSIX_ONLY_SYMBOLS
- RTS_MINGW_ONLY_SYMBOLS
- RTS_CYGWIN_ONLY_SYMBOLS
- RTS_DARWIN_ONLY_SYMBOLS
- RTS_LIBGCC_SYMBOLS
- RTS_LIBFFI_SYMBOLS
- #if defined(darwin_HOST_OS) && defined(i386_HOST_ARCH)
- // dyld stub code contains references to this,
- // but it should never be called because we treat
- // lazy pointers as nonlazy.
- { "dyld_stub_binding_helper", (void*)0xDEADBEEF },
- #endif
- { 0, 0 } /* sentinel */
- };
- /* -----------------------------------------------------------------------------
- * Insert symbols into hash tables, checking for duplicates.
- */
- static void ghciInsertStrHashTable ( char* obj_name,
- HashTable *table,
- char* key,
- void *data
- )
- {
- if (lookupHashTable(table, (StgWord)key) == NULL)
- {
- insertStrHashTable(table, (StgWord)key, data);
- return;
- }
- debugBelch(
- "\n\n"
- "GHCi runtime linker: fatal error: I found a duplicate definition for symbol\n"
- " %s\n"
- "whilst processing object file\n"
- " %s\n"
- "This could be caused by:\n"
- " * Loading two different object files which export the same symbol\n"
- " * Specifying the same object file twice on the GHCi command line\n"
- " * An incorrect `package.conf' entry, causing some object to be\n"
- " loaded twice.\n"
- "GHCi cannot safely continue in this situation. Exiting now. Sorry.\n"
- "\n",
- (char*)key,
- obj_name
- );
- stg_exit(1);
- }
- /* -----------------------------------------------------------------------------
- * initialize the object linker
- */
- static int linker_init_done = 0 ;
- #if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
- static void *dl_prog_handle;
- static regex_t re_invalid;
- static regex_t re_realso;
- #ifdef THREADED_RTS
- static Mutex dl_mutex; // mutex to protect dlopen/dlerror critical section
- #endif
- #endif
- void
- initLinker( void )
- {
- RtsSymbolVal *sym;
- #if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
- int compileResult;
- #endif
- IF_DEBUG(linker, debugBelch("initLinker: start\n"));
- /* Make initLinker idempotent, so we can call it
- before evey relevant operation; that means we
- don't need to initialise the linker separately */
- if (linker_init_done == 1) {
- IF_DEBUG(linker, debugBelch("initLinker: idempotent return\n"));
- return;
- } else {
- linker_init_done = 1;
- }
- #if defined(THREADED_RTS) && (defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO))
- initMutex(&dl_mutex);
- #endif
- stablehash = allocStrHashTable();
- symhash = allocStrHashTable();
- /* populate the symbol table with stuff from the RTS */
- for (sym = rtsSyms; sym->lbl != NULL; sym++) {
- ghciInsertStrHashTable("(GHCi built-in symbols)",
- symhash, sym->lbl, sym->addr);
- IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
- }
- # if defined(OBJFORMAT_MACHO) && defined(powerpc_HOST_ARCH)
- machoInitSymbolsWithoutUnderscore();
- # endif
- # if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
- # if defined(RTLD_DEFAULT)
- dl_prog_handle = RTLD_DEFAULT;
- # else
- dl_prog_handle = dlopen(NULL, RTLD_LAZY);
- # endif /* RTLD_DEFAULT */
- compileResult = regcomp(&re_invalid,
- "(([^ \t()])+\\.so([^ \t:()])*):([ \t])*invalid ELF header",
- REG_EXTENDED);
- ASSERT( compileResult == 0 );
- compileResult = regcomp(&re_realso,
- "GROUP *\\( *(([^ )])+)",
- REG_EXTENDED);
- ASSERT( compileResult == 0 );
- # endif
- #if !defined(ALWAYS_PIC) && defined(x86_64_HOST_ARCH)
- if (RtsFlags.MiscFlags.linkerMemBase != 0) {
- // User-override for mmap_32bit_base
- mmap_32bit_base = (void*)RtsFlags.MiscFlags.linkerMemBase;
- }
- #endif
- #if defined(mingw32_HOST_OS)
- /*
- * These two libraries cause problems when added to the static link,
- * but are necessary for resolving symbols in GHCi, hence we load
- * them manually here.
- */
- addDLL("msvcrt");
- addDLL("kernel32");
- #endif
- IF_DEBUG(linker, debugBelch("initLinker: done\n"));
- return;
- }
- void
- exitLinker( void ) {
- #if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
- if (linker_init_done == 1) {
- regfree(&re_invalid);
- regfree(&re_realso);
- #ifdef THREADED_RTS
- closeMutex(&dl_mutex);
- #endif
- }
- #endif
- }
- /* -----------------------------------------------------------------------------
- * Loading DLL or .so dynamic libraries
- * -----------------------------------------------------------------------------
- *
- * Add a DLL from which symbols may be found. In the ELF case, just
- * do RTLD_GLOBAL-style add, so no further messing around needs to
- * happen in order that symbols in the loaded .so are findable --
- * lookupSymbol() will subsequently see them by dlsym on the program's
- * dl-handle. Returns NULL if success, otherwise ptr to an err msg.
- *
- * In the PEi386 case, open the DLLs and put handles to them in a
- * linked list. When looking for a symbol, try all handles in the
- * list. This means that we need to load even DLLs that are guaranteed
- * to be in the ghc.exe image already, just so we can get a handle
- * to give to loadSymbol, so that we can find the symbols. For such
- * libraries, the LoadLibrary call should be a no-op except for returning
- * the handle.
- *
- */
- #if defined(OBJFORMAT_PEi386)
- /* A record for storing handles into DLLs. */
- typedef
- struct _OpenedDLL {
- char* name;
- struct _OpenedDLL* next;
- HINSTANCE instance;
- }
- OpenedDLL;
- /* A list thereof. */
- static OpenedDLL* opened_dlls = NULL;
- #endif
- # if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
- static const char *
- internal_dlopen(const char *dll_name)
- {
- void *hdl;
- const char *errmsg;
- char *errmsg_copy;
- // omitted: RTLD_NOW
- // see http://www.haskell.org/pipermail/cvs-ghc/2007-September/038570.html
- IF_DEBUG(linker,
- debugBelch("internal_dlopen: dll_name = '%s'\n", dll_name));
- //-------------- Begin critical section ------------------
- // This critical section is necessary because dlerror() is not
- // required to be reentrant (see POSIX -- IEEE Std 1003.1-2008)
- // Also, the error message returned must be copied to preserve it
- // (see POSIX also)
- ACQUIRE_LOCK(&dl_mutex);
- hdl = dlopen(dll_name, RTLD_LAZY | RTLD_GLOBAL);
- errmsg = NULL;
- if (hdl == NULL) {
- /* dlopen failed; return a ptr to the error msg. */
- errmsg = dlerror();
- if (errmsg == NULL) errmsg = "addDLL: unknown error";
- errmsg_copy = stgMallocBytes(strlen(errmsg)+1, "addDLL");
- strcpy(errmsg_copy, errmsg);
- errmsg = errmsg_copy;
- }
- RELEASE_LOCK(&dl_mutex);
- //--------------- End critical section -------------------
- return errmsg;
- }
- # endif
- const char *
- addDLL( char *dll_name )
- {
- # if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
- /* ------------------- ELF DLL loader ------------------- */
- #define NMATCH 5
- regmatch_t match[NMATCH];
- const char *errmsg;
- FILE* fp;
- size_t match_length;
- #define MAXLINE 1000
- char line[MAXLINE];
- int result;
- initLinker();
- IF_DEBUG(linker, debugBelch("addDLL: dll_name = '%s'\n", dll_name));
- errmsg = internal_dlopen(dll_name);
- if (errmsg == NULL) {
- return NULL;
- }
- // GHC Trac ticket #2615
- // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so)
- // contain linker scripts rather than ELF-format object code. This
- // code handles the situation by recognizing the real object code
- // file name given in the linker script.
- //
- // If an "invalid ELF header" error occurs, it is assumed that the
- // .so file contains a linker script instead of ELF object code.
- // In this case, the code looks for the GROUP ( ... ) linker
- // directive. If one is found, the first file name inside the
- // parentheses is treated as the name of a dynamic library and the
- // code attempts to dlopen that file. If this is also unsuccessful,
- // an error message is returned.
- // see if the error message is due to an invalid ELF header
- IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", errmsg));
- result = regexec(&re_invalid, errmsg, (size_t) NMATCH, match, 0);
- IF_DEBUG(linker, debugBelch("result = %i\n", result));
- if (result == 0) {
- // success -- try to read the named file as a linker script
- match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so),
- MAXLINE-1);
- strncpy(line, (errmsg+(match[1].rm_so)),match_length);
- line[match_length] = '\0'; // make sure string is null-terminated
- IF_DEBUG(linker, debugBelch ("file name = '%s'\n", line));
- if ((fp = fopen(line, "r")) == NULL) {
- return errmsg; // return original error if open fails
- }
- // try to find a GROUP ( ... ) command
- while (fgets(line, MAXLINE, fp) != NULL) {
- IF_DEBUG(linker, debugBelch("input line = %s", line));
- if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) {
- // success -- try to dlopen the first named file
- IF_DEBUG(linker, debugBelch("match%s\n",""));
- line[match[1].rm_eo] = '\0';
- errmsg = internal_dlopen(line+match[1].rm_so);
- break;
- }
- // if control reaches here, no GROUP ( ... ) directive was found
- // and the original error message is returned to the caller
- }
- fclose(fp);
- }
- return errmsg;
- # elif defined(OBJFORMAT_PEi386)
- /* ------------------- Win32 DLL loader ------------------- */
- char* buf;
- OpenedDLL* o_dll;
- HINSTANCE instance;
- initLinker();
- /* debugBelch("\naddDLL; dll_name = `%s'\n", dll_name); */
- /* See if we've already got it, and ignore if so. */
- for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
- if (0 == strcmp(o_dll->name, dll_name))
- return NULL;
- }
- /* The file name has no suffix (yet) so that we can try
- both foo.dll and foo.drv
- The documentation for LoadLibrary says:
- If no file name extension is specified in the lpFileName
- parameter, the default library extension .dll is
- appended. However, the file name string can include a trailing
- point character (.) to indicate that the module name has no
- extension. */
- buf = stgMallocBytes(strlen(dll_name) + 10, "addDLL");
- sprintf(buf, "%s.DLL", dll_name);
- instance = LoadLibrary(buf);
- if (instance == NULL) {
- if (GetLastError() != ERROR_MOD_NOT_FOUND) goto error;
- // KAA: allow loading of drivers (like winspool.drv)
- sprintf(buf, "%s.DRV", dll_name);
- instance = LoadLibrary(buf);
- if (instance == NULL) {
- if (GetLastError() != ERROR_MOD_NOT_FOUND) goto error;
- // #1883: allow loading of unix-style libfoo.dll DLLs
- sprintf(buf, "lib%s.DLL", dll_name);
- instance = LoadLibrary(buf);
- if (instance == NULL) {
- goto error;
- }
- }
- }
- stgFree(buf);
- /* Add this DLL to the list of DLLs in which to search for symbols. */
- o_dll = stgMallocBytes( sizeof(OpenedDLL), "addDLL" );
- o_dll->name = stgMallocBytes(1+strlen(dll_name), "addDLL");
- strcpy(o_dll->name, dll_name);
- o_dll->instance = instance;
- o_dll->next = opened_dlls;
- opened_dlls = o_dll;
- return NULL;
- error:
- stgFree(buf);
- sysErrorBelch(dll_name);
- /* LoadLibrary failed; return a ptr to the error msg. */
- return "addDLL: could not load DLL";
- # else
- barf("addDLL: not implemented on this platform");
- # endif
- }
- /* -----------------------------------------------------------------------------
- * insert a stable symbol in the hash table
- */
- void
- insertStableSymbol(char* obj_name, char* key, StgPtr p)
- {
- ghciInsertStrHashTable(obj_name, stablehash, key, getStablePtr(p));
- }
- /* -----------------------------------------------------------------------------
- * insert a symbol in the hash table
- */
- void
- insertSymbol(char* obj_name, char* key, void* data)
- {
- ghciInsertStrHashTable(obj_name, symhash, key, data);
- }
- /* -----------------------------------------------------------------------------
- * lookup a symbol in the hash table
- */
- void *
- lookupSymbol( char *lbl )
- {
- void *val;
- IF_DEBUG(linker, debugBelch("lookupSymbol: looking up %s\n", lbl));
- initLinker() ;
- ASSERT(symhash != NULL);
- val = lookupStrHashTable(symhash, lbl);
- if (val == NULL) {
- IF_DEBUG(linker, debugBelch("lookupSymbol: symbol not found\n"));
- # if defined(OBJFORMAT_ELF)
- return dlsym(dl_prog_handle, lbl);
- # elif defined(OBJFORMAT_MACHO)
- # if HAVE_DLFCN_H
- /* On OS X 10.3 and later, we use dlsym instead of the old legacy
- interface.
- HACK: On OS X, global symbols are prefixed with an underscore.
- However, dlsym wants us to omit the leading underscore from the
- symbol name. For now, we simply strip it off here (and ONLY
- here).
- */
- IF_DEBUG(linker, debugBelch("lookupSymbol: looking up %s with dlsym\n", lbl));
- ASSERT(lbl[0] == '_');
- return dlsym(dl_prog_handle, lbl+1);
- # else
- if(NSIsSymbolNameDefined(lbl)) {
- NSSymbol symbol = NSLookupAndBindSymbol(lbl);
- return NSAddressOfSymbol(symbol);
- } else {
- return NULL;
- }
- # endif /* HAVE_DLFCN_H */
- # elif defined(OBJFORMAT_PEi386)
- void* sym;
- sym = lookupSymbolInDLLs((unsigned char*)lbl);
- if (sym != NULL) { return sym; };
- // Also try looking up the symbol without the @N suffix. Some
- // DLLs have the suffixes on their symbols, some don't.
- zapTrailingAtSign ( (unsigned char*)lbl );
- sym = lookupSymbolInDLLs((unsigned char*)lbl);
- if (sym != NULL) { return sym; };
- return NULL;
- # else
- ASSERT(2+2 == 5);
- return NULL;
- # endif
- } else {
- IF_DEBUG(linker, debugBelch("lookupSymbol: value of %s is %p\n", lbl, val));
- return val;
- }
- }
- /* -----------------------------------------------------------------------------
- * Debugging aid: look in GHCi's object symbol tables for symbols
- * within DELTA bytes of the specified address, and show their names.
- */
- #ifdef DEBUG
- void ghci_enquire ( char* addr );
- void