Linker.c 137 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
22
23
24
#include "Rts.h"
#include "RtsFlags.h"
#include "HsFFI.h"
#include "Hash.h"
#include "Linker.h"
25
#include "LinkerInternals.h"
26
#include "RtsUtils.h"
27
#include "Schedule.h"
28
#include "Sparks.h"
ei@vuokko.info's avatar
ei@vuokko.info committed
29
#include "RtsTypeable.h"
30

31
#ifdef HAVE_SYS_TYPES_H
32
#include <sys/types.h>
33
34
#endif

35
36
37
#include <stdlib.h>
#include <string.h>

38
#ifdef HAVE_SYS_STAT_H
39
#include <sys/stat.h>
40
#endif
41

42
#if defined(HAVE_DLFCN_H)
43
#include <dlfcn.h>
44
#endif
45

46
#if defined(cygwin32_HOST_OS)
sof's avatar
sof committed
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#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

62
#if defined(ia64_HOST_ARCH) || defined(openbsd_HOST_OS) || defined(linux_HOST_OS) || defined(freebsd_HOST_OS)
63
64
65
#define USE_MMAP
#include <fcntl.h>
#include <sys/mman.h>
dons's avatar
dons committed
66

67
#if defined(openbsd_HOST_OS) || defined(linux_HOST_OS) || defined(freebsd_HOST_OS)
dons's avatar
dons committed
68
69
70
71
72
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#endif

73
74
#endif

75
#if defined(linux_HOST_OS) || defined(solaris2_HOST_OS) || defined(freebsd_HOST_OS) || defined(netbsd_HOST_OS) || defined(openbsd_HOST_OS)
76
#  define OBJFORMAT_ELF
77
#elif defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
78
#  define OBJFORMAT_PEi386
79
#  include <windows.h>
sof's avatar
sof committed
80
#  include <math.h>
81
#elif defined(darwin_HOST_OS)
82
83
84
85
#  define OBJFORMAT_MACHO
#  include <mach-o/loader.h>
#  include <mach-o/nlist.h>
#  include <mach-o/reloc.h>
86
#  include <mach-o/dyld.h>
87
88
89
#if defined(powerpc_HOST_ARCH)
#  include <mach-o/ppc/reloc.h>
#endif
90
91
#endif

92
/* Hash table mapping symbol names to Symbol */
93
static /*Str*/HashTable *symhash;
94

95
96
97
/* Hash table mapping symbol names to StgStablePtr */
static /*Str*/HashTable *stablehash;

98
#if defined(DEBUGGER)
99
100
101
102
/* Hash table mapping info table ptrs to DataCon names */
static HashTable *dchash;
#endif 

103
104
105
/* List of currently loaded objects */
ObjectCode *objects = NULL;	/* initially empty */

106
#if defined(OBJFORMAT_ELF)
107
108
109
static int ocVerifyImage_ELF    ( ObjectCode* oc );
static int ocGetNames_ELF       ( ObjectCode* oc );
static int ocResolve_ELF        ( ObjectCode* oc );
110
#if defined(powerpc_HOST_ARCH)
111
112
static int ocAllocateJumpIslands_ELF ( ObjectCode* oc );
#endif
113
#elif defined(OBJFORMAT_PEi386)
114
115
116
static int ocVerifyImage_PEi386 ( ObjectCode* oc );
static int ocGetNames_PEi386    ( ObjectCode* oc );
static int ocResolve_PEi386     ( ObjectCode* oc );
117
118
119
120
#elif defined(OBJFORMAT_MACHO)
static int ocVerifyImage_MachO    ( ObjectCode* oc );
static int ocGetNames_MachO       ( ObjectCode* oc );
static int ocResolve_MachO        ( ObjectCode* oc );
121

122
static int machoGetMisalignment( FILE * );
123
124
#ifdef powerpc_HOST_ARCH
static int ocAllocateJumpIslands_MachO ( ObjectCode* oc );
125
static void machoInitSymbolsWithoutUnderscore( void );
126
#endif
127
#endif
128

129
130
131
132
#if defined(x86_64_HOST_ARCH)
static void*x86_64_high_symbol( char *lbl, void *addr );
#endif

133
134
135
136
/* -----------------------------------------------------------------------------
 * Built-in symbols from the RTS
 */

137
138
139
140
141
142
typedef struct _RtsSymbolVal {
    char   *lbl;
    void   *addr;
} RtsSymbolVal;


143
144
145
146
147
148
149
150
#if !defined(PAR)
#define Maybe_Stable_Names      SymX(mkWeakzh_fast)			\
      				SymX(makeStableNamezh_fast)		\
      				SymX(finalizzeWeakzh_fast)
#else
/* These are not available in GUM!!! -- HWL */
#define Maybe_Stable_Names
#endif
151

152
#if !defined (mingw32_HOST_OS)
153
#define RTS_POSIX_ONLY_SYMBOLS                  \
154
      SymX(signal_handlers)			\
155
156
      SymX(stg_sig_install)			\
      Sym(nocldstop)
sof's avatar
sof committed
157
#endif
158

159
#if defined (cygwin32_HOST_OS)
sof's avatar
sof committed
160
161
162
#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
163
 * exports; sigh.
sof's avatar
sof committed
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
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
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
 */
