Linker.c 168 KB
Newer Older
1 2
/* -----------------------------------------------------------------------------
 *
3
 * (c) The GHC Team, 2000-2004
4 5 6 7 8
 *
 * RTS Object Linker
 *
 * ---------------------------------------------------------------------------*/

sof's avatar
sof committed
9
#if 0
10
#include "PosixSource.h"
sof's avatar
sof committed
11
#endif
12

13
/* Linux needs _GNU_SOURCE to get RTLD_DEFAULT from <dlfcn.h> and
14 15
   MREMAP_MAYMOVE from <sys/mman.h>.
 */
16 17 18 19
#ifdef __linux__
#define _GNU_SOURCE
#endif

20 21
#include "Rts.h"
#include "HsFFI.h"
Simon Marlow's avatar
Simon Marlow committed
22 23

#include "sm/Storage.h"
Simon Marlow's avatar
Simon Marlow committed
24
#include "Stats.h"
25
#include "Hash.h"
26
#include "LinkerInternals.h"
27
#include "RtsUtils.h"
28
#include "Trace.h"
Simon Marlow's avatar
Simon Marlow committed
29 30 31 32 33 34
#include "StgPrimFloat.h" // for __int_encodeFloat etc.
#include "Stable.h"

#if !defined(mingw32_HOST_OS)
#include "posix/Signals.h"
#endif
35

Simon Marlow's avatar
Simon Marlow committed
36 37 38
// get protos for is*()
#include <ctype.h>

39
#ifdef HAVE_SYS_TYPES_H
40
#include <sys/types.h>
41 42
#endif

43 44
#include <stdlib.h>
#include <string.h>
45 46
#include <stdio.h>
#include <assert.h>
47

48
#ifdef HAVE_SYS_STAT_H
49
#include <sys/stat.h>
50
#endif
51

52
#if defined(HAVE_DLFCN_H)
53
#include <dlfcn.h>
54
#endif
55

56
#if defined(cygwin32_HOST_OS)
sof's avatar
sof committed
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
#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

72
#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)
73 74 75
#define USE_MMAP
#include <fcntl.h>
#include <sys/mman.h>
dons's avatar
dons committed
76 77 78 79 80

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

81 82
#endif

Simon Marlow's avatar
Simon Marlow committed
83
#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)
84
#  define OBJFORMAT_ELF
85 86
#  include <regex.h>	// regex is already used by dlopen() so this is OK
			// to use here without requiring an additional lib
87
#elif defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
88
#  define OBJFORMAT_PEi386
89
#  include <windows.h>
sof's avatar
sof committed
90
#  include <math.h>
91
#elif defined(darwin_HOST_OS)
92
#  define OBJFORMAT_MACHO
93
#  include <regex.h>
94 95 96
#  include <mach-o/loader.h>
#  include <mach-o/nlist.h>
#  include <mach-o/reloc.h>
97
#if !defined(HAVE_DLFCN_H)
98
#  include <mach-o/dyld.h>
99
#endif
100 101 102
#if defined(powerpc_HOST_ARCH)
#  include <mach-o/ppc/reloc.h>
#endif
103 104 105
#if defined(x86_64_HOST_ARCH)
#  include <mach-o/x86_64/reloc.h>
#endif
106 107
#endif

108 109 110 111
#if defined(x86_64_HOST_ARCH) && defined(darwin_HOST_OS)
#define ALWAYS_PIC
#endif

112
/* Hash table mapping symbol names to Symbol */
113
static /*Str*/HashTable *symhash;
114

115 116 117
/* Hash table mapping symbol names to StgStablePtr */
static /*Str*/HashTable *stablehash;

118 119 120
/* List of currently loaded objects */
ObjectCode *objects = NULL;	/* initially empty */

121 122 123 124 125 126 127 128 129
static HsInt loadOc( ObjectCode* oc );
static ObjectCode* mkOc( char *path, char *image, int imageSize
#ifndef USE_MMAP
#ifdef darwin_HOST_OS
                       , int misalignment
#endif
#endif
                       );