#define RTS_CYGWIN_ONLY_SYMBOLS                 \
      SymX(regfree)                             \
      SymX(regexec)                             \
      SymX(regerror)                            \
      SymX(regcomp)                             \
      SymX(__errno)                             \
      SymX(access)                              \
      SymX(chmod)                               \
      SymX(chdir)                               \
      SymX(close)                               \
      SymX(creat)                               \
      SymX(dup)                                 \
      SymX(dup2)                                \
      SymX(fstat)                               \
      SymX(fcntl)                               \
      SymX(getcwd)                              \
      SymX(getenv)                              \
      SymX(lseek)                               \
      SymX(open)                                \
      SymX(fpathconf)                           \
      SymX(pathconf)                            \
      SymX(stat)                                \
      SymX(pow)                                 \
      SymX(tanh)                                \
      SymX(cosh)                                \
      SymX(sinh)                                \
      SymX(atan)                                \
      SymX(acos)                                \
      SymX(asin)                                \
      SymX(tan)                                 \
      SymX(cos)                                 \
      SymX(sin)                                 \
      SymX(exp)                                 \
      SymX(log)                                 \
      SymX(sqrt)                                \
      SymX(localtime_r)                         \
      SymX(gmtime_r)                            \
      SymX(mktime)                              \
      Sym(_imp___tzname)                        \
      SymX(gettimeofday)                        \
      SymX(timezone)                            \
      SymX(tcgetattr)                           \
      SymX(tcsetattr)                           \
      SymX(memcpy)                              \
      SymX(memmove)                             \
      SymX(realloc)                             \
      SymX(malloc)                              \
      SymX(free)                                \
      SymX(fork)                                \
      SymX(lstat)                               \
      SymX(isatty)                              \
      SymX(mkdir)                               \
      SymX(opendir)                             \
      SymX(readdir)                             \
      SymX(rewinddir)                           \
      SymX(closedir)                            \
      SymX(link)                                \
      SymX(mkfifo)                              \
      SymX(pipe)                                \
      SymX(read)                                \
      SymX(rename)                              \
      SymX(rmdir)                               \
      SymX(select)                              \
      SymX(system)                              \
      SymX(write)                               \
      SymX(strcmp)                              \
      SymX(strcpy)                              \
      SymX(strncpy)                             \
      SymX(strerror)                            \
      SymX(sigaddset)                           \
      SymX(sigemptyset)                         \
      SymX(sigprocmask)                         \
      SymX(umask)                               \
      SymX(uname)                               \
      SymX(unlink)                              \
      SymX(utime)                               \
241
      SymX(waitpid)
242

243
#elif !defined(mingw32_HOST_OS)
sof's avatar
sof committed
244
245
#define RTS_MINGW_ONLY_SYMBOLS /**/
#define RTS_CYGWIN_ONLY_SYMBOLS /**/
246
#else /* defined(mingw32_HOST_OS) */
sof's avatar
sof committed
247
248
#define RTS_POSIX_ONLY_SYMBOLS  /**/
#define RTS_CYGWIN_ONLY_SYMBOLS /**/
249

250
251
252
253
/* Extra syms gen'ed by mingw-2's gcc-3.2: */
#if __GNUC__>=3
#define RTS_MINGW_EXTRA_SYMS                    \
      Sym(_imp____mb_cur_max)                   \
254
      Sym(_imp___pctype)
255
256
257
258
#else
#define RTS_MINGW_EXTRA_SYMS
#endif

259
260
/* These are statically linked from the mingw libraries into the ghc
   executable, so we have to employ this hack. */
261
#define RTS_MINGW_ONLY_SYMBOLS                  \
sof's avatar
sof committed
262
263
      SymX(asyncReadzh_fast)			\
      SymX(asyncWritezh_fast)			\
sof's avatar
sof committed
264
      SymX(asyncDoProczh_fast)			\
265
      SymX(memset)                              \
266
267
268
269
270
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
      SymX(inet_ntoa)                           \
      SymX(inet_addr)                           \
      SymX(htonl)                               \
      SymX(recvfrom)                            \
      SymX(listen)                              \
      SymX(bind)                                \
      SymX(shutdown)                            \
      SymX(connect)                             \
      SymX(htons)                               \
      SymX(ntohs)                               \
      SymX(getservbyname)                       \
      SymX(getservbyport)                       \
      SymX(getprotobynumber)                    \
      SymX(getprotobyname)                      \
      SymX(gethostbyname)                       \
      SymX(gethostbyaddr)                       \
      SymX(gethostname)                         \
      SymX(strcpy)                              \
      SymX(strncpy)                             \
      SymX(abort)                               \
      Sym(_alloca)                              \
      Sym(isxdigit)                             \
      Sym(isupper)                              \
      Sym(ispunct)                              \
      Sym(islower)                              \
      Sym(isspace)                              \
      Sym(isprint)                              \
      Sym(isdigit)                              \
      Sym(iscntrl)                              \
      Sym(isalpha)                              \
      Sym(isalnum)                              \
      SymX(strcmp)                              \
298
299
300
      SymX(memmove)                             \
      SymX(realloc)                             \
      SymX(malloc)                              \
301
302
303
304
305
306
307
308
309
310
311
312
313
      SymX(pow)                                 \
      SymX(tanh)                                \
      SymX(cosh)                                \
      SymX(sinh)                                \
      SymX(atan)                                \
      SymX(acos)                                \
      SymX(asin)                                \
      SymX(tan)                                 \
      SymX(cos)                                 \
      SymX(sin)                                 \
      SymX(exp)                                 \
      SymX(log)                                 \
      SymX(sqrt)                                \
314
315
316
317
318
319
320
321
322
323
324
325
326
      SymX(powf)                                 \
      SymX(tanhf)                                \
      SymX(coshf)                                \
      SymX(sinhf)                                \
      SymX(atanf)                                \
      SymX(acosf)                                \
      SymX(asinf)                                \
      SymX(tanf)                                 \
      SymX(cosf)                                 \
      SymX(sinf)                                 \
      SymX(expf)                                 \
      SymX(logf)                                 \
      SymX(sqrtf)                                \
327
      SymX(memcpy)                              \
sof's avatar
sof committed
328
329
      SymX(rts_InstallConsoleEvent)             \
      SymX(rts_ConsoleHandlerDone)              \
330
      Sym(mktime)                               \
331
      Sym(_imp___timezone)                      \
332
      Sym(_imp___tzname)                        \
333
      Sym(_imp__tzname)                         \
334
      Sym(_imp___iob)                           \
sof's avatar
sof committed
335
      Sym(_imp___osver)                         \