130
#if defined(OBJFORMAT_ELF)
131 132 133
static int ocVerifyImage_ELF    ( ObjectCode* oc );
static int ocGetNames_ELF       ( ObjectCode* oc );
static int ocResolve_ELF        ( ObjectCode* oc );
134
#if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
135
static int ocAllocateSymbolExtras_ELF ( ObjectCode* oc );
136
#endif
137
#elif defined(OBJFORMAT_PEi386)
138 139 140
static int ocVerifyImage_PEi386 ( ObjectCode* oc );
static int ocGetNames_PEi386    ( ObjectCode* oc );
static int ocResolve_PEi386     ( ObjectCode* oc );
141 142
static void *lookupSymbolInDLLs ( unsigned char *lbl );
static void zapTrailingAtSign   ( unsigned char *sym );
143 144 145 146
#elif defined(OBJFORMAT_MACHO)
static int ocVerifyImage_MachO    ( ObjectCode* oc );
static int ocGetNames_MachO       ( ObjectCode* oc );
static int ocResolve_MachO        ( ObjectCode* oc );
147

Ian Lynagh's avatar
Ian Lynagh committed
148
#ifndef USE_MMAP
149
static int machoGetMisalignment( FILE * );
Ian Lynagh's avatar
Ian Lynagh committed
150
#endif
151 152 153
#if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
static int ocAllocateSymbolExtras_MachO ( ObjectCode* oc );
#endif
154
#ifdef powerpc_HOST_ARCH
155
static void machoInitSymbolsWithoutUnderscore( void );
156
#endif
157
#endif
158

159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
/* 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
181 182 183 184 185 186 187 188 189 190 191 192
 *
 * 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);
193 194
 */
#define X86_64_ELF_NONPIC_HACK 1
195

196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
/* 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)
 */
222
#if !defined(ALWAYS_PIC) && defined(x86_64_HOST_ARCH)
223 224 225 226 227 228 229 230 231

#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

Ian Lynagh's avatar
Ian Lynagh committed
232
static void *mmap_32bit_base = (void *)MMAP_32BIT_BASE_DEFAULT;
233 234 235 236 237 238 239
#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

240 241 242 243
/* -----------------------------------------------------------------------------
 * Built-in symbols from the RTS
 */

244 245 246 247 248
typedef struct _RtsSymbolVal {
    char   *lbl;
    void   *addr;
} RtsSymbolVal;

249 250 251 252
#define Maybe_Stable_Names      SymI_HasProto(stg_mkWeakzh)			\
      				SymI_HasProto(stg_mkWeakForeignEnvzh)		\
      				SymI_HasProto(stg_makeStableNamezh)		\
      				SymI_HasProto(stg_finalizzeWeakzh)
253

254
#if !defined (mingw32_HOST_OS)
255
#define RTS_POSIX_ONLY_SYMBOLS                  \
Simon Marlow's avatar
Simon Marlow committed
256 257
      SymI_HasProto(__hscore_get_saved_termios)	\
      SymI_HasProto(__hscore_set_saved_termios)	\
258
      SymI_HasProto(shutdownHaskellAndSignal)	\
Simon Marlow's avatar
Simon Marlow committed
259 260
      SymI_HasProto(lockFile)                   \
      SymI_HasProto(unlockFile)                 \
261 262 263
      SymI_HasProto(signal_handlers)		\
      SymI_HasProto(stg_sig_install)		\
      SymI_NeedsProto(nocldstop)
sof's avatar
sof committed
264
#endif
265

266
#if defined (cygwin32_HOST_OS)
sof's avatar
sof committed
267 268 269
#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
270
 * exports; sigh.
sof's avatar
sof committed
271
 */
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
#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)
349

350
#elif !defined(mingw32_HOST_OS)
sof's avatar
sof committed
351 352
#define RTS_MINGW_ONLY_SYMBOLS /**/
#define RTS_CYGWIN_ONLY_SYMBOLS /**/
353
#else /* defined(mingw32_HOST_OS) */
sof's avatar
sof committed
354 355
#define RTS_POSIX_ONLY_SYMBOLS  /**/
#define RTS_CYGWIN_ONLY_SYMBOLS /**/
356

357
#if HAVE_GETTIMEOFDAY
358
#define RTS_MINGW_GETTIMEOFDAY_SYM SymI_NeedsProto(gettimeofday)
359 360 361 362
#else
#define RTS_MINGW_GETTIMEOFDAY_SYM /**/
#endif

363 364 365 366 367 368
#if HAVE___MINGW_VFPRINTF
#define RTS___MINGW_VFPRINTF_SYM SymI_HasProto(__mingw_vfprintf)
#else
#define RTS___MINGW_VFPRINTF_SYM /**/
#endif

369 370
/* These are statically linked from the mingw libraries into the ghc
   executable, so we have to employ this hack. */
371
#define RTS_MINGW_ONLY_SYMBOLS                           \
372 373 374
      SymI_HasProto(stg_asyncReadzh)			 \
      SymI_HasProto(stg_asyncWritezh)			 \
      SymI_HasProto(stg_asyncDoProczh)			 \
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
      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)                           \
Simon Marlow's avatar
Simon Marlow committed
397 398 399 400 401 402 403 404 405 406 407
      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)                           \
408
      RTS___MINGW_VFPRINTF_SYM                           \
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
      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)                               \
439 440 441 442
      SymI_HasProto(erf)                                \
      SymI_HasProto(erfc)                                \
      SymI_HasProto(erff)                                \
      SymI_HasProto(erfcf)                               \
443 444 445 446 447 448 449 450 451 452 453 454 455 456
      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)                         \
457 458 459
      SymI_NeedsProto(_imp____mb_cur_max)	         \
      SymI_NeedsProto(_imp___pctype)	         	 \
      SymI_NeedsProto(__chkstk)				 \
460 461
      RTS_MINGW_GETTIMEOFDAY_SYM		         \
      SymI_NeedsProto(closedir)
462
#endif
463

464

465
#if defined(darwin_HOST_OS) && HAVE_PRINTF_LDBLSTUB
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510
#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)
511 512 513 514
#else
#define RTS_DARWIN_ONLY_SYMBOLS
#endif

sof's avatar
sof committed
515
#ifndef SMP
516
# define MAIN_CAP_SYM SymI_HasProto(MainCapability)
sof's avatar
sof committed
517 518 519
#else
# define MAIN_CAP_SYM
#endif
520

sof's avatar
sof committed
521 522
#if !defined(mingw32_HOST_OS)
#define RTS_USER_SIGNALS_SYMBOLS \
523 524
   SymI_HasProto(setIOManagerControlFd) \
   SymI_HasProto(setIOManagerWakeupFd) \
525
   SymI_HasProto(ioManagerWakeup) \
526 527
   SymI_HasProto(blockUserSignals) \
   SymI_HasProto(unblockUserSignals)
sof's avatar
sof committed
528
#else
529
#define RTS_USER_SIGNALS_SYMBOLS     \
530
   SymI_HasProto(ioManagerWakeup) \
531 532 533 534
   SymI_HasProto(sendIOManagerEvent) \
   SymI_HasProto(readIOManagerEvent) \
   SymI_HasProto(getIOManagerEvent)  \
   SymI_HasProto(console_handler)
sof's avatar
sof committed
535 536
#endif

537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
#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)
552

553 554 555
#ifdef TABLES_NEXT_TO_CODE
#define RTS_RET_SYMBOLS /* nothing */
#else
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572
#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)
573 574
#endif