336
337
338
339
      Sym(localtime)                            \
      Sym(gmtime)                               \
      Sym(opendir)                              \
      Sym(readdir)                              \
sof's avatar
sof committed
340
      Sym(rewinddir)                            \
341
      RTS_MINGW_EXTRA_SYMS                      \
342
      Sym(closedir)
343
#endif
344

345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
#if defined(darwin_TARGET_OS) && HAVE_PRINTF_LDBLSTUB
#define RTS_DARWIN_ONLY_SYMBOLS			\
     Sym(asprintf$LDBLStub)                     \
     Sym(err$LDBLStub)                          \
     Sym(errc$LDBLStub)                         \
     Sym(errx$LDBLStub)                         \
     Sym(fprintf$LDBLStub)                      \
     Sym(fscanf$LDBLStub)                       \
     Sym(fwprintf$LDBLStub)                     \
     Sym(fwscanf$LDBLStub)                      \
     Sym(printf$LDBLStub)                       \
     Sym(scanf$LDBLStub)                        \
     Sym(snprintf$LDBLStub)                     \
     Sym(sprintf$LDBLStub)                      \
     Sym(sscanf$LDBLStub)                       \
     Sym(strtold$LDBLStub)                      \
     Sym(swprintf$LDBLStub)                     \
     Sym(swscanf$LDBLStub)                      \
     Sym(syslog$LDBLStub)                       \
     Sym(vasprintf$LDBLStub)                    \
     Sym(verr$LDBLStub)                         \
     Sym(verrc$LDBLStub)                        \
     Sym(verrx$LDBLStub)                        \
     Sym(vfprintf$LDBLStub)                     \
     Sym(vfscanf$LDBLStub)                      \
     Sym(vfwprintf$LDBLStub)                    \
     Sym(vfwscanf$LDBLStub)                     \
     Sym(vprintf$LDBLStub)                      \
     Sym(vscanf$LDBLStub)                       \
     Sym(vsnprintf$LDBLStub)                    \
     Sym(vsprintf$LDBLStub)                     \
     Sym(vsscanf$LDBLStub)                      \
     Sym(vswprintf$LDBLStub)                    \
     Sym(vswscanf$LDBLStub)                     \
     Sym(vsyslog$LDBLStub)                      \
     Sym(vwarn$LDBLStub)                        \
     Sym(vwarnc$LDBLStub)                       \
     Sym(vwarnx$LDBLStub)                       \
     Sym(vwprintf$LDBLStub)                     \
     Sym(vwscanf$LDBLStub)                      \
     Sym(warn$LDBLStub)                         \
     Sym(warnc$LDBLStub)                        \
     Sym(warnx$LDBLStub)                        \
     Sym(wcstold$LDBLStub)                      \
     Sym(wprintf$LDBLStub)                      \
     Sym(wscanf$LDBLStub)
#else
#define RTS_DARWIN_ONLY_SYMBOLS
#endif

sof's avatar
sof committed
395
396
397
398
399
#ifndef SMP
# define MAIN_CAP_SYM SymX(MainCapability)
#else
# define MAIN_CAP_SYM
#endif
400

sof's avatar
sof committed
401
402
403
404
#if !defined(mingw32_HOST_OS)
#define RTS_USER_SIGNALS_SYMBOLS \
   SymX(setIOManagerPipe)
#else
Simon Marlow's avatar
Simon Marlow committed
405
406
407
408
409
#define RTS_USER_SIGNALS_SYMBOLS \
   SymX(sendIOManagerEvent) \
   SymX(readIOManagerEvent) \
   SymX(getIOManagerEvent) \
   SymX(console_handler)
sof's avatar
sof committed
410
411
#endif

412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
#ifdef TABLES_NEXT_TO_CODE
#define RTS_RET_SYMBOLS /* nothing */
#else
#define RTS_RET_SYMBOLS 			\
      SymX(stg_enter_ret)			\
      SymX(stg_gc_fun_ret)			\
      SymX(stg_ap_v_ret)			\
      SymX(stg_ap_f_ret)			\
      SymX(stg_ap_d_ret)			\
      SymX(stg_ap_l_ret)			\
      SymX(stg_ap_n_ret)			\
      SymX(stg_ap_p_ret)			\
      SymX(stg_ap_pv_ret)			\
      SymX(stg_ap_pp_ret)			\
      SymX(stg_ap_ppv_ret)			\
      SymX(stg_ap_ppp_ret)			\
      SymX(stg_ap_pppv_ret)			\
      SymX(stg_ap_pppp_ret)			\
      SymX(stg_ap_ppppp_ret)			\
      SymX(stg_ap_pppppp_ret)
#endif

434
#define RTS_SYMBOLS				\
435
436
      Maybe_Stable_Names			\
      Sym(StgReturn)				\
437
438
      SymX(stg_enter_info)			\
      SymX(stg_gc_void_info)			\
439
440
      SymX(__stg_gc_enter_1)			\
      SymX(stg_gc_noregs)			\
441
      SymX(stg_gc_unpt_r1_info)			\
442
      SymX(stg_gc_unpt_r1)			\
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
      SymX(stg_gc_unbx_r1_info)			\
      SymX(stg_gc_unbx_r1)			\
      SymX(stg_gc_f1_info)			\
      SymX(stg_gc_f1)				\
      SymX(stg_gc_d1_info)			\
      SymX(stg_gc_d1)				\
      SymX(stg_gc_l1_info)			\
      SymX(stg_gc_l1)				\
      SymX(__stg_gc_fun)			\
      SymX(stg_gc_fun_info)			\
      SymX(stg_gc_gen)				\
      SymX(stg_gc_gen_info)			\
      SymX(stg_gc_gen_hp)			\
      SymX(stg_gc_ut)				\
      SymX(stg_gen_yield)			\
      SymX(stg_yield_noregs)			\
459
      SymX(stg_yield_to_interpreter)		\
460
461
462
463
464
465
      SymX(stg_gen_block)			\
      SymX(stg_block_noregs)			\
      SymX(stg_block_1)				\
      SymX(stg_block_takemvar)			\
      SymX(stg_block_putmvar)			\
      SymX(stg_seq_frame_info)			\
sof's avatar
sof committed
466
      MAIN_CAP_SYM                              \
467
468
469
470
471
472
      SymX(MallocFailHook)			\
      SymX(OnExitHook)				\
      SymX(OutOfHeapHook)			\
      SymX(StackOverflowHook)			\
      SymX(__encodeDouble)			\
      SymX(__encodeFloat)			\
dons's avatar
dons committed
473
      SymX(addDLL)               		\
474
475
476
477
478
479
480
481
482
      SymX(__gmpn_gcd_1)			\
      SymX(__gmpz_cmp)				\
      SymX(__gmpz_cmp_si)			\
      SymX(__gmpz_cmp_ui)			\
      SymX(__gmpz_get_si)			\
      SymX(__gmpz_get_ui)			\
      SymX(__int_encodeDouble)			\
      SymX(__int_encodeFloat)			\
      SymX(andIntegerzh_fast)			\
483
      SymX(atomicallyzh_fast)			\
484
      SymX(barf)				\
485
486
      SymX(debugBelch)				\
      SymX(errorBelch)				\
487
488
      SymX(blockAsyncExceptionszh_fast)		\
      SymX(catchzh_fast)			\
489
490
      SymX(catchRetryzh_fast)			\
      SymX(catchSTMzh_fast)			\
tharris@microsoft.com's avatar
tharris@microsoft.com committed
491
      SymX(checkzh_fast)                        \
sof's avatar
sof committed
492
      SymX(closure_flags)                       \
493
      SymX(cmp_thread)				\
sof's avatar
sof committed
494
495
      SymX(cmpIntegerzh_fast)	        	\
      SymX(cmpIntegerIntzh_fast)	      	\
sof's avatar
sof committed
496
      SymX(complementIntegerzh_fast)		\
497
498
499
500
501
      SymX(createAdjustor)			\
      SymX(decodeDoublezh_fast)			\
      SymX(decodeFloatzh_fast)			\
      SymX(defaultsHook)			\
      SymX(delayzh_fast)			\
sof's avatar
sof committed
502
503
      SymX(deRefWeakzh_fast)			\
      SymX(deRefStablePtrzh_fast)		\
504
      SymX(dirty_MUT_VAR)			\
505
506
507
      SymX(divExactIntegerzh_fast)		\
      SymX(divModIntegerzh_fast)		\
      SymX(forkzh_fast)				\
Simon Marlow's avatar
Simon Marlow committed
508
      SymX(forkOnzh_fast)			\
509
      SymX(forkProcess)				\
510
      SymX(forkOS_createThread)			\
511
      SymX(freeHaskellFunctionPtr)		\
sof's avatar
sof committed
512
      SymX(freeStablePtr)		        \
ei@vuokko.info's avatar
ei@vuokko.info committed
513
      SymX(getOrSetTypeableStore)		\
514
      SymX(gcdIntegerzh_fast)			\
sof's avatar
sof committed
515
516
      SymX(gcdIntegerIntzh_fast)		\
      SymX(gcdIntzh_fast)			\
517
      SymX(genSymZh)				\
dons's avatar
dons committed
518
      SymX(genericRaise)			\
519
520
      SymX(getProgArgv)				\
      SymX(getStablePtr)			\
521
522
523
524
525
526
527
528
      SymX(hs_init)				\
      SymX(hs_exit)				\
      SymX(hs_set_argv)				\
      SymX(hs_add_root)				\
      SymX(hs_perform_gc)			\
      SymX(hs_free_stable_ptr)			\
      SymX(hs_free_fun_ptr)			\
      SymX(initLinker)				\
529
530
      SymX(infoPtrzh_fast)                      \
      SymX(closurePayloadzh_fast)               \
531
      SymX(int2Integerzh_fast)			\
sof's avatar
sof committed
532
533
      SymX(integer2Intzh_fast)			\
      SymX(integer2Wordzh_fast)			\
534
      SymX(isCurrentThreadBoundzh_fast)		\
535
536
537
538
      SymX(isDoubleDenormalized)		\
      SymX(isDoubleInfinite)			\
      SymX(isDoubleNaN)				\
      SymX(isDoubleNegativeZero)		\
sof's avatar
sof committed
539
      SymX(isEmptyMVarzh_fast)			\
540
541
542
543
544
      SymX(isFloatDenormalized)			\
      SymX(isFloatInfinite)			\
      SymX(isFloatNaN)				\
      SymX(isFloatNegativeZero)			\
      SymX(killThreadzh_fast)			\
dons's avatar
dons committed
545
      SymX(loadObj)          			\
546
547
      SymX(insertStableSymbol) 			\
      SymX(insertSymbol)     			\
dons's avatar
dons committed
548
      SymX(lookupSymbol)     			\
549
      SymX(lookupDataCon)     			\
sof's avatar
sof committed
550
      SymX(makeStablePtrzh_fast)		\
551
552
      SymX(minusIntegerzh_fast)			\
      SymX(mkApUpd0zh_fast)			\
sof's avatar
sof committed
553
      SymX(myThreadIdzh_fast)			\
554
      SymX(labelThreadzh_fast)                  \
555
556
557
      SymX(newArrayzh_fast)			\
      SymX(newBCOzh_fast)			\
      SymX(newByteArrayzh_fast)			\
558
      SymX_redirect(newCAF, newDynCAF)		\
559
560
      SymX(newMVarzh_fast)			\
      SymX(newMutVarzh_fast)			\
561
      SymX(newTVarzh_fast)			\
562
      SymX(atomicModifyMutVarzh_fast)		\
563
      SymX(newPinnedByteArrayzh_fast)		\
564
      SymX(newSpark)				\