575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687
/* 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)


688 689 690 691 692 693 694 695 696 697 698 699 700 701 702
// 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


703 704
#define RTS_SYMBOLS				        \
      Maybe_Stable_Names			        \
705
      RTS_TICKY_SYMBOLS                                 \
706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745
      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)			\
746
      SymI_HasProto(stg_atomicallyzh)			\
747 748 749
      SymI_HasProto(barf)				\
      SymI_HasProto(debugBelch)				\
      SymI_HasProto(errorBelch)				\
Simon Marlow's avatar
Simon Marlow committed
750
      SymI_HasProto(sysErrorBelch)                      \
751 752 753
      SymI_HasProto(stg_getMaskingStatezh)		\
      SymI_HasProto(stg_maskAsyncExceptionszh)	        \
      SymI_HasProto(stg_maskUninterruptiblezh)	        \
754 755 756 757
      SymI_HasProto(stg_catchzh)			\
      SymI_HasProto(stg_catchRetryzh)			\
      SymI_HasProto(stg_catchSTMzh)			\
      SymI_HasProto(stg_checkzh)                        \
758 759 760
      SymI_HasProto(closure_flags)                      \
      SymI_HasProto(cmp_thread)				\
      SymI_HasProto(createAdjustor)			\
761 762
      SymI_HasProto(stg_decodeDoublezu2Intzh)		\
      SymI_HasProto(stg_decodeFloatzuIntzh)		\
763
      SymI_HasProto(defaultsHook)			\
764 765 766
      SymI_HasProto(stg_delayzh)			\
      SymI_HasProto(stg_deRefWeakzh)			\
      SymI_HasProto(stg_deRefStablePtrzh)		\
767
      SymI_HasProto(dirty_MUT_VAR)			\
768 769
      SymI_HasProto(stg_forkzh)			        \
      SymI_HasProto(stg_forkOnzh)			\
770 771 772 773
      SymI_HasProto(forkProcess)			\
      SymI_HasProto(forkOS_createThread)		\
      SymI_HasProto(freeHaskellFunctionPtr)		\
      SymI_HasProto(getOrSetTypeableStore)		\
774 775 776 777 778 779
      SymI_HasProto(getOrSetGHCConcSignalSignalHandlerStore)		\
      SymI_HasProto(getOrSetGHCConcWindowsPendingDelaysStore)		\
      SymI_HasProto(getOrSetGHCConcWindowsIOManagerThreadStore)	\
      SymI_HasProto(getOrSetGHCConcWindowsProddingStore)		\
      SymI_HasProto(getOrSetSystemEventThreadEventManagerStore)		\
      SymI_HasProto(getOrSetSystemEventThreadIOManagerThreadStore)		\
780 781 782 783 784 785 786 787 788 789 790 791 792
      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)		        \
793
      SymI_HasProto(hs_hpc_module)		        \
794
      SymI_HasProto(initLinker)				\
795 796 797
      SymI_HasProto(stg_unpackClosurezh)                \
      SymI_HasProto(stg_getApStackValzh)                \
      SymI_HasProto(stg_getSparkzh)                     \
Simon Marlow's avatar
Simon Marlow committed
798
      SymI_HasProto(stg_numSparkszh)                    \
799 800 801
      SymI_HasProto(stg_isCurrentThreadBoundzh)	        \
      SymI_HasProto(stg_isEmptyMVarzh)			\
      SymI_HasProto(stg_killThreadzh)			\
802
      SymI_HasProto(loadArchive)          			\
803 804 805 806
      SymI_HasProto(loadObj)          			\
      SymI_HasProto(insertStableSymbol) 		\
      SymI_HasProto(insertSymbol)     			\
      SymI_HasProto(lookupSymbol)     			\
807 808 809 810 811 812 813
      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)  		\
814
      SymI_HasProto_redirect(newCAF, newDynCAF)		\
815 816 817 818 819 820 821
      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)	\
822 823 824 825 826
      SymI_HasProto(newSpark)				\
      SymI_HasProto(performGC)				\
      SymI_HasProto(performMajorGC)			\
      SymI_HasProto(prog_argc)				\
      SymI_HasProto(prog_argv)				\
827 828 829 830 831
      SymI_HasProto(stg_putMVarzh)			\
      SymI_HasProto(stg_raisezh)			\
      SymI_HasProto(stg_raiseIOzh)			\
      SymI_HasProto(stg_readTVarzh)			\
      SymI_HasProto(stg_readTVarIOzh)			\
832 833
      SymI_HasProto(resumeThread)			\
      SymI_HasProto(resolveObjs)                        \
834
      SymI_HasProto(stg_retryzh)                        \
835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879
      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)				\
880
      SymI_HasProto(rts_unsafeGetMyCapability)          \
881
      SymI_HasProto(rtsSupportsBoundThreads)		\
882
      SymI_HasProto(rts_isProfiled)			\
883 884 885 886 887 888 889
      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)		\
890
      SymI_HasProto(stg_BLACKHOLE_info)			\
891
      SymI_HasProto(__stg_EAGER_BLACKHOLE_info)		\
892 893
      SymI_HasProto(stg_BLOCKING_QUEUE_CLEAN_info)      \
      SymI_HasProto(stg_BLOCKING_QUEUE_DIRTY_info)	\
894 895 896 897
      SymI_HasProto(startTimer)                         \
      SymI_HasProto(stg_MVAR_CLEAN_info)		\
      SymI_HasProto(stg_MVAR_DIRTY_info)		\
      SymI_HasProto(stg_IND_STATIC_info)		\
898
      SymI_HasProto(stg_ARR_WORDS_info)                 \
899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956
      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)			\
957
      SymI_HasProto(stg_bh_upd_frame_info)		\
958
      SymI_HasProto(suspendThread)			\
959 960 961 962
      SymI_HasProto(stg_takeMVarzh)			\
      SymI_HasProto(stg_threadStatuszh)		        \
      SymI_HasProto(stg_tryPutMVarzh)			\
      SymI_HasProto(stg_tryTakeMVarzh)			\
963
      SymI_HasProto(stg_unmaskAsyncExceptionszh)	\
964
      SymI_HasProto(unloadObj)                          \
965 966 967 968 969
      SymI_HasProto(stg_unsafeThawArrayzh)		\
      SymI_HasProto(stg_waitReadzh)			\
      SymI_HasProto(stg_waitWritezh)			\
      SymI_HasProto(stg_writeTVarzh)			\
      SymI_HasProto(stg_yieldzh)                        \
970
      SymI_NeedsProto(stg_interp_constr_entry)          \
971
      SymI_HasProto(stg_arg_bitmaps)                    \
972
      SymI_HasProto(alloc_blocks_lim)                   \
Simon Marlow's avatar
Simon Marlow committed
973
      SymI_HasProto(g0)                                 \
974
      SymI_HasProto(allocate)                           \
975 976 977 978 979 980 981 982 983 984
      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)			\
985
      SymI_HasProto(stg_traceCcszh)                     \
986
      SymI_HasProto(stg_traceEventzh)                   \
987 988
      RTS_USER_SIGNALS_SYMBOLS				\
      RTS_INTCHAR_SYMBOLS
989

990

991 992
// 64-bit support functions in libgcc.a
#if defined(__GNUC__) && SIZEOF_VOID_P <= 4
993 994 995 996 997 998 999 1000
#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)		       \
1001
      SymI_NeedsProto(__lshrdi3)
1002 1003 1004 1005
#else
#define RTS_LIBGCC_SYMBOLS
#endif

1006
#if defined(darwin_HOST_OS) && defined(powerpc_HOST_ARCH)
1007 1008 1009 1010
      // 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		\
1011 1012
      SymI_NeedsProto(saveFP)				\
      SymI_NeedsProto(restFP)
1013
#endif
1014 1015

/* entirely bogus claims about types of these symbols */
1016
#define SymI_NeedsProto(vvv)  extern void vvv(void);
1017
#if defined(__PIC__) && defined(mingw32_HOST_OS)
1018 1019
#define SymE_HasProto(vvv)    SymE_HasProto(vvv);
#define SymE_NeedsProto(vvv)    extern void _imp__ ## vvv (void);
1020
#else
1021 1022
#define SymE_NeedsProto(vvv)  SymI_NeedsProto(vvv);
#define SymE_HasProto(vvv)    SymI_HasProto(vvv)
1023
#endif
1024 1025
#define SymI_HasProto(vvv) /**/
#define SymI_HasProto_redirect(vvv,xxx) /**/
1026
RTS_SYMBOLS
1027
RTS_RET_SYMBOLS
1028
RTS_POSIX_ONLY_SYMBOLS
1029
RTS_MINGW_ONLY_SYMBOLS
sof's avatar
sof committed
1030
RTS_CYGWIN_ONLY_SYMBOLS
1031
RTS_DARWIN_ONLY_SYMBOLS
1032
RTS_LIBGCC_SYMBOLS
1033
RTS_LIBFFI_SYMBOLS
1034 1035 1036 1037 1038
#undef SymI_NeedsProto
#undef SymI_HasProto
#undef SymI_HasProto_redirect
#undef SymE_HasProto
#undef SymE_NeedsProto
1039 1040 1041 1042 1043 1044 1045