565
566
      SymX(orIntegerzh_fast)			\
      SymX(performGC)				\
567
      SymX(performMajorGC)			\
568
569
570
571
572
573
574
      SymX(plusIntegerzh_fast)			\
      SymX(prog_argc)				\
      SymX(prog_argv)				\
      SymX(putMVarzh_fast)			\
      SymX(quotIntegerzh_fast)			\
      SymX(quotRemIntegerzh_fast)		\
      SymX(raisezh_fast)			\
575
      SymX(raiseIOzh_fast)			\
576
      SymX(readTVarzh_fast)			\
577
578
579
      SymX(remIntegerzh_fast)			\
      SymX(resetNonBlockingFd)			\
      SymX(resumeThread)			\
dons's avatar
dons committed
580
      SymX(resolveObjs)                         \
581
      SymX(retryzh_fast)                        \
582
583
584
585
586
      SymX(rts_apply)				\
      SymX(rts_checkSchedStatus)		\
      SymX(rts_eval)				\
      SymX(rts_evalIO)				\
      SymX(rts_evalLazyIO)			\
587
      SymX(rts_evalStableIO)			\
588
589
590
591
592
593
594
595
      SymX(rts_eval_)				\
      SymX(rts_getBool)				\
      SymX(rts_getChar)				\
      SymX(rts_getDouble)			\
      SymX(rts_getFloat)			\
      SymX(rts_getInt)				\
      SymX(rts_getInt32)			\
      SymX(rts_getPtr)				\
596
      SymX(rts_getFunPtr)			\
597
      SymX(rts_getStablePtr)			\
598
      SymX(rts_getThreadId)			\
599
600
      SymX(rts_getWord)				\
      SymX(rts_getWord32)			\
601
      SymX(rts_lock)				\
602
603
604
605
606
607
608
609
610
611
      SymX(rts_mkBool)				\
      SymX(rts_mkChar)				\
      SymX(rts_mkDouble)			\
      SymX(rts_mkFloat)				\
      SymX(rts_mkInt)				\
      SymX(rts_mkInt16)				\
      SymX(rts_mkInt32)				\
      SymX(rts_mkInt64)				\
      SymX(rts_mkInt8)				\
      SymX(rts_mkPtr)				\
612
      SymX(rts_mkFunPtr)			\
613
614
615
616
617
618
619
      SymX(rts_mkStablePtr)			\
      SymX(rts_mkString)			\
      SymX(rts_mkWord)				\
      SymX(rts_mkWord16)			\
      SymX(rts_mkWord32)			\
      SymX(rts_mkWord64)			\
      SymX(rts_mkWord8)				\
620
      SymX(rts_unlock)				\
621
      SymX(rtsSupportsBoundThreads)		\
622
623
      SymX(__hscore_get_saved_termios)		\
      SymX(__hscore_set_saved_termios)		\
624
      SymX(setProgArgv)				\
625
626
      SymX(startupHaskell)			\
      SymX(shutdownHaskell)			\
627
628
629
630
      SymX(shutdownHaskellAndExit)		\
      SymX(stable_ptr_table)			\
      SymX(stackOverflow)			\
      SymX(stg_CAF_BLACKHOLE_info)		\
631
      SymX(awakenBlockedQueue)			\
632
633
634
635
      SymX(stg_CHARLIKE_closure)		\
      SymX(stg_EMPTY_MVAR_info)			\
      SymX(stg_IND_STATIC_info)			\
      SymX(stg_INTLIKE_closure)			\
636
      SymX(stg_MUT_ARR_PTRS_DIRTY_info)		\
637
      SymX(stg_MUT_ARR_PTRS_FROZEN_info)	\
638
      SymX(stg_MUT_ARR_PTRS_FROZEN0_info)	\
639
      SymX(stg_WEAK_info)                       \
640
641
642
643
644
645
646
647
648
649
      SymX(stg_ap_v_info)			\
      SymX(stg_ap_f_info)			\
      SymX(stg_ap_d_info)			\
      SymX(stg_ap_l_info)			\
      SymX(stg_ap_n_info)			\
      SymX(stg_ap_p_info)			\
      SymX(stg_ap_pv_info)			\
      SymX(stg_ap_pp_info)			\
      SymX(stg_ap_ppv_info)			\
      SymX(stg_ap_ppp_info)			\
650
      SymX(stg_ap_pppv_info)			\
651
652
653
      SymX(stg_ap_pppp_info)			\
      SymX(stg_ap_ppppp_info)			\
      SymX(stg_ap_pppppp_info)			\
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
      SymX(stg_ap_0_fast)			\
      SymX(stg_ap_v_fast)			\
      SymX(stg_ap_f_fast)			\
      SymX(stg_ap_d_fast)			\
      SymX(stg_ap_l_fast)			\
      SymX(stg_ap_n_fast)			\
      SymX(stg_ap_p_fast)			\
      SymX(stg_ap_pv_fast)			\
      SymX(stg_ap_pp_fast)			\
      SymX(stg_ap_ppv_fast)			\
      SymX(stg_ap_ppp_fast)			\
      SymX(stg_ap_pppv_fast)			\
      SymX(stg_ap_pppp_fast)			\
      SymX(stg_ap_ppppp_fast)			\
      SymX(stg_ap_pppppp_fast)			\
669
      SymX(stg_ap_1_upd_info)			\
670
671
672
673
674
675
      SymX(stg_ap_2_upd_info)			\
      SymX(stg_ap_3_upd_info)			\
      SymX(stg_ap_4_upd_info)			\
      SymX(stg_ap_5_upd_info)			\
      SymX(stg_ap_6_upd_info)			\
      SymX(stg_ap_7_upd_info)			\
676
      SymX(stg_exit)				\
677
      SymX(stg_sel_0_upd_info)			\