#ifdef LEADING_UNDERSCORE
#define MAYBE_LEADING_UNDERSCORE_STR(s) ("_" s)
#else
#define MAYBE_LEADING_UNDERSCORE_STR(s) (s)
#endif

1046
#define SymI_HasProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
1047
                    (void*)(&(vvv)) },
1048
#define SymE_HasProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
1049
	    (void*)DLL_IMPORT_DATA_REF(vvv) },
1050

1051 1052 1053 1054
#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
1055
// another symbol.  See newCAF/newDynCAF for an example.
1056
#define SymI_HasProto_redirect(vvv,xxx) \
1057 1058 1059
    { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
      (void*)(&(xxx)) },

1060
static RtsSymbolVal rtsSyms[] = {
1061
      RTS_SYMBOLS
1062
      RTS_RET_SYMBOLS
1063
      RTS_POSIX_ONLY_SYMBOLS
1064
      RTS_MINGW_ONLY_SYMBOLS
sof's avatar
sof committed
1065
      RTS_CYGWIN_ONLY_SYMBOLS
1066
      RTS_DARWIN_ONLY_SYMBOLS
1067
      RTS_LIBGCC_SYMBOLS
1068
      RTS_LIBFFI_SYMBOLS
1069 1070 1071 1072
#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.
1073
      { "dyld_stub_binding_helper", (void*)0xDEADBEEF },
1074
#endif
1075 1076 1077
      { 0, 0 } /* sentinel */
};

1078 1079


1080 1081 1082
/* -----------------------------------------------------------------------------
 * Insert symbols into hash tables, checking for duplicates.
 */
1083

1084 1085
static void ghciInsertStrHashTable ( char* obj_name,
                                     HashTable *table,
1086
                                     char* key,
1087 1088 1089
                                     void *data
				   )
{
Simon Marlow's avatar
Simon Marlow committed
1090 1091
   if (lookupHashTable(table, (StgWord)key) == NULL)
   {
1092 1093
      insertStrHashTable(table, (StgWord)key, data);
      return;
Simon Marlow's avatar
Simon Marlow committed
1094 1095
   }
   debugBelch(
1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109
      "\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
Simon Marlow's avatar
Simon Marlow committed
1110 1111
   );
   exit(1);
1112
}
1113 1114 1115
/* -----------------------------------------------------------------------------
 * initialize the object linker
 */
1116 1117 1118 1119


static int linker_init_done = 0 ;

1120
#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
1121
static void *dl_prog_handle;
1122 1123 1124 1125 1126
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
1127
#endif
1128 1129 1130 1131

void
initLinker( void )
{
1132
    RtsSymbolVal *sym;
Simon Marlow's avatar
Simon Marlow committed
1133
#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
1134
    int compileResult;
Simon Marlow's avatar
Simon Marlow committed
1135
#endif
1136

1137 1138 1139 1140 1141 1142 1143
    /* 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) { return; } else {
      linker_init_done = 1;
    }

Simon Marlow's avatar
Simon Marlow committed
1144
#if defined(THREADED_RTS) && (defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO))
1145 1146
    initMutex(&dl_mutex);
#endif
1147
    stablehash = allocStrHashTable();
1148 1149 1150 1151
    symhash = allocStrHashTable();

    /* populate the symbol table with stuff from the RTS */
    for (sym = rtsSyms; sym->lbl != NULL; sym++) {
1152 1153
	ghciInsertStrHashTable("(GHCi built-in symbols)",
                               symhash, sym->lbl, sym->addr);
1154
    }
1155
#   if defined(OBJFORMAT_MACHO) && defined(powerpc_HOST_ARCH)
1156 1157 1158
    machoInitSymbolsWithoutUnderscore();
#   endif

1159
#   if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
1160
#   if defined(RTLD_DEFAULT)
1161 1162
    dl_prog_handle = RTLD_DEFAULT;
#   else
1163
    dl_prog_handle = dlopen(NULL, RTLD_LAZY);
1164
#   endif /* RTLD_DEFAULT */
1165 1166 1167 1168 1169 1170 1171 1172 1173

    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 );