678
679
680
681
682
683
      SymX(stg_sel_10_upd_info)			\
      SymX(stg_sel_11_upd_info)			\
      SymX(stg_sel_12_upd_info)			\
      SymX(stg_sel_13_upd_info)			\
      SymX(stg_sel_14_upd_info)			\
      SymX(stg_sel_15_upd_info)			\
684
685
686
687
688
689
690
691
692
      SymX(stg_sel_1_upd_info)			\
      SymX(stg_sel_2_upd_info)			\
      SymX(stg_sel_3_upd_info)			\
      SymX(stg_sel_4_upd_info)			\
      SymX(stg_sel_5_upd_info)			\
      SymX(stg_sel_6_upd_info)			\
      SymX(stg_sel_7_upd_info)			\
      SymX(stg_sel_8_upd_info)			\
      SymX(stg_sel_9_upd_info)			\
693
694
      SymX(stg_upd_frame_info)			\
      SymX(suspendThread)			\
695
      SymX(takeMVarzh_fast)			\
696
      SymX(timesIntegerzh_fast)			\
697
      SymX(tryPutMVarzh_fast)			\
698
699
      SymX(tryTakeMVarzh_fast)			\
      SymX(unblockAsyncExceptionszh_fast)	\
dons's avatar
dons committed
700
      SymX(unloadObj)                           \
701
      SymX(unsafeThawArrayzh_fast)		\
702
703
      SymX(waitReadzh_fast)			\
      SymX(waitWritezh_fast)			\
704
      SymX(word2Integerzh_fast)			\
705
      SymX(writeTVarzh_fast)			\
706
      SymX(xorIntegerzh_fast)			\
sof's avatar
sof committed
707
      SymX(yieldzh_fast)                        \
708
709
710
711
712
713
714
715
716
      SymX(stg_interp_constr_entry)             \
      SymX(stg_interp_constr1_entry)            \
      SymX(stg_interp_constr2_entry)            \
      SymX(stg_interp_constr3_entry)            \
      SymX(stg_interp_constr4_entry)            \
      SymX(stg_interp_constr5_entry)            \
      SymX(stg_interp_constr6_entry)            \
      SymX(stg_interp_constr7_entry)            \
      SymX(stg_interp_constr8_entry)            \
717
718
      SymX(allocateExec)	                \
      SymX(freeExec)		                \
719
720
721
      SymX(getAllocations)                      \
      SymX(revertCAFs)                          \
      SymX(RtsFlags)                            \
sof's avatar
sof committed
722
      RTS_USER_SIGNALS_SYMBOLS
723

724
#ifdef SUPPORT_LONG_LONGS
725
#define RTS_LONG_LONG_SYMS			\
726
727
      SymX(int64ToIntegerzh_fast)		\
      SymX(word64ToIntegerzh_fast)
728
729
730
731
#else
#define RTS_LONG_LONG_SYMS /* nothing */
#endif

732
733
734
// 64-bit support functions in libgcc.a
#if defined(__GNUC__) && SIZEOF_VOID_P <= 4
#define RTS_LIBGCC_SYMBOLS			\
735
736
737
      Sym(__divdi3)                             \
      Sym(__udivdi3)                            \
      Sym(__moddi3)                             \
738
      Sym(__umoddi3)				\
739
      Sym(__muldi3)				\
740
741
742
743
      Sym(__ashldi3)				\
      Sym(__ashrdi3)				\
      Sym(__lshrdi3)				\
      Sym(__eprintf)
744
#elif defined(ia64_HOST_ARCH)
745
746
747
748
749
750
751
#define RTS_LIBGCC_SYMBOLS			\
      Sym(__divdi3)				\
      Sym(__udivdi3)                            \
      Sym(__moddi3)				\
      Sym(__umoddi3)				\
      Sym(__divsf3)				\
      Sym(__divdf3)
752
753
754
755
#else
#define RTS_LIBGCC_SYMBOLS
#endif

756
#if defined(darwin_HOST_OS) && defined(powerpc_HOST_ARCH)
757
758
759
760
761
762
      // 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		\
      Sym(saveFP)				\
      Sym(restFP)
763
#endif
764
765

/* entirely bogus claims about types of these symbols */
766
#define Sym(vvv)  extern void vvv(void);
767
#define SymX(vvv) /**/
768
#define SymX_redirect(vvv,xxx) /**/
769
RTS_SYMBOLS
770
RTS_RET_SYMBOLS
771
RTS_LONG_LONG_SYMS
772
RTS_POSIX_ONLY_SYMBOLS
773
RTS_MINGW_ONLY_SYMBOLS
sof's avatar
sof committed
774
RTS_CYGWIN_ONLY_SYMBOLS
775
RTS_DARWIN_ONLY_SYMBOLS
776
RTS_LIBGCC_SYMBOLS
777
778
#undef Sym
#undef SymX
779
#undef SymX_redirect
780
781
782
783
784
785
786
787
788
789
790

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

#define Sym(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
                    (void*)(&(vvv)) },
#define SymX(vvv) Sym(vvv)

791
792
793
794
795
796
// SymX_redirect allows us to redirect references to one symbol to
// another symbol.  See newCAF/newDynCAF for an example.
#define SymX_redirect(vvv,xxx) \
    { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
      (void*)(&(xxx)) },

797
static RtsSymbolVal rtsSyms[] = {
798
      RTS_SYMBOLS
799
      RTS_RET_SYMBOLS
800
      RTS_LONG_LONG_SYMS
801
      RTS_POSIX_ONLY_SYMBOLS
802
      RTS_MINGW_ONLY_SYMBOLS
sof's avatar
sof committed
803
      RTS_CYGWIN_ONLY_SYMBOLS
804
      RTS_DARWIN_ONLY_SYMBOLS
805
      RTS_LIBGCC_SYMBOLS
806
807
808
809
#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.
810
      { "dyld_stub_binding_helper", (void*)0xDEADBEEF },
811
#endif
812
813
814
      { 0, 0 } /* sentinel */
};

815
816


817
818
819
/* -----------------------------------------------------------------------------
 * Insert symbols into hash tables, checking for duplicates.
 */