1174
#   endif
1175

1176
#if !defined(ALWAYS_PIC) && defined(x86_64_HOST_ARCH)
1177 1178 1179 1180 1181
    if (RtsFlags.MiscFlags.linkerMemBase != 0) {
        // User-override for mmap_32bit_base
        mmap_32bit_base = (void*)RtsFlags.MiscFlags.linkerMemBase;
    }
#endif
1182 1183 1184 1185 1186 1187 1188 1189 1190 1191

#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
1192 1193
}

1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206
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
}

1207
/* -----------------------------------------------------------------------------
1208 1209 1210
 *                  Loading DLL or .so dynamic libraries
 * -----------------------------------------------------------------------------
 *
1211 1212 1213 1214
 * 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
1215 1216
 * dl-handle.  Returns NULL if success, otherwise ptr to an err msg.
 *
1217
 * In the PEi386 case, open the DLLs and put handles to them in a
1218
 * linked list.  When looking for a symbol, try all handles in the
1219 1220 1221 1222 1223
 * 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.
1224
 *
1225
 */
1226 1227 1228 1229 1230 1231

#if defined(OBJFORMAT_PEi386)
/* A record for storing handles into DLLs. */

typedef
   struct _OpenedDLL {
1232
      char*              name;
1233 1234
      struct _OpenedDLL* next;
      HINSTANCE instance;
1235
   }
1236 1237 1238 1239 1240 1241
   OpenedDLL;

/* A list thereof. */
static OpenedDLL* opened_dlls = NULL;
#endif

1242
#  if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
1243

1244
static const char *
1245 1246 1247
internal_dlopen(const char *dll_name)
{
   void *hdl;
1248 1249
   const char *errmsg;
   char *errmsg_copy;
1250

1251 1252
   // omitted: RTLD_NOW
   // see http://www.haskell.org/pipermail/cvs-ghc/2007-September/038570.html
1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263
   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);
dons's avatar
dons committed
1264

1265
   errmsg = NULL;
1266 1267 1268 1269
   if (hdl == NULL) {
      /* dlopen failed; return a ptr to the error msg. */
      errmsg = dlerror();
      if (errmsg == NULL) errmsg = "addDLL: unknown error";
1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288
      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];
1289
   const char *errmsg;
1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301
   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) {
1302 1303
      return NULL;
   }
1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348

   // 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;
1349

1350
#  elif defined(OBJFORMAT_PEi386)
1351
   /* ------------------- Win32 DLL loader ------------------- */
1352

1353
   char*      buf;
1354
   OpenedDLL* o_dll;
1355
   HINSTANCE  instance;
1356

1357 1358
   initLinker();

1359
   /* debugBelch("\naddDLL; dll_name = `%s'\n", dll_name); */
1360 1361 1362