mnislaih's avatar
mnislaih committed
820
int isSuffixOf(char* x, char* suffix);
821

822
823
static void ghciInsertStrHashTable ( char* obj_name,
                                     HashTable *table,
824
                                     char* key,
825
826
827
828
829
830
                                     void *data
				   )
{
   if (lookupHashTable(table, (StgWord)key) == NULL)
   {
      insertStrHashTable(table, (StgWord)key, data);
831
#if defined(DEBUGGER)    
832
833
834
835
836
837
838
839
      // Insert the reverse pair in the datacon hash if it is a closure
      {
	if(isSuffixOf(key, "static_info") || isSuffixOf(key, "con_info")) {
	     insertHashTable(dchash, (StgWord)data, key);
	     //             debugBelch("DChash addSymbol: %s (%p)\n", key, data);
	   }
      }
#endif
840
841
      return;
   }
842
   debugBelch(
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
      "\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
   );
   exit(1);
}
860
861
862
/* -----------------------------------------------------------------------------
 * initialize the object linker
 */
863
864
865
866


static int linker_init_done = 0 ;

867
#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
868
static void *dl_prog_handle;
869
#endif
870
871
872
873

void
initLinker( void )
{
874
    RtsSymbolVal *sym;
875

876
877
878
879
880
881
882
    /* 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;
    }

883
    stablehash = allocStrHashTable();
884
    symhash = allocStrHashTable();
885
#if defined(DEBUGGER)
886
887
    dchash  = allocHashTable();
#endif
888
889
890

    /* populate the symbol table with stuff from the RTS */
    for (sym = rtsSyms; sym->lbl != NULL; sym++) {
891
892
	ghciInsertStrHashTable("(GHCi built-in symbols)",
                               symhash, sym->lbl, sym->addr);
893
    }
894
#   if defined(OBJFORMAT_MACHO) && defined(powerpc_HOST_ARCH)
895
896
897
    machoInitSymbolsWithoutUnderscore();
#   endif

898
#   if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
899
#   if defined(RTLD_DEFAULT)
900
901
    dl_prog_handle = RTLD_DEFAULT;
#   else
902
    dl_prog_handle = dlopen(NULL, RTLD_LAZY);
903
#   endif /* RTLD_DEFAULT */
904
#   endif
905
906
}

907
/* -----------------------------------------------------------------------------
908
909
910
 *                  Loading DLL or .so dynamic libraries
 * -----------------------------------------------------------------------------
 *
911
912
913
914
 * 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
915
916
 * dl-handle.  Returns NULL if success, otherwise ptr to an err msg.
 *
917
 * In the PEi386 case, open the DLLs and put handles to them in a
918
 * linked list.  When looking for a symbol, try all handles in the
919
920
921
922
923
 * 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.
924
 *
925
 */
926
927
928
929
930
931

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

typedef
   struct _OpenedDLL {
932
      char*              name;
933
934
      struct _OpenedDLL* next;
      HINSTANCE instance;
935
   }
936
937
938
939
940
941
   OpenedDLL;

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

942
943
char *
addDLL( char *dll_name )
944
{
945
#  if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
946
   /* ------------------- ELF DLL loader ------------------- */
947
   void *hdl;
948
   char *errmsg;
949

950
951
   initLinker();

952
   hdl= dlopen(dll_name, RTLD_NOW | RTLD_GLOBAL);
dons's avatar
dons committed
953

954
955
956
957
958
959
960
961
   if (hdl == NULL) {
      /* dlopen failed; return a ptr to the error msg. */
      errmsg = dlerror();
      if (errmsg == NULL) errmsg = "addDLL: unknown error";
      return errmsg;
   } else {
      return NULL;
   }
962
963
   /*NOTREACHED*/

964
#  elif defined(OBJFORMAT_PEi386)
965
   /* ------------------- Win32 DLL loader ------------------- */
966

967
   char*      buf;
968
   OpenedDLL* o_dll;
969
   HINSTANCE  instance;
970

971
972
   initLinker();

973
   /* debugBelch("\naddDLL; dll_name = `%s'\n", dll_name); */
974
975
976
977
978

   /* 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;
979
980
   }

981
982
983
984
985
986
987
988
989
990
   /* 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. */

991
   buf = stgMallocBytes(strlen(dll_name) + 10, "addDLL");
992
993
994
   sprintf(buf, "%s.DLL", dll_name);
   instance = LoadLibrary(buf);
   if (instance == NULL) {
995
	 sprintf(buf, "%s.DRV", dll_name);	// KAA: allow loading of drivers (like winspool.drv)
996
997
	 instance = LoadLibrary(buf);
	 if (instance == NULL) {
sof's avatar
sof committed
998
		stgFree(buf);
999
1000
1001
1002

	    /* LoadLibrary failed; return a ptr to the error msg. */
	    return "addDLL: unknown error";
   	 }
1003
   }
sof's avatar
sof committed
1004
   stgFree(buf);
1005

1006
   /* Add this DLL to the list of DLLs in which to search for symbols. */
1007
   o_dll = stgMallocBytes( sizeof(OpenedDLL), "addDLL" );
1008
1009
   o_dll->name     = stgMallocBytes(1+strlen(dll_name), "addDLL");
   strcpy(o_dll->name, dll_name);
1010
   o_dll->instance = instance;
1011
1012
   o_dll->next     = opened_dlls;
   opened_dlls     = o_dll;
1013
1014

   return NULL;
1015
1016
1017
1018
1019
#  else
   barf("addDLL: not implemented on this platform");
#  endif
}

1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
/* -----------------------------------------------------------------------------
 * 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);
}

1040
1041
/* -----------------------------------------------------------------------------
 * lookup a symbol in the hash table
1042
 */
1043
1044
1045
void *
lookupSymbol( char *lbl )
{
1046
    void *val;
1047
    initLinker() ;
1048
    ASSERT(symhash != NULL);
1049
1050
1051
    val = lookupStrHashTable(symhash, lbl);

    if (val == NULL) {
1052
#       if defined(OBJFORMAT_ELF)
1053
#	if defined(x86_64_HOST_ARCH)
1054
1055
1056
1057
1058
1059
1060
1061
1062
	val = dlsym(dl_prog_handle, lbl);
	if (val >= (void *)0x80000000) {
	    void *new_val;
	    new_val = x86_64_high_symbol(lbl, val);
	    IF_DEBUG(linker,debugBelch("lookupSymbol: relocating out of range symbol: %s = %p, now %p\n", lbl, val, new_val));
	    return new_val;
	} else {
	    return val;
	}
1063
#	else
1064
	return dlsym(dl_prog_handle, lbl);
dons's avatar
dons committed
1065
#	endif
1066
1067
1068
1069
1070
1071
1072
#       elif defined(OBJFORMAT_MACHO)
	if(NSIsSymbolNameDefined(lbl)) {
	    NSSymbol symbol = NSLookupAndBindSymbol(lbl);
	    return NSAddressOfSymbol(symbol);
	} else {
	    return NULL;
	}
1073
#       elif defined(OBJFORMAT_PEi386)
1074
1075
1076
        OpenedDLL* o_dll;
        void* sym;
        for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
1077
	  /* debugBelch("look in %s for %s\n", o_dll->name, lbl); */
1078
1079
1080
1081
1082
1083
1084
           if (lbl[0] == '_') {
              /* HACK: if the name has an initial underscore, try stripping
                 it off & look that up first. I've yet to verify whether there's
                 a Rule that governs whether an initial '_' *should always* be
                 stripped off when mapping from import lib name to the DLL name.
              */
              sym = GetProcAddress(o_dll->instance, (lbl+1));
sof's avatar
sof committed
1085
              if (sym != NULL) {
1086
		/*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/
sof's avatar
sof committed
1087
		return sym;
1088
	      }
1089
           }
1090
           sym = GetProcAddress(o_dll->instance, lbl);
sof's avatar
sof committed
1091
           if (sym != NULL) {
1092
	     /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/
sof's avatar
sof committed
1093
1094
	     return sym;
	   }
1095
        }
1096
        return NULL;
ken's avatar
ken committed
1097
1098
1099
#       else
        ASSERT(2+2 == 5);
        return NULL;
1100
#       endif
1101
    } else {
1102
	return val;
1103
1104
1105
    }
}

1106
#if defined(DEBUGGER)
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
char * 
lookupDataCon( StgWord addr ) 
{
  void *val;
    initLinker() ;
    ASSERT(dchash != NULL);
    val = lookupHashTable(dchash, addr); 

    return val;
}
#else
char* lookupDataCon( StgWord addr )
{
  return NULL;
}
#endif

1124
static
1125
__attribute((unused))
1126
1127
1128
void *
lookupLocalSymbol( ObjectCode* oc, char *lbl )
{
1129
    void *val;
1130
    initLinker() ;
1131
1132
1133
1134
1135
    val = lookupStrHashTable(oc->lochash, lbl);

    if (val == NULL) {
        return NULL;
    } else {
1136
	return val;
1137
1138
1139
1140
    }
}


1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
/* -----------------------------------------------------------------------------
 * 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 ghci_enquire ( char* addr )
{
   int   i;
   char* sym;
   char* a;
   const int DELTA = 64;
   ObjectCode* oc;
1155
1156
1157

   initLinker();

1158
1159
1160
1161
   for (oc = objects; oc; oc = oc->next) {
      for (i = 0; i < oc->n_symbols; i++) {
         sym = oc->symbols[i];
         if (sym == NULL) continue;
1162
         // debugBelch("enquire %p %p\n", sym, oc->lochash);
1163
         a = NULL;
1164
         if (oc->lochash != NULL) {
1165
            a = lookupStrHashTable(oc->lochash, sym);
1166
1167
	 }
         if (a == NULL) {
1168
            a = lookupStrHashTable(symhash, sym);
1169
	 }
1170
         if (a == NULL) {
1171
	     // debugBelch("ghci_enquire: can't find %s\n", sym);
1172
         }
1173
         else if (addr-DELTA <= a && a <= addr+DELTA) {
1174
            debugBelch("%p + %3d  ==  `%s'\n", addr, (int)(a - addr), sym);
1175
1176
1177
1178
1179
1180
         }
      }
   }
}
#endif

1181
#ifdef ia64_HOST_ARCH
1182
1183
static unsigned int PLTSize(void);
#endif
1184

1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
/* -----------------------------------------------------------------------------
 * Load an obj (populate the global symbol table, but don't resolve yet)
 *
 * Returns: 1 if ok, 0 on error.
 */
HsInt
loadObj( char *path )
{
   ObjectCode* oc;
   struct stat st;
   int r, n;
1196
1197
#ifdef USE_MMAP
   int fd, pagesize;
1198
   void *map_addr = NULL;
1199
#else
1200
   FILE *f;
1201
#endif
1202
1203
   initLinker();

1204
   /* debugBelch("loadObj %s\n", path ); */
1205

1206
   /* Check that we haven't already loaded this object.
dons's avatar
dons committed
1207
      Ignore requests to load multiple times */
1208
   {
1209
       ObjectCode *o;
1210
1211
       int is_dup = 0;
       for (o = objects; o; o = o->next) {
dons's avatar
dons committed
1212
          if (0 == strcmp(o->fileName, path)) {
1213
             is_dup = 1;
dons's avatar
dons committed
1214
1215
             break; /* don't need to search further */
          }
1216
1217
       }
       if (is_dup) {
1218
          IF_DEBUG(linker, debugBelch(
1219
1220
1221
            "GHCi runtime linker: warning: looks like you're trying to load the\n"
            "same object file twice:\n"
            "   %s\n"
dons's avatar
dons committed
1222
1223
1224