PageRenderTime 93ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 1ms

/rts/Linker.c

https://github.com/dorchard/ghc
C | 6556 lines | 5063 code | 687 blank | 806 comment | 964 complexity | e8907cc17e82ad8e0a73e6a5b6e91f69 MD5 | raw file
  1. /* -----------------------------------------------------------------------------
  2. *
  3. * (c) The GHC Team, 2000-2012
  4. *
  5. * RTS Object Linker
  6. *
  7. * ---------------------------------------------------------------------------*/
  8. #if 0
  9. #include "PosixSource.h"
  10. #endif
  11. /* Linux needs _GNU_SOURCE to get RTLD_DEFAULT from <dlfcn.h> and
  12. MREMAP_MAYMOVE from <sys/mman.h>.
  13. */
  14. #if defined(__linux__) || defined(__GLIBC__)
  15. #define _GNU_SOURCE 1
  16. #endif
  17. #include "Rts.h"
  18. #include "HsFFI.h"
  19. #include "sm/Storage.h"
  20. #include "Stats.h"
  21. #include "Hash.h"
  22. #include "LinkerInternals.h"
  23. #include "RtsUtils.h"
  24. #include "Trace.h"
  25. #include "StgPrimFloat.h" // for __int_encodeFloat etc.
  26. #include "Stable.h"
  27. #include "Proftimer.h"
  28. #if !defined(mingw32_HOST_OS)
  29. #include "posix/Signals.h"
  30. #endif
  31. // get protos for is*()
  32. #include <ctype.h>
  33. #ifdef HAVE_SYS_TYPES_H
  34. #include <sys/types.h>
  35. #endif
  36. #include <inttypes.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39. #include <stdio.h>
  40. #include <assert.h>
  41. #ifdef HAVE_SYS_STAT_H
  42. #include <sys/stat.h>
  43. #endif
  44. #if defined(HAVE_DLFCN_H)
  45. #include <dlfcn.h>
  46. #endif
  47. #if defined(cygwin32_HOST_OS)
  48. #ifdef HAVE_DIRENT_H
  49. #include <dirent.h>
  50. #endif
  51. #ifdef HAVE_SYS_TIME_H
  52. #include <sys/time.h>
  53. #endif
  54. #include <regex.h>
  55. #include <sys/fcntl.h>
  56. #include <sys/termios.h>
  57. #include <sys/utime.h>
  58. #include <sys/utsname.h>
  59. #include <sys/wait.h>
  60. #endif
  61. #if (defined(powerpc_HOST_ARCH) && defined(linux_HOST_OS)) \
  62. || (!defined(powerpc_HOST_ARCH) && \
  63. ( defined(linux_HOST_OS) || defined(freebsd_HOST_OS) || \
  64. defined(dragonfly_HOST_OS) || defined(netbsd_HOST_OS ) || \
  65. defined(openbsd_HOST_OS ) || defined(darwin_HOST_OS ) || \
  66. defined(kfreebsdgnu_HOST_OS) || defined(gnu_HOST_OS)))
  67. /* Don't use mmap on powerpc_HOST_ARCH as mmap doesn't support
  68. * reallocating but we need to allocate jump islands just after each
  69. * object images. Otherwise relative branches to jump islands can fail
  70. * due to 24-bits displacement overflow.
  71. */
  72. #define USE_MMAP
  73. #include <fcntl.h>
  74. #include <sys/mman.h>
  75. #ifdef HAVE_UNISTD_H
  76. #include <unistd.h>
  77. #endif
  78. #endif
  79. /* PowerPC has relative branch instructions with only 24 bit displacements
  80. * and therefore needs jump islands contiguous with each object code module.
  81. */
  82. #if (defined(USE_MMAP) && defined(powerpc_HOST_ARCH) && defined(linux_HOST_OS))
  83. #define USE_CONTIGUOUS_MMAP 1
  84. #else
  85. #define USE_CONTIGUOUS_MMAP 0
  86. #endif
  87. #if defined(linux_HOST_OS) || defined(solaris2_HOST_OS) || defined(freebsd_HOST_OS) || defined(kfreebsdgnu_HOST_OS) || defined(dragonfly_HOST_OS) || defined(netbsd_HOST_OS) || defined(openbsd_HOST_OS) || defined(gnu_HOST_OS)
  88. # define OBJFORMAT_ELF
  89. # include <regex.h> // regex is already used by dlopen() so this is OK
  90. // to use here without requiring an additional lib
  91. #elif defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
  92. # define OBJFORMAT_PEi386
  93. # include <windows.h>
  94. # include <math.h>
  95. #elif defined(darwin_HOST_OS)
  96. # define OBJFORMAT_MACHO
  97. # include <regex.h>
  98. # include <mach/machine.h>
  99. # include <mach-o/fat.h>
  100. # include <mach-o/loader.h>
  101. # include <mach-o/nlist.h>
  102. # include <mach-o/reloc.h>
  103. #if !defined(HAVE_DLFCN_H)
  104. # include <mach-o/dyld.h>
  105. #endif
  106. #if defined(powerpc_HOST_ARCH)
  107. # include <mach-o/ppc/reloc.h>
  108. #endif
  109. #if defined(x86_64_HOST_ARCH)
  110. # include <mach-o/x86_64/reloc.h>
  111. #endif
  112. #endif
  113. #if defined(x86_64_HOST_ARCH) && defined(darwin_HOST_OS)
  114. #define ALWAYS_PIC
  115. #endif
  116. #if defined(dragonfly_HOST_OS)
  117. #include <sys/tls.h>
  118. #endif
  119. // Defining this as 'int' rather than 'const int' means that we don't get
  120. // warnings like
  121. // error: function might be possible candidate for attribute ‘noreturn’
  122. // from gcc:
  123. #ifdef DYNAMIC_BY_DEFAULT
  124. int dynamicByDefault = 1;
  125. #else
  126. int dynamicByDefault = 0;
  127. #endif
  128. /* Hash table mapping symbol names to Symbol */
  129. static /*Str*/HashTable *symhash;
  130. /* Hash table mapping symbol names to StgStablePtr */
  131. static /*Str*/HashTable *stablehash;
  132. /* List of currently loaded objects */
  133. ObjectCode *objects = NULL; /* initially empty */
  134. static HsInt loadOc( ObjectCode* oc );
  135. static ObjectCode* mkOc( pathchar *path, char *image, int imageSize,
  136. char *archiveMemberName
  137. #ifndef USE_MMAP
  138. #ifdef darwin_HOST_OS
  139. , int misalignment
  140. #endif
  141. #endif
  142. );
  143. // Use wchar_t for pathnames on Windows (#5697)
  144. #if defined(mingw32_HOST_OS)
  145. #define pathcmp wcscmp
  146. #define pathlen wcslen
  147. #define pathopen _wfopen
  148. #define pathstat _wstat
  149. #define struct_stat struct _stat
  150. #define open wopen
  151. #define WSTR(s) L##s
  152. #define PATH_FMT "S"
  153. #else
  154. #define pathcmp strcmp
  155. #define pathlen strlen
  156. #define pathopen fopen
  157. #define pathstat stat
  158. #define struct_stat struct stat
  159. #define WSTR(s) s
  160. #define PATH_FMT "s"
  161. #endif
  162. static pathchar* pathdup(pathchar *path)
  163. {
  164. pathchar *ret;
  165. #if defined(mingw32_HOST_OS)
  166. ret = wcsdup(path);
  167. #else
  168. /* sigh, strdup() isn't a POSIX function, so do it the long way */
  169. ret = stgMallocBytes( strlen(path)+1, "loadObj" );
  170. strcpy(ret, path);
  171. #endif
  172. return ret;
  173. }
  174. #if defined(OBJFORMAT_ELF)
  175. static int ocVerifyImage_ELF ( ObjectCode* oc );
  176. static int ocGetNames_ELF ( ObjectCode* oc );
  177. static int ocResolve_ELF ( ObjectCode* oc );
  178. #if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH) || defined(arm_HOST_ARCH)
  179. static int ocAllocateSymbolExtras_ELF ( ObjectCode* oc );
  180. #endif
  181. #elif defined(OBJFORMAT_PEi386)
  182. static int ocVerifyImage_PEi386 ( ObjectCode* oc );
  183. static int ocGetNames_PEi386 ( ObjectCode* oc );
  184. static int ocResolve_PEi386 ( ObjectCode* oc );
  185. static void *lookupSymbolInDLLs ( unsigned char *lbl );
  186. static void zapTrailingAtSign ( unsigned char *sym );
  187. #elif defined(OBJFORMAT_MACHO)
  188. static int ocVerifyImage_MachO ( ObjectCode* oc );
  189. static int ocGetNames_MachO ( ObjectCode* oc );
  190. static int ocResolve_MachO ( ObjectCode* oc );
  191. #ifndef USE_MMAP
  192. static int machoGetMisalignment( FILE * );
  193. #endif
  194. #if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
  195. static int ocAllocateSymbolExtras_MachO ( ObjectCode* oc );
  196. #endif
  197. #ifdef powerpc_HOST_ARCH
  198. static void machoInitSymbolsWithoutUnderscore( void );
  199. #endif
  200. #endif
  201. /* on x86_64 we have a problem with relocating symbol references in
  202. * code that was compiled without -fPIC. By default, the small memory
  203. * model is used, which assumes that symbol references can fit in a
  204. * 32-bit slot. The system dynamic linker makes this work for
  205. * references to shared libraries by either (a) allocating a jump
  206. * table slot for code references, or (b) moving the symbol at load
  207. * time (and copying its contents, if necessary) for data references.
  208. *
  209. * We unfortunately can't tell whether symbol references are to code
  210. * or data. So for now we assume they are code (the vast majority
  211. * are), and allocate jump-table slots. Unfortunately this will
  212. * SILENTLY generate crashing code for data references. This hack is
  213. * enabled by X86_64_ELF_NONPIC_HACK.
  214. *
  215. * One workaround is to use shared Haskell libraries. This is
  216. * coming. Another workaround is to keep the static libraries but
  217. * compile them with -fPIC, because that will generate PIC references
  218. * to data which can be relocated. The PIC code is still too green to
  219. * do this systematically, though.
  220. *
  221. * See bug #781
  222. * See thread http://www.haskell.org/pipermail/cvs-ghc/2007-September/038458.html
  223. *
  224. * Naming Scheme for Symbol Macros
  225. *
  226. * SymI_*: symbol is internal to the RTS. It resides in an object
  227. * file/library that is statically.
  228. * SymE_*: symbol is external to the RTS library. It might be linked
  229. * dynamically.
  230. *
  231. * Sym*_HasProto : the symbol prototype is imported in an include file
  232. * or defined explicitly
  233. * Sym*_NeedsProto: the symbol is undefined and we add a dummy
  234. * default proto extern void sym(void);
  235. */
  236. #define X86_64_ELF_NONPIC_HACK 1
  237. /* Link objects into the lower 2Gb on x86_64. GHC assumes the
  238. * small memory model on this architecture (see gcc docs,
  239. * -mcmodel=small).
  240. *
  241. * MAP_32BIT not available on OpenBSD/amd64
  242. */
  243. #if defined(x86_64_HOST_ARCH) && defined(MAP_32BIT)
  244. #define TRY_MAP_32BIT MAP_32BIT
  245. #else
  246. #define TRY_MAP_32BIT 0
  247. #endif
  248. /*
  249. * Due to the small memory model (see above), on x86_64 we have to map
  250. * all our non-PIC object files into the low 2Gb of the address space
  251. * (why 2Gb and not 4Gb? Because all addresses must be reachable
  252. * using a 32-bit signed PC-relative offset). On Linux we can do this
  253. * using the MAP_32BIT flag to mmap(), however on other OSs
  254. * (e.g. *BSD, see #2063, and also on Linux inside Xen, see #2512), we
  255. * can't do this. So on these systems, we have to pick a base address
  256. * in the low 2Gb of the address space and try to allocate memory from
  257. * there.
  258. *
  259. * We pick a default address based on the OS, but also make this
  260. * configurable via an RTS flag (+RTS -xm)
  261. */
  262. #if !defined(ALWAYS_PIC) && defined(x86_64_HOST_ARCH)
  263. #if defined(MAP_32BIT)
  264. // Try to use MAP_32BIT
  265. #define MMAP_32BIT_BASE_DEFAULT 0
  266. #else
  267. // A guess: 1Gb.
  268. #define MMAP_32BIT_BASE_DEFAULT 0x40000000
  269. #endif
  270. static void *mmap_32bit_base = (void *)MMAP_32BIT_BASE_DEFAULT;
  271. #endif
  272. /* MAP_ANONYMOUS is MAP_ANON on some systems, e.g. OpenBSD */
  273. #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
  274. #define MAP_ANONYMOUS MAP_ANON
  275. #endif
  276. /* -----------------------------------------------------------------------------
  277. * Built-in symbols from the RTS
  278. */
  279. typedef struct _RtsSymbolVal {
  280. char *lbl;
  281. void *addr;
  282. } RtsSymbolVal;
  283. #define Maybe_Stable_Names SymI_HasProto(stg_mkWeakzh) \
  284. SymI_HasProto(stg_mkWeakNoFinalizzerzh) \
  285. SymI_HasProto(stg_mkWeakForeignEnvzh) \
  286. SymI_HasProto(stg_makeStableNamezh) \
  287. SymI_HasProto(stg_finalizzeWeakzh)
  288. #if !defined (mingw32_HOST_OS)
  289. #define RTS_POSIX_ONLY_SYMBOLS \
  290. SymI_HasProto(__hscore_get_saved_termios) \
  291. SymI_HasProto(__hscore_set_saved_termios) \
  292. SymI_HasProto(shutdownHaskellAndSignal) \
  293. SymI_HasProto(signal_handlers) \
  294. SymI_HasProto(stg_sig_install) \
  295. SymI_HasProto(rtsTimerSignal) \
  296. SymI_HasProto(atexit) \
  297. SymI_NeedsProto(nocldstop)
  298. #endif
  299. #if defined (cygwin32_HOST_OS)
  300. #define RTS_MINGW_ONLY_SYMBOLS /**/
  301. /* Don't have the ability to read import libs / archives, so
  302. * we have to stupidly list a lot of what libcygwin.a
  303. * exports; sigh.
  304. */
  305. #define RTS_CYGWIN_ONLY_SYMBOLS \
  306. SymI_HasProto(regfree) \
  307. SymI_HasProto(regexec) \
  308. SymI_HasProto(regerror) \
  309. SymI_HasProto(regcomp) \
  310. SymI_HasProto(__errno) \
  311. SymI_HasProto(access) \
  312. SymI_HasProto(chmod) \
  313. SymI_HasProto(chdir) \
  314. SymI_HasProto(close) \
  315. SymI_HasProto(creat) \
  316. SymI_HasProto(dup) \
  317. SymI_HasProto(dup2) \
  318. SymI_HasProto(fstat) \
  319. SymI_HasProto(fcntl) \
  320. SymI_HasProto(getcwd) \
  321. SymI_HasProto(getenv) \
  322. SymI_HasProto(lseek) \
  323. SymI_HasProto(open) \
  324. SymI_HasProto(fpathconf) \
  325. SymI_HasProto(pathconf) \
  326. SymI_HasProto(stat) \
  327. SymI_HasProto(pow) \
  328. SymI_HasProto(tanh) \
  329. SymI_HasProto(cosh) \
  330. SymI_HasProto(sinh) \
  331. SymI_HasProto(atan) \
  332. SymI_HasProto(acos) \
  333. SymI_HasProto(asin) \
  334. SymI_HasProto(tan) \
  335. SymI_HasProto(cos) \
  336. SymI_HasProto(sin) \
  337. SymI_HasProto(exp) \
  338. SymI_HasProto(log) \
  339. SymI_HasProto(sqrt) \
  340. SymI_HasProto(localtime_r) \
  341. SymI_HasProto(gmtime_r) \
  342. SymI_HasProto(mktime) \
  343. SymI_NeedsProto(_imp___tzname) \
  344. SymI_HasProto(gettimeofday) \
  345. SymI_HasProto(timezone) \
  346. SymI_HasProto(tcgetattr) \
  347. SymI_HasProto(tcsetattr) \
  348. SymI_HasProto(memcpy) \
  349. SymI_HasProto(memmove) \
  350. SymI_HasProto(realloc) \
  351. SymI_HasProto(malloc) \
  352. SymI_HasProto(free) \
  353. SymI_HasProto(fork) \
  354. SymI_HasProto(lstat) \
  355. SymI_HasProto(isatty) \
  356. SymI_HasProto(mkdir) \
  357. SymI_HasProto(opendir) \
  358. SymI_HasProto(readdir) \
  359. SymI_HasProto(rewinddir) \
  360. SymI_HasProto(closedir) \
  361. SymI_HasProto(link) \
  362. SymI_HasProto(mkfifo) \
  363. SymI_HasProto(pipe) \
  364. SymI_HasProto(read) \
  365. SymI_HasProto(rename) \
  366. SymI_HasProto(rmdir) \
  367. SymI_HasProto(select) \
  368. SymI_HasProto(system) \
  369. SymI_HasProto(write) \
  370. SymI_HasProto(strcmp) \
  371. SymI_HasProto(strcpy) \
  372. SymI_HasProto(strncpy) \
  373. SymI_HasProto(strerror) \
  374. SymI_HasProto(sigaddset) \
  375. SymI_HasProto(sigemptyset) \
  376. SymI_HasProto(sigprocmask) \
  377. SymI_HasProto(umask) \
  378. SymI_HasProto(uname) \
  379. SymI_HasProto(unlink) \
  380. SymI_HasProto(utime) \
  381. SymI_HasProto(waitpid)
  382. #elif defined(mingw32_HOST_OS)
  383. #define RTS_POSIX_ONLY_SYMBOLS /**/
  384. #define RTS_CYGWIN_ONLY_SYMBOLS /**/
  385. #if HAVE_GETTIMEOFDAY
  386. #define RTS_MINGW_GETTIMEOFDAY_SYM SymI_NeedsProto(gettimeofday)
  387. #else
  388. #define RTS_MINGW_GETTIMEOFDAY_SYM /**/
  389. #endif
  390. #if HAVE___MINGW_VFPRINTF
  391. #define RTS___MINGW_VFPRINTF_SYM SymI_HasProto(__mingw_vfprintf)
  392. #else
  393. #define RTS___MINGW_VFPRINTF_SYM /**/
  394. #endif
  395. #if defined(i386_HOST_ARCH)
  396. #define RTS_WIN32_ONLY(X) X
  397. #else
  398. #define RTS_WIN32_ONLY(X) /**/
  399. #endif
  400. #if defined(x86_64_HOST_ARCH)
  401. #define RTS_WIN64_ONLY(X) X
  402. #else
  403. #define RTS_WIN64_ONLY(X) /**/
  404. #endif
  405. /* These are statically linked from the mingw libraries into the ghc
  406. executable, so we have to employ this hack. */
  407. #define RTS_MINGW_ONLY_SYMBOLS \
  408. SymI_HasProto(stg_asyncReadzh) \
  409. SymI_HasProto(stg_asyncWritezh) \
  410. SymI_HasProto(stg_asyncDoProczh) \
  411. SymI_HasProto(getWin32ProgArgv) \
  412. SymI_HasProto(setWin32ProgArgv) \
  413. SymI_HasProto(memset) \
  414. SymI_HasProto(inet_ntoa) \
  415. SymI_HasProto(inet_addr) \
  416. SymI_HasProto(htonl) \
  417. SymI_HasProto(recvfrom) \
  418. SymI_HasProto(listen) \
  419. SymI_HasProto(bind) \
  420. SymI_HasProto(shutdown) \
  421. SymI_HasProto(connect) \
  422. SymI_HasProto(htons) \
  423. SymI_HasProto(ntohs) \
  424. SymI_HasProto(getservbyname) \
  425. SymI_HasProto(getservbyport) \
  426. SymI_HasProto(getprotobynumber) \
  427. SymI_HasProto(getprotobyname) \
  428. SymI_HasProto(gethostbyname) \
  429. SymI_HasProto(gethostbyaddr) \
  430. SymI_HasProto(gethostname) \
  431. SymI_HasProto(strcpy) \
  432. SymI_HasProto(strncpy) \
  433. SymI_HasProto(abort) \
  434. RTS_WIN32_ONLY(SymI_NeedsProto(_alloca)) \
  435. SymI_HasProto(isxdigit) \
  436. SymI_HasProto(isupper) \
  437. SymI_HasProto(ispunct) \
  438. SymI_HasProto(islower) \
  439. SymI_HasProto(isspace) \
  440. SymI_HasProto(isprint) \
  441. SymI_HasProto(isdigit) \
  442. SymI_HasProto(iscntrl) \
  443. SymI_HasProto(isalpha) \
  444. SymI_HasProto(isalnum) \
  445. SymI_HasProto(isascii) \
  446. RTS___MINGW_VFPRINTF_SYM \
  447. SymI_HasProto(strcmp) \
  448. SymI_HasProto(memmove) \
  449. SymI_HasProto(realloc) \
  450. SymI_HasProto(malloc) \
  451. SymI_HasProto(pow) \
  452. SymI_HasProto(tanh) \
  453. SymI_HasProto(cosh) \
  454. SymI_HasProto(sinh) \
  455. SymI_HasProto(atan) \
  456. SymI_HasProto(acos) \
  457. SymI_HasProto(asin) \
  458. SymI_HasProto(tan) \
  459. SymI_HasProto(cos) \
  460. SymI_HasProto(sin) \
  461. SymI_HasProto(exp) \
  462. SymI_HasProto(log) \
  463. SymI_HasProto(sqrt) \
  464. SymI_HasProto(powf) \
  465. SymI_HasProto(tanhf) \
  466. SymI_HasProto(coshf) \
  467. SymI_HasProto(sinhf) \
  468. SymI_HasProto(atanf) \
  469. SymI_HasProto(acosf) \
  470. SymI_HasProto(asinf) \
  471. SymI_HasProto(tanf) \
  472. SymI_HasProto(cosf) \
  473. SymI_HasProto(sinf) \
  474. SymI_HasProto(expf) \
  475. SymI_HasProto(logf) \
  476. SymI_HasProto(sqrtf) \
  477. SymI_HasProto(erf) \
  478. SymI_HasProto(erfc) \
  479. SymI_HasProto(erff) \
  480. SymI_HasProto(erfcf) \
  481. SymI_HasProto(memcpy) \
  482. SymI_HasProto(rts_InstallConsoleEvent) \
  483. SymI_HasProto(rts_ConsoleHandlerDone) \
  484. SymI_NeedsProto(mktime) \
  485. RTS_WIN32_ONLY(SymI_NeedsProto(_imp___timezone)) \
  486. RTS_WIN32_ONLY(SymI_NeedsProto(_imp___tzname)) \
  487. RTS_WIN32_ONLY(SymI_NeedsProto(_imp__tzname)) \
  488. RTS_WIN32_ONLY(SymI_NeedsProto(_imp___iob)) \
  489. RTS_WIN32_ONLY(SymI_NeedsProto(_imp___osver)) \
  490. SymI_NeedsProto(localtime) \
  491. SymI_NeedsProto(gmtime) \
  492. SymI_NeedsProto(opendir) \
  493. SymI_NeedsProto(readdir) \
  494. SymI_NeedsProto(rewinddir) \
  495. RTS_WIN32_ONLY(SymI_NeedsProto(_imp____mb_cur_max)) \
  496. RTS_WIN32_ONLY(SymI_NeedsProto(_imp___pctype)) \
  497. RTS_WIN32_ONLY(SymI_NeedsProto(__chkstk)) \
  498. RTS_WIN64_ONLY(SymI_NeedsProto(__imp___iob_func)) \
  499. RTS_WIN64_ONLY(SymI_NeedsProto(___chkstk_ms)) \
  500. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_localeconv)) \
  501. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_islower)) \
  502. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_isspace)) \
  503. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_isxdigit)) \
  504. RTS_WIN64_ONLY(SymI_HasProto(close)) \
  505. RTS_WIN64_ONLY(SymI_HasProto(read)) \
  506. RTS_WIN64_ONLY(SymI_HasProto(dup)) \
  507. RTS_WIN64_ONLY(SymI_HasProto(dup2)) \
  508. RTS_WIN64_ONLY(SymI_HasProto(write)) \
  509. SymI_NeedsProto(getpid) \
  510. RTS_WIN64_ONLY(SymI_HasProto(access)) \
  511. SymI_HasProto(chmod) \
  512. RTS_WIN64_ONLY(SymI_HasProto(creat)) \
  513. RTS_WIN64_ONLY(SymI_HasProto(umask)) \
  514. SymI_HasProto(unlink) \
  515. RTS_WIN64_ONLY(SymI_NeedsProto(__imp__errno)) \
  516. RTS_WIN64_ONLY(SymI_NeedsProto(ftruncate64)) \
  517. RTS_WIN64_ONLY(SymI_HasProto(setmode)) \
  518. RTS_WIN64_ONLY(SymI_NeedsProto(__imp__wstat64)) \
  519. RTS_WIN64_ONLY(SymI_NeedsProto(__imp__fstat64)) \
  520. RTS_WIN64_ONLY(SymI_NeedsProto(__imp__wsopen)) \
  521. RTS_WIN64_ONLY(SymI_HasProto(__imp__environ)) \
  522. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetFileAttributesA)) \
  523. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetFileInformationByHandle)) \
  524. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetFileType)) \
  525. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetLastError)) \
  526. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_QueryPerformanceFrequency)) \
  527. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_QueryPerformanceCounter)) \
  528. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetTickCount)) \
  529. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_WaitForSingleObject)) \
  530. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_PeekConsoleInputA)) \
  531. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_ReadConsoleInputA)) \
  532. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_PeekNamedPipe)) \
  533. RTS_WIN64_ONLY(SymI_NeedsProto(__imp__isatty)) \
  534. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_select)) \
  535. RTS_WIN64_ONLY(SymI_HasProto(isatty)) \
  536. RTS_WIN64_ONLY(SymI_NeedsProto(__imp__get_osfhandle)) \
  537. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetConsoleMode)) \
  538. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_SetConsoleMode)) \
  539. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_FlushConsoleInputBuffer)) \
  540. RTS_WIN64_ONLY(SymI_HasProto(free)) \
  541. RTS_WIN64_ONLY(SymI_NeedsProto(raise)) \
  542. RTS_WIN64_ONLY(SymI_NeedsProto(_getpid)) \
  543. RTS_WIN64_ONLY(SymI_HasProto(getc)) \
  544. RTS_WIN64_ONLY(SymI_HasProto(ungetc)) \
  545. RTS_WIN64_ONLY(SymI_HasProto(puts)) \
  546. RTS_WIN64_ONLY(SymI_HasProto(putc)) \
  547. RTS_WIN64_ONLY(SymI_HasProto(putchar)) \
  548. RTS_WIN64_ONLY(SymI_HasProto(fputc)) \
  549. RTS_WIN64_ONLY(SymI_HasProto(fread)) \
  550. RTS_WIN64_ONLY(SymI_HasProto(fwrite)) \
  551. RTS_WIN64_ONLY(SymI_HasProto(ferror)) \
  552. RTS_WIN64_ONLY(SymI_HasProto(printf)) \
  553. RTS_WIN64_ONLY(SymI_HasProto(fprintf)) \
  554. RTS_WIN64_ONLY(SymI_HasProto(sprintf)) \
  555. RTS_WIN64_ONLY(SymI_HasProto(vsprintf)) \
  556. RTS_WIN64_ONLY(SymI_HasProto(sscanf)) \
  557. RTS_WIN64_ONLY(SymI_HasProto(ldexp)) \
  558. RTS_WIN64_ONLY(SymI_HasProto(strlen)) \
  559. RTS_WIN64_ONLY(SymI_HasProto(strnlen)) \
  560. RTS_WIN64_ONLY(SymI_HasProto(strchr)) \
  561. RTS_WIN64_ONLY(SymI_HasProto(strtol)) \
  562. RTS_WIN64_ONLY(SymI_HasProto(strerror)) \
  563. RTS_WIN64_ONLY(SymI_HasProto(memchr)) \
  564. RTS_WIN64_ONLY(SymI_HasProto(memcmp)) \
  565. RTS_WIN64_ONLY(SymI_HasProto(wcscpy)) \
  566. RTS_WIN64_ONLY(SymI_HasProto(wcslen)) \
  567. RTS_WIN64_ONLY(SymI_HasProto(_lseeki64)) \
  568. RTS_WIN64_ONLY(SymI_HasProto(_wchmod)) \
  569. RTS_WIN64_ONLY(SymI_HasProto(closesocket)) \
  570. RTS_WIN64_ONLY(SymI_HasProto(send)) \
  571. RTS_WIN64_ONLY(SymI_HasProto(recv)) \
  572. RTS_WIN64_ONLY(SymI_HasProto(bsearch)) \
  573. RTS_WIN64_ONLY(SymI_HasProto(CommandLineToArgvW)) \
  574. RTS_WIN64_ONLY(SymI_HasProto(CreateBitmap)) \
  575. RTS_WIN64_ONLY(SymI_HasProto(CreateBitmapIndirect)) \
  576. RTS_WIN64_ONLY(SymI_HasProto(CreateCompatibleBitmap)) \
  577. RTS_WIN64_ONLY(SymI_HasProto(CreateDIBPatternBrushPt)) \
  578. RTS_WIN64_ONLY(SymI_HasProto(CreateDIBitmap)) \
  579. RTS_WIN64_ONLY(SymI_HasProto(SetBitmapDimensionEx)) \
  580. RTS_WIN64_ONLY(SymI_HasProto(GetBitmapDimensionEx)) \
  581. RTS_WIN64_ONLY(SymI_HasProto(GetStockObject)) \
  582. RTS_WIN64_ONLY(SymI_HasProto(GetObjectW)) \
  583. RTS_WIN64_ONLY(SymI_HasProto(DeleteObject)) \
  584. RTS_WIN64_ONLY(SymI_HasProto(SetDIBits)) \
  585. RTS_WIN64_ONLY(SymI_HasProto(GetDIBits)) \
  586. RTS_WIN64_ONLY(SymI_HasProto(CreateSolidBrush)) \
  587. RTS_WIN64_ONLY(SymI_HasProto(CreateHatchBrush)) \
  588. RTS_WIN64_ONLY(SymI_HasProto(CreatePatternBrush)) \
  589. RTS_WIN64_ONLY(SymI_HasProto(CreateFontW)) \
  590. RTS_WIN64_ONLY(SymI_HasProto(AngleArc)) \
  591. RTS_WIN64_ONLY(SymI_HasProto(Arc)) \
  592. RTS_WIN64_ONLY(SymI_HasProto(ArcTo)) \
  593. RTS_WIN64_ONLY(SymI_HasProto(BeginPath)) \
  594. RTS_WIN64_ONLY(SymI_HasProto(BitBlt)) \
  595. RTS_WIN64_ONLY(SymI_HasProto(CancelDC)) \
  596. RTS_WIN64_ONLY(SymI_HasProto(Chord)) \
  597. RTS_WIN64_ONLY(SymI_HasProto(CloseFigure)) \
  598. RTS_WIN64_ONLY(SymI_HasProto(CombineRgn)) \
  599. RTS_WIN64_ONLY(SymI_HasProto(CreateCompatibleDC)) \
  600. RTS_WIN64_ONLY(SymI_HasProto(CreateEllipticRgn)) \
  601. RTS_WIN64_ONLY(SymI_HasProto(CreateEllipticRgnIndirect)) \
  602. RTS_WIN64_ONLY(SymI_HasProto(CreatePen)) \
  603. RTS_WIN64_ONLY(SymI_HasProto(CreatePolygonRgn)) \
  604. RTS_WIN64_ONLY(SymI_HasProto(CreateRectRgn)) \
  605. RTS_WIN64_ONLY(SymI_HasProto(CreateRectRgnIndirect)) \
  606. RTS_WIN64_ONLY(SymI_HasProto(CreateRoundRectRgn)) \
  607. RTS_WIN64_ONLY(SymI_HasProto(DeleteDC)) \
  608. RTS_WIN64_ONLY(SymI_HasProto(Ellipse)) \
  609. RTS_WIN64_ONLY(SymI_HasProto(EndPath)) \
  610. RTS_WIN64_ONLY(SymI_HasProto(EqualRgn)) \
  611. RTS_WIN64_ONLY(SymI_HasProto(ExtSelectClipRgn)) \
  612. RTS_WIN64_ONLY(SymI_HasProto(FillPath)) \
  613. RTS_WIN64_ONLY(SymI_HasProto(FillRgn)) \
  614. RTS_WIN64_ONLY(SymI_HasProto(FlattenPath)) \
  615. RTS_WIN64_ONLY(SymI_HasProto(FrameRgn)) \
  616. RTS_WIN64_ONLY(SymI_HasProto(GetArcDirection)) \
  617. RTS_WIN64_ONLY(SymI_HasProto(GetBkColor)) \
  618. RTS_WIN64_ONLY(SymI_HasProto(GetBkMode)) \
  619. RTS_WIN64_ONLY(SymI_HasProto(GetBrushOrgEx)) \
  620. RTS_WIN64_ONLY(SymI_HasProto(GetCurrentObject)) \
  621. RTS_WIN64_ONLY(SymI_HasProto(GetDCOrgEx)) \
  622. RTS_WIN64_ONLY(SymI_HasProto(GetGraphicsMode)) \
  623. RTS_WIN64_ONLY(SymI_HasProto(GetMiterLimit)) \
  624. RTS_WIN64_ONLY(SymI_HasProto(GetPolyFillMode)) \
  625. RTS_WIN64_ONLY(SymI_HasProto(GetRgnBox)) \
  626. RTS_WIN64_ONLY(SymI_HasProto(GetStretchBltMode)) \
  627. RTS_WIN64_ONLY(SymI_HasProto(GetTextAlign)) \
  628. RTS_WIN64_ONLY(SymI_HasProto(GetTextCharacterExtra)) \
  629. RTS_WIN64_ONLY(SymI_HasProto(GetTextColor)) \
  630. RTS_WIN64_ONLY(SymI_HasProto(GetTextExtentPoint32W)) \
  631. RTS_WIN64_ONLY(SymI_HasProto(InvertRgn)) \
  632. RTS_WIN64_ONLY(SymI_HasProto(LineTo)) \
  633. RTS_WIN64_ONLY(SymI_HasProto(MaskBlt)) \
  634. RTS_WIN64_ONLY(SymI_HasProto(MoveToEx)) \
  635. RTS_WIN64_ONLY(SymI_HasProto(OffsetRgn)) \
  636. RTS_WIN64_ONLY(SymI_HasProto(PaintRgn)) \
  637. RTS_WIN64_ONLY(SymI_HasProto(PathToRegion)) \
  638. RTS_WIN64_ONLY(SymI_HasProto(Pie)) \
  639. RTS_WIN64_ONLY(SymI_HasProto(PlgBlt)) \
  640. RTS_WIN64_ONLY(SymI_HasProto(PolyBezier)) \
  641. RTS_WIN64_ONLY(SymI_HasProto(PolyBezierTo)) \
  642. RTS_WIN64_ONLY(SymI_HasProto(Polygon)) \
  643. RTS_WIN64_ONLY(SymI_HasProto(Polyline)) \
  644. RTS_WIN64_ONLY(SymI_HasProto(PolylineTo)) \
  645. RTS_WIN64_ONLY(SymI_HasProto(PtInRegion)) \
  646. RTS_WIN64_ONLY(SymI_HasProto(Rectangle)) \
  647. RTS_WIN64_ONLY(SymI_HasProto(RectInRegion)) \
  648. RTS_WIN64_ONLY(SymI_HasProto(RestoreDC)) \
  649. RTS_WIN64_ONLY(SymI_HasProto(RoundRect)) \
  650. RTS_WIN64_ONLY(SymI_HasProto(SaveDC)) \
  651. RTS_WIN64_ONLY(SymI_HasProto(SelectClipPath)) \
  652. RTS_WIN64_ONLY(SymI_HasProto(SelectClipRgn)) \
  653. RTS_WIN64_ONLY(SymI_HasProto(SelectObject)) \
  654. RTS_WIN64_ONLY(SymI_HasProto(SelectPalette)) \
  655. RTS_WIN64_ONLY(SymI_HasProto(SetArcDirection)) \
  656. RTS_WIN64_ONLY(SymI_HasProto(SetBkColor)) \
  657. RTS_WIN64_ONLY(SymI_HasProto(SetBkMode)) \
  658. RTS_WIN64_ONLY(SymI_HasProto(SetBrushOrgEx)) \
  659. RTS_WIN64_ONLY(SymI_HasProto(SetGraphicsMode)) \
  660. RTS_WIN64_ONLY(SymI_HasProto(SetMiterLimit)) \
  661. RTS_WIN64_ONLY(SymI_HasProto(SetPolyFillMode)) \
  662. RTS_WIN64_ONLY(SymI_HasProto(SetStretchBltMode)) \
  663. RTS_WIN64_ONLY(SymI_HasProto(SetTextAlign)) \
  664. RTS_WIN64_ONLY(SymI_HasProto(SetTextCharacterExtra)) \
  665. RTS_WIN64_ONLY(SymI_HasProto(SetTextColor)) \
  666. RTS_WIN64_ONLY(SymI_HasProto(StretchBlt)) \
  667. RTS_WIN64_ONLY(SymI_HasProto(StrokeAndFillPath)) \
  668. RTS_WIN64_ONLY(SymI_HasProto(StrokePath)) \
  669. RTS_WIN64_ONLY(SymI_HasProto(TextOutW)) \
  670. RTS_WIN64_ONLY(SymI_HasProto(timeGetTime)) \
  671. RTS_WIN64_ONLY(SymI_HasProto(WidenPath)) \
  672. RTS_WIN64_ONLY(SymI_HasProto(GetFileSecurityW)) \
  673. RTS_WIN64_ONLY(SymI_HasProto(RegCloseKey)) \
  674. RTS_WIN64_ONLY(SymI_HasProto(RegConnectRegistryW)) \
  675. RTS_WIN64_ONLY(SymI_HasProto(RegCreateKeyExW)) \
  676. RTS_WIN64_ONLY(SymI_HasProto(RegCreateKeyW)) \
  677. RTS_WIN64_ONLY(SymI_HasProto(RegDeleteKeyW)) \
  678. RTS_WIN64_ONLY(SymI_HasProto(RegDeleteValueW)) \
  679. RTS_WIN64_ONLY(SymI_HasProto(RegEnumKeyW)) \
  680. RTS_WIN64_ONLY(SymI_HasProto(RegEnumValueW)) \
  681. RTS_WIN64_ONLY(SymI_HasProto(RegFlushKey)) \
  682. RTS_WIN64_ONLY(SymI_HasProto(RegLoadKeyW)) \
  683. RTS_WIN64_ONLY(SymI_HasProto(RegNotifyChangeKeyValue)) \
  684. RTS_WIN64_ONLY(SymI_HasProto(RegOpenKeyExW)) \
  685. RTS_WIN64_ONLY(SymI_HasProto(RegOpenKeyW)) \
  686. RTS_WIN64_ONLY(SymI_HasProto(RegQueryInfoKeyW)) \
  687. RTS_WIN64_ONLY(SymI_HasProto(RegQueryValueExW)) \
  688. RTS_WIN64_ONLY(SymI_HasProto(RegQueryValueW)) \
  689. RTS_WIN64_ONLY(SymI_HasProto(RegReplaceKeyW)) \
  690. RTS_WIN64_ONLY(SymI_HasProto(RegRestoreKeyW)) \
  691. RTS_WIN64_ONLY(SymI_HasProto(RegSaveKeyW)) \
  692. RTS_WIN64_ONLY(SymI_HasProto(RegSetValueExW)) \
  693. RTS_WIN64_ONLY(SymI_HasProto(RegSetValueW)) \
  694. RTS_WIN64_ONLY(SymI_HasProto(RegUnLoadKeyW)) \
  695. RTS_WIN64_ONLY(SymI_NeedsProto(SHGetFolderPathW)) \
  696. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_SetWindowLongPtrW)) \
  697. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetWindowLongPtrW)) \
  698. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_MenuItemFromPoint)) \
  699. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_ChildWindowFromPoint)) \
  700. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_ChildWindowFromPointEx)) \
  701. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_DeleteObject)) \
  702. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_UnmapViewOfFile)) \
  703. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_CloseHandle)) \
  704. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_FreeLibrary)) \
  705. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetMessageW)) \
  706. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_TranslateMessage)) \
  707. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_DispatchMessageW)) \
  708. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_DefWindowProcW)) \
  709. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetDIBits)) \
  710. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GlobalAlloc)) \
  711. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GlobalFree)) \
  712. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_CreateFileW)) \
  713. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_WriteFile)) \
  714. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_CreateCompatibleBitmap)) \
  715. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_SelectObject)) \
  716. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_Polygon)) \
  717. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_FormatMessageW)) \
  718. RTS_WIN64_ONLY(SymI_NeedsProto(__imp__localtime64)) \
  719. RTS_WIN64_ONLY(SymI_NeedsProto(__imp__tzname)) \
  720. RTS_WIN64_ONLY(SymI_NeedsProto(__imp__timezone)) \
  721. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_CreatePipe)) \
  722. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_SetHandleInformation)) \
  723. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetStdHandle)) \
  724. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetCurrentProcess)) \
  725. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_DuplicateHandle)) \
  726. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_CreateProcessW)) \
  727. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_TerminateProcess)) \
  728. RTS_WIN64_ONLY(SymI_NeedsProto(__imp__open_osfhandle)) \
  729. RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetExitCodeProcess)) \
  730. RTS_MINGW_GETTIMEOFDAY_SYM \
  731. SymI_NeedsProto(closedir)
  732. #else
  733. #define RTS_MINGW_ONLY_SYMBOLS /**/
  734. #define RTS_CYGWIN_ONLY_SYMBOLS /**/
  735. #endif
  736. #if defined(darwin_HOST_OS) && HAVE_PRINTF_LDBLSTUB
  737. #define RTS_DARWIN_ONLY_SYMBOLS \
  738. SymI_NeedsProto(asprintf$LDBLStub) \
  739. SymI_NeedsProto(err$LDBLStub) \
  740. SymI_NeedsProto(errc$LDBLStub) \
  741. SymI_NeedsProto(errx$LDBLStub) \
  742. SymI_NeedsProto(fprintf$LDBLStub) \
  743. SymI_NeedsProto(fscanf$LDBLStub) \
  744. SymI_NeedsProto(fwprintf$LDBLStub) \
  745. SymI_NeedsProto(fwscanf$LDBLStub) \
  746. SymI_NeedsProto(printf$LDBLStub) \
  747. SymI_NeedsProto(scanf$LDBLStub) \
  748. SymI_NeedsProto(snprintf$LDBLStub) \
  749. SymI_NeedsProto(sprintf$LDBLStub) \
  750. SymI_NeedsProto(sscanf$LDBLStub) \
  751. SymI_NeedsProto(strtold$LDBLStub) \
  752. SymI_NeedsProto(swprintf$LDBLStub) \
  753. SymI_NeedsProto(swscanf$LDBLStub) \
  754. SymI_NeedsProto(syslog$LDBLStub) \
  755. SymI_NeedsProto(vasprintf$LDBLStub) \
  756. SymI_NeedsProto(verr$LDBLStub) \
  757. SymI_NeedsProto(verrc$LDBLStub) \
  758. SymI_NeedsProto(verrx$LDBLStub) \
  759. SymI_NeedsProto(vfprintf$LDBLStub) \
  760. SymI_NeedsProto(vfscanf$LDBLStub) \
  761. SymI_NeedsProto(vfwprintf$LDBLStub) \
  762. SymI_NeedsProto(vfwscanf$LDBLStub) \
  763. SymI_NeedsProto(vprintf$LDBLStub) \
  764. SymI_NeedsProto(vscanf$LDBLStub) \
  765. SymI_NeedsProto(vsnprintf$LDBLStub) \
  766. SymI_NeedsProto(vsprintf$LDBLStub) \
  767. SymI_NeedsProto(vsscanf$LDBLStub) \
  768. SymI_NeedsProto(vswprintf$LDBLStub) \
  769. SymI_NeedsProto(vswscanf$LDBLStub) \
  770. SymI_NeedsProto(vsyslog$LDBLStub) \
  771. SymI_NeedsProto(vwarn$LDBLStub) \
  772. SymI_NeedsProto(vwarnc$LDBLStub) \
  773. SymI_NeedsProto(vwarnx$LDBLStub) \
  774. SymI_NeedsProto(vwprintf$LDBLStub) \
  775. SymI_NeedsProto(vwscanf$LDBLStub) \
  776. SymI_NeedsProto(warn$LDBLStub) \
  777. SymI_NeedsProto(warnc$LDBLStub) \
  778. SymI_NeedsProto(warnx$LDBLStub) \
  779. SymI_NeedsProto(wcstold$LDBLStub) \
  780. SymI_NeedsProto(wprintf$LDBLStub) \
  781. SymI_NeedsProto(wscanf$LDBLStub)
  782. #else
  783. #define RTS_DARWIN_ONLY_SYMBOLS
  784. #endif
  785. #ifndef SMP
  786. # define MAIN_CAP_SYM SymI_HasProto(MainCapability)
  787. #else
  788. # define MAIN_CAP_SYM
  789. #endif
  790. #if !defined(mingw32_HOST_OS)
  791. #define RTS_USER_SIGNALS_SYMBOLS \
  792. SymI_HasProto(setIOManagerControlFd) \
  793. SymI_HasProto(setIOManagerWakeupFd) \
  794. SymI_HasProto(ioManagerWakeup) \
  795. SymI_HasProto(blockUserSignals) \
  796. SymI_HasProto(unblockUserSignals)
  797. #else
  798. #define RTS_USER_SIGNALS_SYMBOLS \
  799. SymI_HasProto(ioManagerWakeup) \
  800. SymI_HasProto(sendIOManagerEvent) \
  801. SymI_HasProto(readIOManagerEvent) \
  802. SymI_HasProto(getIOManagerEvent) \
  803. SymI_HasProto(console_handler)
  804. #endif
  805. #define RTS_LIBFFI_SYMBOLS \
  806. SymE_NeedsProto(ffi_prep_cif) \
  807. SymE_NeedsProto(ffi_call) \
  808. SymE_NeedsProto(ffi_type_void) \
  809. SymE_NeedsProto(ffi_type_float) \
  810. SymE_NeedsProto(ffi_type_double) \
  811. SymE_NeedsProto(ffi_type_sint64) \
  812. SymE_NeedsProto(ffi_type_uint64) \
  813. SymE_NeedsProto(ffi_type_sint32) \
  814. SymE_NeedsProto(ffi_type_uint32) \
  815. SymE_NeedsProto(ffi_type_sint16) \
  816. SymE_NeedsProto(ffi_type_uint16) \
  817. SymE_NeedsProto(ffi_type_sint8) \
  818. SymE_NeedsProto(ffi_type_uint8) \
  819. SymE_NeedsProto(ffi_type_pointer)
  820. #ifdef TABLES_NEXT_TO_CODE
  821. #define RTS_RET_SYMBOLS /* nothing */
  822. #else
  823. #define RTS_RET_SYMBOLS \
  824. SymI_HasProto(stg_enter_ret) \
  825. SymI_HasProto(stg_gc_fun_ret) \
  826. SymI_HasProto(stg_ap_v_ret) \
  827. SymI_HasProto(stg_ap_f_ret) \
  828. SymI_HasProto(stg_ap_d_ret) \
  829. SymI_HasProto(stg_ap_l_ret) \
  830. SymI_HasProto(stg_ap_v16_ret) \
  831. SymI_HasProto(stg_ap_n_ret) \
  832. SymI_HasProto(stg_ap_p_ret) \
  833. SymI_HasProto(stg_ap_pv_ret) \
  834. SymI_HasProto(stg_ap_pp_ret) \
  835. SymI_HasProto(stg_ap_ppv_ret) \
  836. SymI_HasProto(stg_ap_ppp_ret) \
  837. SymI_HasProto(stg_ap_pppv_ret) \
  838. SymI_HasProto(stg_ap_pppp_ret) \
  839. SymI_HasProto(stg_ap_ppppp_ret) \
  840. SymI_HasProto(stg_ap_pppppp_ret)
  841. #endif
  842. /* Modules compiled with -ticky may mention ticky counters */
  843. /* This list should marry up with the one in $(TOP)/includes/stg/Ticky.h */
  844. #define RTS_TICKY_SYMBOLS \
  845. SymI_NeedsProto(ticky_entry_ctrs) \
  846. SymI_NeedsProto(top_ct) \
  847. \
  848. SymI_HasProto(ENT_VIA_NODE_ctr) \
  849. SymI_HasProto(ENT_STATIC_THK_ctr) \
  850. SymI_HasProto(ENT_DYN_THK_ctr) \
  851. SymI_HasProto(ENT_STATIC_FUN_DIRECT_ctr) \
  852. SymI_HasProto(ENT_DYN_FUN_DIRECT_ctr) \
  853. SymI_HasProto(ENT_STATIC_CON_ctr) \
  854. SymI_HasProto(ENT_DYN_CON_ctr) \
  855. SymI_HasProto(ENT_STATIC_IND_ctr) \
  856. SymI_HasProto(ENT_DYN_IND_ctr) \
  857. SymI_HasProto(ENT_PERM_IND_ctr) \
  858. SymI_HasProto(ENT_PAP_ctr) \
  859. SymI_HasProto(ENT_AP_ctr) \
  860. SymI_HasProto(ENT_AP_STACK_ctr) \
  861. SymI_HasProto(ENT_BH_ctr) \
  862. SymI_HasProto(UNKNOWN_CALL_ctr) \
  863. SymI_HasProto(SLOW_CALL_v_ctr) \
  864. SymI_HasProto(SLOW_CALL_f_ctr) \
  865. SymI_HasProto(SLOW_CALL_d_ctr) \
  866. SymI_HasProto(SLOW_CALL_l_ctr) \
  867. SymI_HasProto(SLOW_CALL_n_ctr) \
  868. SymI_HasProto(SLOW_CALL_p_ctr) \
  869. SymI_HasProto(SLOW_CALL_pv_ctr) \
  870. SymI_HasProto(SLOW_CALL_pp_ctr) \
  871. SymI_HasProto(SLOW_CALL_ppv_ctr) \
  872. SymI_HasProto(SLOW_CALL_ppp_ctr) \
  873. SymI_HasProto(SLOW_CALL_pppv_ctr) \
  874. SymI_HasProto(SLOW_CALL_pppp_ctr) \
  875. SymI_HasProto(SLOW_CALL_ppppp_ctr) \
  876. SymI_HasProto(SLOW_CALL_pppppp_ctr) \
  877. SymI_HasProto(SLOW_CALL_OTHER_ctr) \
  878. SymI_HasProto(ticky_slow_call_unevald) \
  879. SymI_HasProto(SLOW_CALL_ctr) \
  880. SymI_HasProto(MULTI_CHUNK_SLOW_CALL_ctr) \
  881. SymI_HasProto(MULTI_CHUNK_SLOW_CALL_CHUNKS_ctr) \
  882. SymI_HasProto(KNOWN_CALL_ctr) \
  883. SymI_HasProto(KNOWN_CALL_TOO_FEW_ARGS_ctr) \
  884. SymI_HasProto(KNOWN_CALL_EXTRA_ARGS_ctr) \
  885. SymI_HasProto(SLOW_CALL_FUN_TOO_FEW_ctr) \
  886. SymI_HasProto(SLOW_CALL_FUN_CORRECT_ctr) \
  887. SymI_HasProto(SLOW_CALL_FUN_TOO_MANY_ctr) \
  888. SymI_HasProto(SLOW_CALL_PAP_TOO_FEW_ctr) \
  889. SymI_HasProto(SLOW_CALL_PAP_CORRECT_ctr) \
  890. SymI_HasProto(SLOW_CALL_PAP_TOO_MANY_ctr) \
  891. SymI_HasProto(SLOW_CALL_UNEVALD_ctr) \
  892. SymI_HasProto(UPDF_OMITTED_ctr) \
  893. SymI_HasProto(UPDF_PUSHED_ctr) \
  894. SymI_HasProto(CATCHF_PUSHED_ctr) \
  895. SymI_HasProto(UPDF_RCC_PUSHED_ctr) \
  896. SymI_HasProto(UPDF_RCC_OMITTED_ctr) \
  897. SymI_HasProto(UPD_SQUEEZED_ctr) \
  898. SymI_HasProto(UPD_CON_IN_NEW_ctr) \
  899. SymI_HasProto(UPD_CON_IN_PLACE_ctr) \
  900. SymI_HasProto(UPD_PAP_IN_NEW_ctr) \
  901. SymI_HasProto(UPD_PAP_IN_PLACE_ctr) \
  902. SymI_HasProto(ALLOC_HEAP_ctr) \
  903. SymI_HasProto(ALLOC_HEAP_tot) \
  904. SymI_HasProto(ALLOC_FUN_ctr) \
  905. SymI_HasProto(ALLOC_FUN_adm) \
  906. SymI_HasProto(ALLOC_FUN_gds) \
  907. SymI_HasProto(ALLOC_FUN_slp) \
  908. SymI_HasProto(UPD_NEW_IND_ctr) \
  909. SymI_HasProto(UPD_NEW_PERM_IND_ctr) \
  910. SymI_HasProto(UPD_OLD_IND_ctr) \
  911. SymI_HasProto(UPD_OLD_PERM_IND_ctr) \
  912. SymI_HasProto(UPD_BH_UPDATABLE_ctr) \
  913. SymI_HasProto(UPD_BH_SINGLE_ENTRY_ctr) \
  914. SymI_HasProto(UPD_CAF_BH_UPDATABLE_ctr) \
  915. SymI_HasProto(UPD_CAF_BH_SINGLE_ENTRY_ctr) \
  916. SymI_HasProto(GC_SEL_ABANDONED_ctr) \
  917. SymI_HasProto(GC_SEL_MINOR_ctr) \
  918. SymI_HasProto(GC_SEL_MAJOR_ctr) \
  919. SymI_HasProto(GC_FAILED_PROMOTION_ctr) \
  920. SymI_HasProto(ALLOC_UP_THK_ctr) \
  921. SymI_HasProto(ALLOC_SE_THK_ctr) \
  922. SymI_HasProto(ALLOC_THK_adm) \
  923. SymI_HasProto(ALLOC_THK_gds) \
  924. SymI_HasProto(ALLOC_THK_slp) \
  925. SymI_HasProto(ALLOC_CON_ctr) \
  926. SymI_HasProto(ALLOC_CON_adm) \
  927. SymI_HasProto(ALLOC_CON_gds) \
  928. SymI_HasProto(ALLOC_CON_slp) \
  929. SymI_HasProto(ALLOC_TUP_ctr) \
  930. SymI_HasProto(ALLOC_TUP_adm) \
  931. SymI_HasProto(ALLOC_TUP_gds) \
  932. SymI_HasProto(ALLOC_TUP_slp) \
  933. SymI_HasProto(ALLOC_BH_ctr) \
  934. SymI_HasProto(ALLOC_BH_adm) \
  935. SymI_HasProto(ALLOC_BH_gds) \
  936. SymI_HasProto(ALLOC_BH_slp) \
  937. SymI_HasProto(ALLOC_PRIM_ctr) \
  938. SymI_HasProto(ALLOC_PRIM_adm) \
  939. SymI_HasProto(ALLOC_PRIM_gds) \
  940. SymI_HasProto(ALLOC_PRIM_slp) \
  941. SymI_HasProto(ALLOC_PAP_ctr) \
  942. SymI_HasProto(ALLOC_PAP_adm) \
  943. SymI_HasProto(ALLOC_PAP_gds) \
  944. SymI_HasProto(ALLOC_PAP_slp) \
  945. SymI_HasProto(ALLOC_TSO_ctr) \
  946. SymI_HasProto(ALLOC_TSO_adm) \
  947. SymI_HasProto(ALLOC_TSO_gds) \
  948. SymI_HasProto(ALLOC_TSO_slp) \
  949. SymI_HasProto(RET_NEW_ctr) \
  950. SymI_HasProto(RET_OLD_ctr) \
  951. SymI_HasProto(RET_UNBOXED_TUP_ctr) \
  952. SymI_HasProto(RET_SEMI_loads_avoided)
  953. // On most platforms, the garbage collector rewrites references
  954. // to small integer and char objects to a set of common, shared ones.
  955. //
  956. // We don't do this when compiling to Windows DLLs at the moment because
  957. // it doesn't support cross package data references well.
  958. //
  959. #if defined(COMPILING_WINDOWS_DLL)
  960. #define RTS_INTCHAR_SYMBOLS
  961. #else
  962. #define RTS_INTCHAR_SYMBOLS \
  963. SymI_HasProto(stg_CHARLIKE_closure) \
  964. SymI_HasProto(stg_INTLIKE_closure)
  965. #endif
  966. #define RTS_SYMBOLS \
  967. Maybe_Stable_Names \
  968. RTS_TICKY_SYMBOLS \
  969. SymI_HasProto(StgReturn) \
  970. SymI_HasProto(stg_gc_noregs) \
  971. SymI_HasProto(stg_ret_v_info) \
  972. SymI_HasProto(stg_ret_p_info) \
  973. SymI_HasProto(stg_ret_n_info) \
  974. SymI_HasProto(stg_ret_f_info) \
  975. SymI_HasProto(stg_ret_d_info) \
  976. SymI_HasProto(stg_ret_l_info) \
  977. SymI_HasProto(stg_gc_prim_p) \
  978. SymI_HasProto(stg_gc_prim_pp) \
  979. SymI_HasProto(stg_gc_prim_n) \
  980. SymI_HasProto(stg_enter_info) \
  981. SymI_HasProto(__stg_gc_enter_1) \
  982. SymI_HasProto(stg_gc_unpt_r1) \
  983. SymI_HasProto(stg_gc_unbx_r1) \
  984. SymI_HasProto(stg_gc_f1) \
  985. SymI_HasProto(stg_gc_d1) \
  986. SymI_HasProto(stg_gc_l1) \
  987. SymI_HasProto(stg_gc_pp) \
  988. SymI_HasProto(stg_gc_ppp) \
  989. SymI_HasProto(stg_gc_pppp) \
  990. SymI_HasProto(__stg_gc_fun) \
  991. SymI_HasProto(stg_gc_fun_info) \
  992. SymI_HasProto(stg_yield_noregs) \
  993. SymI_HasProto(stg_yield_to_interpreter) \
  994. SymI_HasProto(stg_block_noregs) \
  995. SymI_HasProto(stg_block_takemvar) \
  996. SymI_HasProto(stg_block_putmvar) \
  997. MAIN_CAP_SYM \
  998. SymI_HasProto(MallocFailHook) \
  999. SymI_HasProto(OnExitHook) \
  1000. SymI_HasProto(OutOfHeapHook) \
  1001. SymI_HasProto(StackOverflowHook) \
  1002. SymI_HasProto(addDLL) \
  1003. SymI_HasProto(__int_encodeDouble) \
  1004. SymI_HasProto(__word_encodeDouble) \
  1005. SymI_HasProto(__2Int_encodeDouble) \
  1006. SymI_HasProto(__int_encodeFloat) \
  1007. SymI_HasProto(__word_encodeFloat) \
  1008. SymI_HasProto(stg_atomicallyzh) \
  1009. SymI_HasProto(barf) \
  1010. SymI_HasProto(debugBelch) \
  1011. SymI_HasProto(errorBelch) \
  1012. SymI_HasProto(sysErrorBelch) \
  1013. SymI_HasProto(stg_getMaskingStatezh) \
  1014. SymI_HasProto(stg_maskAsyncExceptionszh) \
  1015. SymI_HasProto(stg_maskUninterruptiblezh) \
  1016. SymI_HasProto(stg_catchzh) \
  1017. SymI_HasProto(stg_catchRetryzh) \
  1018. SymI_HasProto(stg_catchSTMzh) \
  1019. SymI_HasProto(stg_checkzh) \
  1020. SymI_HasProto(closure_flags) \
  1021. SymI_HasProto(cmp_thread) \
  1022. SymI_HasProto(createAdjustor) \
  1023. SymI_HasProto(stg_decodeDoublezu2Intzh) \
  1024. SymI_HasProto(stg_decodeFloatzuIntzh) \
  1025. SymI_HasProto(defaultsHook) \
  1026. SymI_HasProto(stg_delayzh) \
  1027. SymI_HasProto(stg_deRefWeakzh) \
  1028. SymI_HasProto(stg_deRefStablePtrzh) \
  1029. SymI_HasProto(dirty_MUT_VAR) \
  1030. SymI_HasProto(dirty_TVAR) \
  1031. SymI_HasProto(stg_forkzh) \
  1032. SymI_HasProto(stg_forkOnzh) \
  1033. SymI_HasProto(forkProcess) \
  1034. SymI_HasProto(forkOS_createThread) \
  1035. SymI_HasProto(freeHaskellFunctionPtr) \
  1036. SymI_HasProto(getOrSetGHCConcSignalSignalHandlerStore) \
  1037. SymI_HasProto(getOrSetGHCConcWindowsPendingDelaysStore) \
  1038. SymI_HasProto(getOrSetGHCConcWindowsIOManagerThreadStore) \
  1039. SymI_HasProto(getOrSetGHCConcWindowsProddingStore) \
  1040. SymI_HasProto(getOrSetSystemEventThreadEventManagerStore) \
  1041. SymI_HasProto(getOrSetSystemEventThreadIOManagerThreadStore) \
  1042. SymI_HasProto(getOrSetSystemTimerThreadEventManagerStore) \
  1043. SymI_HasProto(getOrSetSystemTimerThreadIOManagerThreadStore) \
  1044. SymI_HasProto(getGCStats) \
  1045. SymI_HasProto(getGCStatsEnabled) \
  1046. SymI_HasProto(genSymZh) \
  1047. SymI_HasProto(genericRaise) \
  1048. SymI_HasProto(getProgArgv) \
  1049. SymI_HasProto(getFullProgArgv) \
  1050. SymI_HasProto(getStablePtr) \
  1051. SymI_HasProto(hs_init) \
  1052. SymI_HasProto(hs_exit) \
  1053. SymI_HasProto(hs_set_argv) \
  1054. SymI_HasProto(hs_add_root) \
  1055. SymI_HasProto(hs_perform_gc) \
  1056. SymI_HasProto(hs_lock_stable_tables) \
  1057. SymI_HasProto(hs_unlock_stable_tables) \
  1058. SymI_HasProto(hs_free_stable_ptr) \
  1059. SymI_HasProto(hs_free_stable_ptr_unsafe) \
  1060. SymI_HasProto(hs_free_fun_ptr) \
  1061. SymI_HasProto(hs_hpc_rootModule) \
  1062. SymI_HasProto(hs_hpc_module) \
  1063. SymI_HasProto(initLinker) \
  1064. SymI_HasProto(stg_unpackClosurezh) \
  1065. SymI_HasProto(stg_getApStackValzh) \
  1066. SymI_HasProto(stg_getSparkzh) \
  1067. SymI_HasProto(stg_numSparkszh) \
  1068. SymI_HasProto(stg_isCurrentThreadBoundzh) \
  1069. SymI_HasProto(stg_isEmptyMVarzh) \
  1070. SymI_HasProto(stg_killThreadzh) \
  1071. SymI_HasProto(loadArchive) \
  1072. SymI_HasProto(loadObj) \
  1073. SymI_HasProto(insertStableSymbol) \
  1074. SymI_HasProto(insertSymbol) \
  1075. SymI_HasProto(lookupSymbol) \
  1076. SymI_HasProto(stg_makeStablePtrzh) \
  1077. SymI_HasProto(stg_mkApUpd0zh) \
  1078. SymI_HasProto(stg_myThreadIdzh) \
  1079. SymI_HasProto(stg_labelThreadzh) \
  1080. SymI_HasProto(stg_newArrayzh) \
  1081. SymI_HasProto(stg_newArrayArrayzh) \
  1082. SymI_HasProto(stg_newBCOzh) \
  1083. SymI_HasProto(stg_newByteArrayzh) \
  1084. SymI_HasProto_redirect(newCAF, newDynCAF) \
  1085. SymI_HasProto(stg_newMVarzh) \
  1086. SymI_HasProto(stg_newMutVarzh) \
  1087. SymI_HasProto(stg_newTVarzh) \
  1088. SymI_HasProto(stg_noDuplicatezh) \
  1089. SymI_HasProto(stg_atomicModifyMutVarzh) \
  1090. SymI_HasProto(stg_casMutVarzh) \
  1091. SymI_HasProto(stg_newPinnedByteArrayzh) \
  1092. SymI_HasProto(stg_newAlignedPinnedByteArrayzh) \
  1093. SymI_HasProto(newSpark) \
  1094. SymI_HasProto(performGC) \
  1095. SymI_HasProto(performMajorGC) \
  1096. SymI_HasProto(prog_argc) \
  1097. SymI_HasProto(prog_argv) \
  1098. SymI_HasProto(stg_putMVarzh) \
  1099. SymI_HasProto(stg_raisezh) \
  1100. SymI_HasProto(stg_raiseIOzh) \
  1101. SymI_HasProto(stg_readTVarzh) \
  1102. SymI_HasProto(stg_readTVarIOzh) \
  1103. SymI_HasProto(resumeThread) \
  1104. SymI_HasProto(setNumCapabilities) \
  1105. SymI_HasProto(getNumberOfProcessors) \
  1106. SymI_HasProto(resolveObjs) \
  1107. SymI_HasProto(stg_retryzh) \
  1108. SymI_HasProto(rts_apply) \
  1109. SymI_HasProto(rts_checkSchedStatus) \
  1110. SymI_HasProto(rts_eval) \
  1111. SymI_HasProto(rts_evalIO) \
  1112. SymI_HasProto(rts_evalLazyIO) \
  1113. SymI_HasProto(rts_evalStableIO) \
  1114. SymI_HasProto(rts_eval_) \
  1115. SymI_HasProto(rts_getBool) \
  1116. SymI_HasProto(rts_getChar) \
  1117. SymI_HasProto(rts_getDouble) \
  1118. SymI_HasProto(rts_getFloat) \
  1119. SymI_HasProto(rts_getInt) \
  1120. SymI_HasProto(rts_getInt8) \
  1121. SymI_HasProto(rts_getInt16) \
  1122. SymI_HasProto(rts_getInt32) \
  1123. SymI_HasProto(rts_getInt64) \
  1124. SymI_HasProto(rts_getPtr) \
  1125. SymI_HasProto(rts_getFunPtr) \
  1126. SymI_HasProto(rts_getStablePtr) \
  1127. SymI_HasProto(rts_getThreadId) \
  1128. SymI_HasProto(rts_getWord) \
  1129. SymI_HasProto(rts_getWord8) \
  1130. SymI_HasProto(rts_getWord16) \
  1131. SymI_HasProto(rts_getWord32) \
  1132. SymI_HasProto(rts_getWord64) \
  1133. SymI_HasProto(rts_lock) \
  1134. SymI_HasProto(rts_mkBool) \
  1135. SymI_HasProto(rts_mkChar) \
  1136. SymI_HasProto(rts_mkDouble) \
  1137. SymI_HasProto(rts_mkFloat) \
  1138. SymI_HasProto(rts_mkInt) \
  1139. SymI_HasProto(rts_mkInt8) \
  1140. SymI_HasProto(rts_mkInt16) \
  1141. SymI_HasProto(rts_mkInt32) \
  1142. SymI_HasProto(rts_mkInt64) \
  1143. SymI_HasProto(rts_mkPtr) \
  1144. SymI_HasProto(rts_mkFunPtr) \
  1145. SymI_HasProto(rts_mkStablePtr) \
  1146. SymI_HasProto(rts_mkString) \
  1147. SymI_HasProto(rts_mkWord) \
  1148. SymI_HasProto(rts_mkWord8) \
  1149. SymI_HasProto(rts_mkWord16) \
  1150. SymI_HasProto(rts_mkWord32) \
  1151. SymI_HasProto(rts_mkWord64) \
  1152. SymI_HasProto(rts_unlock) \
  1153. SymI_HasProto(rts_unsafeGetMyCapability) \
  1154. SymI_HasProto(rtsSupportsBoundThreads) \
  1155. SymI_HasProto(rts_isProfiled) \
  1156. SymI_HasProto(setProgArgv) \
  1157. SymI_HasProto(startupHaskell) \
  1158. SymI_HasProto(shutdownHaskell) \
  1159. SymI_HasProto(shutdownHaskellAndExit) \
  1160. SymI_HasProto(stable_name_table) \
  1161. SymI_HasProto(stable_ptr_table) \
  1162. SymI_HasProto(stackOverflow) \
  1163. SymI_HasProto(stg_CAF_BLACKHOLE_info) \
  1164. SymI_HasProto(stg_BLACKHOLE_info) \
  1165. SymI_HasProto(__stg_EAGER_BLACKHOLE_info) \
  1166. SymI_HasProto(stg_BLOCKING_QUEUE_CLEAN_info) \
  1167. SymI_HasProto(stg_BLOCKING_QUEUE_DIRTY_info) \
  1168. SymI_HasProto(startTimer) \
  1169. SymI_HasProto(stg_MVAR_CLEAN_info) \
  1170. SymI_HasProto(stg_MVAR_DIRTY_info) \
  1171. SymI_HasProto(stg_TVAR_CLEAN_info) \
  1172. SymI_HasProto(stg_TVAR_DIRTY_info) \
  1173. SymI_HasProto(stg_IND_STATIC_info) \
  1174. SymI_HasProto(stg_ARR_WORDS_info) \
  1175. SymI_HasProto(stg_MUT_ARR_PTRS_DIRTY_info) \
  1176. SymI_HasProto(stg_MUT_ARR_PTRS_FROZEN_info) \
  1177. SymI_HasProto(stg_MUT_ARR_PTRS_FROZEN0_info) \
  1178. SymI_HasProto(stg_WEAK_info) \
  1179. SymI_HasProto(stg_ap_v_info) \
  1180. SymI_HasProto(stg_ap_f_info) \
  1181. SymI_HasProto(stg_ap_d_info) \
  1182. SymI_HasProto(stg_ap_l_info) \
  1183. SymI_HasProto(stg_ap_v16_info) \
  1184. SymI_HasProto(stg_ap_n_info) \
  1185. SymI_HasProto(stg_ap_p_info) \
  1186. SymI_HasProto(stg_ap_pv_info) \
  1187. SymI_HasProto(stg_ap_pp_info) \
  1188. SymI_HasProto(stg_ap_ppv_info) \
  1189. SymI_HasProto(stg_ap_ppp_info) \
  1190. SymI_HasProto(stg_ap_pppv_info) \
  1191. SymI_HasProto(stg_ap_pppp_info) \
  1192. SymI_HasProto(stg_ap_ppppp_info) \
  1193. SymI_HasProto(stg_ap_pppppp_info) \
  1194. SymI_HasProto(stg_ap_0_fast) \
  1195. SymI_HasProto(stg_ap_v_fast) \
  1196. SymI_HasProto(stg_ap_f_fast) \
  1197. SymI_HasProto(stg_ap_d_fast) \
  1198. SymI_HasProto(stg_ap_l_fast) \
  1199. SymI_HasProto(stg_ap_v16_fast) \
  1200. SymI_HasProto(stg_ap_n_fast) \
  1201. SymI_HasProto(stg_ap_p_fast) \
  1202. SymI_HasProto(stg_ap_pv_fast) \
  1203. SymI_HasProto(stg_ap_pp_fast) \
  1204. SymI_HasProto(stg_ap_ppv_fast) \
  1205. SymI_HasProto(stg_ap_ppp_fast) \
  1206. SymI_HasProto(stg_ap_pppv_fast) \
  1207. SymI_HasProto(stg_ap_pppp_fast) \
  1208. SymI_HasProto(stg_ap_ppppp_fast) \
  1209. SymI_HasProto(stg_ap_pppppp_fast) \
  1210. SymI_HasProto(stg_ap_1_upd_info) \
  1211. SymI_HasProto(stg_ap_2_upd_info) \
  1212. SymI_HasProto(stg_ap_3_upd_info) \
  1213. SymI_HasProto(stg_ap_4_upd_info) \
  1214. SymI_HasProto(stg_ap_5_upd_info) \
  1215. SymI_HasProto(stg_ap_6_upd_info) \
  1216. SymI_HasProto(stg_ap_7_upd_info) \
  1217. SymI_HasProto(stg_exit) \
  1218. SymI_HasProto(stg_sel_0_upd_info) \
  1219. SymI_HasProto(stg_sel_10_upd_info) \
  1220. SymI_HasProto(stg_sel_11_upd_info) \
  1221. SymI_HasProto(stg_sel_12_upd_info) \
  1222. SymI_HasProto(stg_sel_13_upd_info) \
  1223. SymI_HasProto(stg_sel_14_upd_info) \
  1224. SymI_HasProto(stg_sel_15_upd_info) \
  1225. SymI_HasProto(stg_sel_1_upd_info) \
  1226. SymI_HasProto(stg_sel_2_upd_info) \
  1227. SymI_HasProto(stg_sel_3_upd_info) \
  1228. SymI_HasProto(stg_sel_4_upd_info) \
  1229. SymI_HasProto(stg_sel_5_upd_info) \
  1230. SymI_HasProto(stg_sel_6_upd_info) \
  1231. SymI_HasProto(stg_sel_7_upd_info) \
  1232. SymI_HasProto(stg_sel_8_upd_info) \
  1233. SymI_HasProto(stg_sel_9_upd_info) \
  1234. SymI_HasProto(stg_upd_frame_info) \
  1235. SymI_HasProto(stg_bh_upd_frame_info) \
  1236. SymI_HasProto(suspendThread) \
  1237. SymI_HasProto(stg_takeMVarzh) \
  1238. SymI_HasProto(stg_threadStatuszh) \
  1239. SymI_HasProto(stg_tryPutMVarzh) \
  1240. SymI_HasProto(stg_tryTakeMVarzh) \
  1241. SymI_HasProto(stg_unmaskAsyncExceptionszh) \
  1242. SymI_HasProto(unloadObj) \
  1243. SymI_HasProto(stg_unsafeThawArrayzh) \
  1244. SymI_HasProto(stg_waitReadzh) \
  1245. SymI_HasProto(stg_waitWritezh) \
  1246. SymI_HasProto(stg_writeTVarzh) \
  1247. SymI_HasProto(stg_yieldzh) \
  1248. SymI_NeedsProto(stg_interp_constr_entry) \
  1249. SymI_HasProto(stg_arg_bitmaps) \
  1250. SymI_HasProto(large_alloc_lim) \
  1251. SymI_HasProto(g0) \
  1252. SymI_HasProto(allocate) \
  1253. SymI_HasProto(allocateExec) \
  1254. SymI_HasProto(freeExec) \
  1255. SymI_HasProto(getAllocations) \
  1256. SymI_HasProto(revertCAFs) \
  1257. SymI_HasProto(RtsFlags) \
  1258. SymI_NeedsProto(rts_breakpoint_io_action) \
  1259. SymI_NeedsProto(rts_stop_next_breakpoint) \
  1260. SymI_NeedsProto(rts_stop_on_exception) \
  1261. SymI_HasProto(stopTimer) \
  1262. SymI_HasProto(n_capabilities) \
  1263. SymI_HasProto(enabled_capabilities) \
  1264. SymI_HasProto(stg_traceCcszh) \
  1265. SymI_HasProto(stg_traceEventzh) \
  1266. SymI_HasProto(stg_traceMarkerzh) \
  1267. SymI_HasProto(getMonotonicNSec) \
  1268. SymI_HasProto(lockFile) \
  1269. SymI_HasProto(unlockFile) \
  1270. SymI_HasProto(startProfTimer) \
  1271. SymI_HasProto(stopProfTimer) \
  1272. RTS_USER_SIGNALS_SYMBOLS \
  1273. RTS_INTCHAR_SYMBOLS
  1274. // 64-bit support functions in libgcc.a
  1275. #if defined(__GNUC__) && SIZEOF_VOID_P <= 4 && !defined(_ABIN32)
  1276. #define RTS_LIBGCC_SYMBOLS \
  1277. SymI_NeedsProto(__divdi3) \
  1278. SymI_NeedsProto(__udivdi3) \
  1279. SymI_NeedsProto(__moddi3) \
  1280. SymI_NeedsProto(__umoddi3) \
  1281. SymI_NeedsProto(__muldi3) \
  1282. SymI_NeedsProto(__ashldi3) \
  1283. SymI_NeedsProto(__ashrdi3) \
  1284. SymI_NeedsProto(__lshrdi3) \
  1285. SymI_NeedsProto(__fixunsdfdi)
  1286. #else
  1287. #define RTS_LIBGCC_SYMBOLS
  1288. #endif
  1289. #if defined(darwin_HOST_OS) && defined(powerpc_HOST_ARCH)
  1290. // Symbols that don't have a leading underscore
  1291. // on Mac OS X. They have to receive special treatment,
  1292. // see machoInitSymbolsWithoutUnderscore()
  1293. #define RTS_MACHO_NOUNDERLINE_SYMBOLS \
  1294. SymI_NeedsProto(saveFP) \
  1295. SymI_NeedsProto(restFP)
  1296. #endif
  1297. /* entirely bogus claims about types of these symbols */
  1298. #define SymI_NeedsProto(vvv) extern void vvv(void);
  1299. #if defined(COMPILING_WINDOWS_DLL)
  1300. #define SymE_HasProto(vvv) SymE_HasProto(vvv);
  1301. # if defined(x86_64_HOST_ARCH)
  1302. # define SymE_NeedsProto(vvv) extern void __imp_ ## vvv (void);
  1303. # else
  1304. # define SymE_NeedsProto(vvv) extern void _imp__ ## vvv (void);
  1305. # endif
  1306. #else
  1307. #define SymE_NeedsProto(vvv) SymI_NeedsProto(vvv);
  1308. #define SymE_HasProto(vvv) SymI_HasProto(vvv)
  1309. #endif
  1310. #define SymI_HasProto(vvv) /**/
  1311. #define SymI_HasProto_redirect(vvv,xxx) /**/
  1312. RTS_SYMBOLS
  1313. RTS_RET_SYMBOLS
  1314. RTS_POSIX_ONLY_SYMBOLS
  1315. RTS_MINGW_ONLY_SYMBOLS
  1316. RTS_CYGWIN_ONLY_SYMBOLS
  1317. RTS_DARWIN_ONLY_SYMBOLS
  1318. RTS_LIBGCC_SYMBOLS
  1319. RTS_LIBFFI_SYMBOLS
  1320. #undef SymI_NeedsProto
  1321. #undef SymI_HasProto
  1322. #undef SymI_HasProto_redirect
  1323. #undef SymE_HasProto
  1324. #undef SymE_NeedsProto
  1325. #ifdef LEADING_UNDERSCORE
  1326. #define MAYBE_LEADING_UNDERSCORE_STR(s) ("_" s)
  1327. #else
  1328. #define MAYBE_LEADING_UNDERSCORE_STR(s) (s)
  1329. #endif
  1330. #define SymI_HasProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
  1331. (void*)(&(vvv)) },
  1332. #define SymE_HasProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
  1333. (void*)DLL_IMPORT_DATA_REF(vvv) },
  1334. #define SymI_NeedsProto(vvv) SymI_HasProto(vvv)
  1335. #define SymE_NeedsProto(vvv) SymE_HasProto(vvv)
  1336. // SymI_HasProto_redirect allows us to redirect references to one symbol to
  1337. // another symbol. See newCAF/newDynCAF for an example.
  1338. #define SymI_HasProto_redirect(vvv,xxx) \
  1339. { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
  1340. (void*)(&(xxx)) },
  1341. static RtsSymbolVal rtsSyms[] = {
  1342. RTS_SYMBOLS
  1343. RTS_RET_SYMBOLS
  1344. RTS_POSIX_ONLY_SYMBOLS
  1345. RTS_MINGW_ONLY_SYMBOLS
  1346. RTS_CYGWIN_ONLY_SYMBOLS
  1347. RTS_DARWIN_ONLY_SYMBOLS
  1348. RTS_LIBGCC_SYMBOLS
  1349. RTS_LIBFFI_SYMBOLS
  1350. #if defined(darwin_HOST_OS) && defined(i386_HOST_ARCH)
  1351. // dyld stub code contains references to this,
  1352. // but it should never be called because we treat
  1353. // lazy pointers as nonlazy.
  1354. { "dyld_stub_binding_helper", (void*)0xDEADBEEF },
  1355. #endif
  1356. { 0, 0 } /* sentinel */
  1357. };
  1358. /* -----------------------------------------------------------------------------
  1359. * Insert symbols into hash tables, checking for duplicates.
  1360. */
  1361. static void ghciInsertStrHashTable ( pathchar* obj_name,
  1362. HashTable *table,
  1363. char* key,
  1364. void *data
  1365. )
  1366. {
  1367. if (lookupHashTable(table, (StgWord)key) == NULL)
  1368. {
  1369. insertStrHashTable(table, (StgWord)key, data);
  1370. return;
  1371. }
  1372. debugBelch(
  1373. "\n\n"
  1374. "GHCi runtime linker: fatal error: I found a duplicate definition for symbol\n"
  1375. " %s\n"
  1376. "whilst processing object file\n"
  1377. " %" PATH_FMT "\n"
  1378. "This could be caused by:\n"
  1379. " * Loading two different object files which export the same symbol\n"
  1380. " * Specifying the same object file twice on the GHCi command line\n"
  1381. " * An incorrect `package.conf' entry, causing some object to be\n"
  1382. " loaded twice.\n"
  1383. "GHCi cannot safely continue in this situation. Exiting now. Sorry.\n"
  1384. "\n",
  1385. (char*)key,
  1386. obj_name
  1387. );
  1388. stg_exit(1);
  1389. }
  1390. /* -----------------------------------------------------------------------------
  1391. * initialize the object linker
  1392. */
  1393. static int linker_init_done = 0 ;
  1394. #if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
  1395. static void *dl_prog_handle;
  1396. static regex_t re_invalid;
  1397. static regex_t re_realso;
  1398. #ifdef THREADED_RTS
  1399. static Mutex dl_mutex; // mutex to protect dlopen/dlerror critical section
  1400. #endif
  1401. #endif
  1402. void
  1403. initLinker( void )
  1404. {
  1405. RtsSymbolVal *sym;
  1406. #if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
  1407. int compileResult;
  1408. #endif
  1409. IF_DEBUG(linker, debugBelch("initLinker: start\n"));
  1410. /* Make initLinker idempotent, so we can call it
  1411. before every relevant operation; that means we
  1412. don't need to initialise the linker separately */
  1413. if (linker_init_done == 1) {
  1414. IF_DEBUG(linker, debugBelch("initLinker: idempotent return\n"));
  1415. return;
  1416. } else {
  1417. linker_init_done = 1;
  1418. }
  1419. #if defined(THREADED_RTS) && (defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO))
  1420. initMutex(&dl_mutex);
  1421. #endif
  1422. stablehash = allocStrHashTable();
  1423. symhash = allocStrHashTable();
  1424. /* populate the symbol table with stuff from the RTS */
  1425. for (sym = rtsSyms; sym->lbl != NULL; sym++) {
  1426. ghciInsertStrHashTable(WSTR("(GHCi built-in symbols)"),
  1427. symhash, sym->lbl, sym->addr);
  1428. IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
  1429. }
  1430. # if defined(OBJFORMAT_MACHO) && defined(powerpc_HOST_ARCH)
  1431. machoInitSymbolsWithoutUnderscore();
  1432. # endif
  1433. # if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
  1434. # if defined(RTLD_DEFAULT)
  1435. dl_prog_handle = RTLD_DEFAULT;
  1436. # else
  1437. dl_prog_handle = dlopen(NULL, RTLD_LAZY);
  1438. # endif /* RTLD_DEFAULT */
  1439. compileResult = regcomp(&re_invalid,
  1440. "(([^ \t()])+\\.so([^ \t:()])*):([ \t])*(invalid ELF header|file too short)",
  1441. REG_EXTENDED);
  1442. if (compileResult != 0) {
  1443. barf("Compiling re_invalid failed");
  1444. }
  1445. compileResult = regcomp(&re_realso,
  1446. "(GROUP|INPUT) *\\( *([^ )]+)",
  1447. REG_EXTENDED);
  1448. if (compileResult != 0) {
  1449. barf("Compiling re_realso failed");
  1450. }
  1451. # endif
  1452. #if !defined(ALWAYS_PIC) && defined(x86_64_HOST_ARCH)
  1453. if (RtsFlags.MiscFlags.linkerMemBase != 0) {
  1454. // User-override for mmap_32bit_base
  1455. mmap_32bit_base = (void*)RtsFlags.MiscFlags.linkerMemBase;
  1456. }
  1457. #endif
  1458. #if defined(mingw32_HOST_OS)
  1459. /*
  1460. * These two libraries cause problems when added to the static link,
  1461. * but are necessary for resolving symbols in GHCi, hence we load
  1462. * them manually here.
  1463. */
  1464. addDLL(WSTR("msvcrt"));
  1465. addDLL(WSTR("kernel32"));
  1466. #endif
  1467. IF_DEBUG(linker, debugBelch("initLinker: done\n"));
  1468. return;
  1469. }
  1470. void
  1471. exitLinker( void ) {
  1472. #if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
  1473. if (linker_init_done == 1) {
  1474. regfree(&re_invalid);
  1475. regfree(&re_realso);
  1476. #ifdef THREADED_RTS
  1477. closeMutex(&dl_mutex);
  1478. #endif
  1479. }
  1480. #endif
  1481. }
  1482. /* -----------------------------------------------------------------------------
  1483. * Loading DLL or .so dynamic libraries
  1484. * -----------------------------------------------------------------------------
  1485. *
  1486. * Add a DLL from which symbols may be found. In the ELF case, just
  1487. * do RTLD_GLOBAL-style add, so no further messing around needs to
  1488. * happen in order that symbols in the loaded .so are findable --
  1489. * lookupSymbol() will subsequently see them by dlsym on the program's
  1490. * dl-handle. Returns NULL if success, otherwise ptr to an err msg.
  1491. *
  1492. * In the PEi386 case, open the DLLs and put handles to them in a
  1493. * linked list. When looking for a symbol, try all handles in the
  1494. * list. This means that we need to load even DLLs that are guaranteed
  1495. * to be in the ghc.exe image already, just so we can get a handle
  1496. * to give to loadSymbol, so that we can find the symbols. For such
  1497. * libraries, the LoadLibrary call should be a no-op except for returning
  1498. * the handle.
  1499. *
  1500. */
  1501. #if defined(OBJFORMAT_PEi386)
  1502. /* A record for storing handles into DLLs. */
  1503. typedef
  1504. struct _OpenedDLL {
  1505. pathchar* name;
  1506. struct _OpenedDLL* next;
  1507. HINSTANCE instance;
  1508. }
  1509. OpenedDLL;
  1510. /* A list thereof. */
  1511. static OpenedDLL* opened_dlls = NULL;
  1512. #endif
  1513. # if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
  1514. /* Suppose in ghci we load a temporary SO for a module containing
  1515. f = 1
  1516. and then modify the module, recompile, and load another temporary
  1517. SO with
  1518. f = 2
  1519. Then as we don't unload the first SO, dlsym will find the
  1520. f = 1
  1521. symbol whereas we want the
  1522. f = 2
  1523. symbol. We therefore need to keep our own SO handle list, and
  1524. try SOs in the right order. */
  1525. typedef
  1526. struct _OpenedSO {
  1527. struct _OpenedSO* next;
  1528. void *handle;
  1529. }
  1530. OpenedSO;
  1531. /* A list thereof. */
  1532. static OpenedSO* openedSOs = NULL;
  1533. static const char *
  1534. internal_dlopen(const char *dll_name)
  1535. {
  1536. OpenedSO* o_so;
  1537. void *hdl;
  1538. const char *errmsg;
  1539. char *errmsg_copy;
  1540. // omitted: RTLD_NOW
  1541. // see http://www.haskell.org/pipermail/cvs-ghc/2007-September/038570.html
  1542. IF_DEBUG(linker,
  1543. debugBelch("internal_dlopen: dll_name = '%s'\n", dll_name));
  1544. //-------------- Begin critical section ------------------
  1545. // This critical section is necessary because dlerror() is not
  1546. // required to be reentrant (see POSIX -- IEEE Std 1003.1-2008)
  1547. // Also, the error message returned must be copied to preserve it
  1548. // (see POSIX also)
  1549. ACQUIRE_LOCK(&dl_mutex);
  1550. hdl = dlopen(dll_name, RTLD_LAZY | RTLD_GLOBAL);
  1551. errmsg = NULL;
  1552. if (hdl == NULL) {
  1553. /* dlopen failed; return a ptr to the error msg. */
  1554. errmsg = dlerror();
  1555. if (errmsg == NULL) errmsg = "addDLL: unknown error";
  1556. errmsg_copy = stgMallocBytes(strlen(errmsg)+1, "addDLL");
  1557. strcpy(errmsg_copy, errmsg);
  1558. errmsg = errmsg_copy;
  1559. }
  1560. o_so = stgMallocBytes(sizeof(OpenedSO), "addDLL");
  1561. o_so->handle = hdl;
  1562. o_so->next = openedSOs;
  1563. openedSOs = o_so;
  1564. RELEASE_LOCK(&dl_mutex);
  1565. //--------------- End critical section -------------------
  1566. return errmsg;
  1567. }
  1568. static void *
  1569. internal_dlsym(void *hdl, const char *symbol) {
  1570. OpenedSO* o_so;
  1571. void *v;
  1572. // We acquire dl_mutex as concurrent dl* calls may alter dlerror
  1573. ACQUIRE_LOCK(&dl_mutex);
  1574. dlerror();
  1575. for (o_so = openedSOs; o_so != NULL; o_so = o_so->next) {
  1576. v = dlsym(o_so->handle, symbol);
  1577. if (dlerror() == NULL) {
  1578. RELEASE_LOCK(&dl_mutex);
  1579. return v;
  1580. }
  1581. }
  1582. v = dlsym(hdl, symbol)
  1583. RELEASE_LOCK(&dl_mutex);
  1584. return v;
  1585. }
  1586. # endif
  1587. const char *
  1588. addDLL( pathchar *dll_name )
  1589. {
  1590. # if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
  1591. /* ------------------- ELF DLL loader ------------------- */
  1592. #define NMATCH 5
  1593. regmatch_t match[NMATCH];
  1594. const char *errmsg;
  1595. FILE* fp;
  1596. size_t match_length;
  1597. #define MAXLINE 1000
  1598. char line[MAXLINE];
  1599. int result;
  1600. initLinker();
  1601. IF_DEBUG(linker, debugBelch("addDLL: dll_name = '%s'\n", dll_name));
  1602. errmsg = internal_dlopen(dll_name);
  1603. if (errmsg == NULL) {
  1604. return NULL;
  1605. }
  1606. // GHC Trac ticket #2615
  1607. // On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so)
  1608. // contain linker scripts rather than ELF-format object code. This
  1609. // code handles the situation by recognizing the real object code
  1610. // file name given in the linker script.
  1611. //
  1612. // If an "invalid ELF header" error occurs, it is assumed that the
  1613. // .so file contains a linker script instead of ELF object code.
  1614. // In this case, the code looks for the GROUP ( ... ) linker
  1615. // directive. If one is found, the first file name inside the
  1616. // parentheses is treated as the name of a dynamic library and the
  1617. // code attempts to dlopen that file. If this is also unsuccessful,
  1618. // an error message is returned.
  1619. // see if the error message is due to an invalid ELF header
  1620. IF_DEBUG(linker, debugBelch("errmsg = '%s'\n", errmsg));
  1621. result = regexec(&re_invalid, errmsg, (size_t) NMATCH, match, 0);
  1622. IF_DEBUG(linker, debugBelch("result = %i\n", result));
  1623. if (result == 0) {
  1624. // success -- try to read the named file as a linker script
  1625. match_length = (size_t) stg_min((match[1].rm_eo - match[1].rm_so),
  1626. MAXLINE-1);
  1627. strncpy(line, (errmsg+(match[1].rm_so)),match_length);
  1628. line[match_length] = '\0'; // make sure string is null-terminated
  1629. IF_DEBUG(linker, debugBelch ("file name = '%s'\n", line));
  1630. if ((fp = fopen(line, "r")) == NULL) {
  1631. return errmsg; // return original error if open fails
  1632. }
  1633. // try to find a GROUP or INPUT ( ... ) command
  1634. while (fgets(line, MAXLINE, fp) != NULL) {
  1635. IF_DEBUG(linker, debugBelch("input line = %s", line));
  1636. if (regexec(&re_realso, line, (size_t) NMATCH, match, 0) == 0) {
  1637. // success -- try to dlopen the first named file
  1638. IF_DEBUG(linker, debugBelch("match%s\n",""));
  1639. line[match[2].rm_eo] = '\0';
  1640. errmsg = internal_dlopen(line+match[2].rm_so);
  1641. break;
  1642. }
  1643. // if control reaches here, no GROUP or INPUT ( ... ) directive
  1644. // was found and the original error message is returned to the
  1645. // caller
  1646. }
  1647. fclose(fp);
  1648. }
  1649. return errmsg;
  1650. # elif defined(OBJFORMAT_PEi386)
  1651. /* ------------------- Win32 DLL loader ------------------- */
  1652. pathchar* buf;
  1653. OpenedDLL* o_dll;
  1654. HINSTANCE instance;
  1655. initLinker();
  1656. /* debugBelch("\naddDLL; dll_name = `%s'\n", dll_name); */
  1657. /* See if we've already got it, and ignore if so. */
  1658. for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
  1659. if (0 == pathcmp(o_dll->name, dll_name))
  1660. return NULL;
  1661. }
  1662. /* The file name has no suffix (yet) so that we can try
  1663. both foo.dll and foo.drv
  1664. The documentation for LoadLibrary says:
  1665. If no file name extension is specified in the lpFileName
  1666. parameter, the default library extension .dll is
  1667. appended. However, the file name string can include a trailing
  1668. point character (.) to indicate that the module name has no
  1669. extension. */
  1670. buf = stgMallocBytes((pathlen(dll_name) + 10) * sizeof(wchar_t), "addDLL");
  1671. swprintf(buf, L"%s.DLL", dll_name);
  1672. instance = LoadLibraryW(buf);
  1673. if (instance == NULL) {
  1674. if (GetLastError() != ERROR_MOD_NOT_FOUND) goto error;
  1675. // KAA: allow loading of drivers (like winspool.drv)
  1676. swprintf(buf, L"%s.DRV", dll_name);
  1677. instance = LoadLibraryW(buf);
  1678. if (instance == NULL) {
  1679. if (GetLastError() != ERROR_MOD_NOT_FOUND) goto error;
  1680. // #1883: allow loading of unix-style libfoo.dll DLLs
  1681. swprintf(buf, L"lib%s.DLL", dll_name);
  1682. instance = LoadLibraryW(buf);
  1683. if (instance == NULL) {
  1684. goto error;
  1685. }
  1686. }
  1687. }
  1688. stgFree(buf);
  1689. /* Add this DLL to the list of DLLs in which to search for symbols. */
  1690. o_dll = stgMallocBytes( sizeof(OpenedDLL), "addDLL" );
  1691. o_dll->name = pathdup(dll_name);
  1692. o_dll->instance = instance;
  1693. o_dll->next = opened_dlls;
  1694. opened_dlls = o_dll;
  1695. return NULL;
  1696. error:
  1697. stgFree(buf);
  1698. sysErrorBelch("%" PATH_FMT, dll_name);
  1699. /* LoadLibrary failed; return a ptr to the error msg. */
  1700. return "addDLL: could not load DLL";
  1701. # else
  1702. barf("addDLL: not implemented on this platform");
  1703. # endif
  1704. }
  1705. /* -----------------------------------------------------------------------------
  1706. * insert a stable symbol in the hash table
  1707. */
  1708. void
  1709. insertStableSymbol(pathchar* obj_name, char* key, StgPtr p)
  1710. {
  1711. ghciInsertStrHashTable(obj_name, stablehash, key, getStablePtr(p));
  1712. }
  1713. /* -----------------------------------------------------------------------------
  1714. * insert a symbol in the hash table
  1715. */
  1716. void
  1717. insertSymbol(pathchar* obj_name, char* key, void* data)
  1718. {
  1719. ghciInsertStrHashTable(obj_name, symhash, key, data);
  1720. }
  1721. /* -----------------------------------------------------------------------------
  1722. * lookup a symbol in the hash table
  1723. */
  1724. void *
  1725. lookupSymbol( char *lbl )
  1726. {
  1727. void *val;
  1728. IF_DEBUG(linker, debugBelch("lookupSymbol: looking up %s\n", lbl));
  1729. initLinker() ;
  1730. ASSERT(symhash != NULL);
  1731. val = lookupStrHashTable(symhash, lbl);
  1732. if (val == NULL) {
  1733. IF_DEBUG(linker, debugBelch("lookupSymbol: symbol not found\n"));
  1734. # if defined(OBJFORMAT_ELF)
  1735. return internal_dlsym(dl_prog_handle, lbl);
  1736. # elif defined(OBJFORMAT_MACHO)
  1737. # if HAVE_DLFCN_H
  1738. /* On OS X 10.3 and later, we use dlsym instead of the old legacy
  1739. interface.
  1740. HACK: On OS X, all symbols are prefixed with an underscore.
  1741. However, dlsym wants us to omit the leading underscore from the
  1742. symbol name -- the dlsym routine puts it back on before searching
  1743. for the symbol. For now, we simply strip it off here (and ONLY
  1744. here).
  1745. */
  1746. IF_DEBUG(linker, debugBelch("lookupSymbol: looking up %s with dlsym\n", lbl));
  1747. ASSERT(lbl[0] == '_');
  1748. return internal_dlsym(dl_prog_handle, lbl + 1);
  1749. # else
  1750. if (NSIsSymbolNameDefined(lbl)) {
  1751. NSSymbol symbol = NSLookupAndBindSymbol(lbl);
  1752. return NSAddressOfSymbol(symbol);
  1753. } else {
  1754. return NULL;
  1755. }
  1756. # endif /* HAVE_DLFCN_H */
  1757. # elif defined(OBJFORMAT_PEi386)
  1758. void* sym;
  1759. sym = lookupSymbolInDLLs((unsigned char*)lbl);
  1760. if (sym != NULL) { return sym; };
  1761. // Also try looking up the symbol without the @N suffix. Some
  1762. // DLLs have the suffixes on their symbols, some don't.
  1763. zapTrailingAtSign ( (unsigned char*)lbl );
  1764. sym = lookupSymbolInDLLs((unsigned char*)lbl);
  1765. if (sym != NULL) { return sym; };
  1766. return NULL;
  1767. # else
  1768. ASSERT(2+2 == 5);
  1769. return NULL;
  1770. # endif
  1771. } else {
  1772. IF_DEBUG(linker, debugBelch("lookupSymbol: value of %s is %p\n", lbl, val));
  1773. return val;
  1774. }
  1775. }
  1776. /* -----------------------------------------------------------------------------
  1777. * Debugging aid: look in GHCi's object symbol tables for symbols
  1778. * within DELTA bytes of the specified address, and show their names.
  1779. */
  1780. #ifdef DEBUG
  1781. void ghci_enquire ( char* addr );
  1782. void ghci_enquire ( char* addr )
  1783. {
  1784. int i;
  1785. char* sym;
  1786. char* a;
  1787. const int DELTA = 64;
  1788. ObjectCode* oc;
  1789. initLinker();
  1790. for (oc = objects; oc; oc = oc->next) {
  1791. for (i = 0; i < oc->n_symbols; i++) {
  1792. sym = oc->symbols[i];
  1793. if (sym == NULL) continue;
  1794. a = NULL;
  1795. if (a == NULL) {
  1796. a = lookupStrHashTable(symhash, sym);
  1797. }
  1798. if (a == NULL) {
  1799. // debugBelch("ghci_enquire: can't find %s\n", sym);
  1800. }
  1801. else if (addr-DELTA <= a && a <= addr+DELTA) {
  1802. debugBelch("%p + %3d == `%s'\n", addr, (int)(a - addr), sym);
  1803. }
  1804. }
  1805. }
  1806. }
  1807. #endif
  1808. #ifdef USE_MMAP
  1809. #define ROUND_UP(x,size) ((x + size - 1) & ~(size - 1))
  1810. static void *
  1811. mmapForLinker (size_t bytes, nat flags, int fd)
  1812. {
  1813. void *map_addr = NULL;
  1814. void *result;
  1815. int pagesize, size;
  1816. static nat fixed = 0;
  1817. IF_DEBUG(linker, debugBelch("mmapForLinker: start\n"));
  1818. pagesize = getpagesize();
  1819. size = ROUND_UP(bytes, pagesize);
  1820. #if !defined(ALWAYS_PIC) && defined(x86_64_HOST_ARCH)
  1821. mmap_again:
  1822. if (mmap_32bit_base != 0) {
  1823. map_addr = mmap_32bit_base;
  1824. }
  1825. #endif
  1826. IF_DEBUG(linker, debugBelch("mmapForLinker: \tprotection %#0x\n", PROT_EXEC | PROT_READ | PROT_WRITE));
  1827. IF_DEBUG(linker, debugBelch("mmapForLinker: \tflags %#0x\n", MAP_PRIVATE | TRY_MAP_32BIT | fixed | flags));
  1828. result = mmap(map_addr, size, PROT_EXEC|PROT_READ|PROT_WRITE,
  1829. MAP_PRIVATE|TRY_MAP_32BIT|fixed|flags, fd, 0);
  1830. if (result == MAP_FAILED) {
  1831. sysErrorBelch("mmap %" FMT_Word " bytes at %p",(W_)size,map_addr);
  1832. errorBelch("Try specifying an address with +RTS -xm<addr> -RTS");
  1833. stg_exit(EXIT_FAILURE);
  1834. }
  1835. #if !defined(ALWAYS_PIC) && defined(x86_64_HOST_ARCH)
  1836. if (mmap_32bit_base != 0) {
  1837. if (result == map_addr) {
  1838. mmap_32bit_base = (StgWord8*)map_addr + size;
  1839. } else {
  1840. if ((W_)result > 0x80000000) {
  1841. // oops, we were given memory over 2Gb
  1842. #if defined(freebsd_HOST_OS) || defined(kfreebsdgnu_HOST_OS) || defined(dragonfly_HOST_OS)
  1843. // Some platforms require MAP_FIXED. This is normally
  1844. // a bad idea, because MAP_FIXED will overwrite
  1845. // existing mappings.
  1846. munmap(result,size);
  1847. fixed = MAP_FIXED;
  1848. goto mmap_again;
  1849. #else
  1850. barf("loadObj: failed to mmap() memory below 2Gb; asked for %lu bytes at %p. Try specifying an address with +RTS -xm<addr> -RTS", size, map_addr, result);
  1851. #endif
  1852. } else {
  1853. // hmm, we were given memory somewhere else, but it's
  1854. // still under 2Gb so we can use it. Next time, ask
  1855. // for memory right after the place we just got some
  1856. mmap_32bit_base = (StgWord8*)result + size;
  1857. }
  1858. }
  1859. } else {
  1860. if ((W_)result > 0x80000000) {
  1861. // oops, we were given memory over 2Gb
  1862. // ... try allocating memory somewhere else?;
  1863. debugTrace(DEBUG_linker,"MAP_32BIT didn't work; gave us %lu bytes at 0x%p", bytes, result);
  1864. munmap(result, size);
  1865. // Set a base address and try again... (guess: 1Gb)
  1866. mmap_32bit_base = (void*)0x40000000;
  1867. goto mmap_again;
  1868. }
  1869. }
  1870. #endif
  1871. IF_DEBUG(linker, debugBelch("mmapForLinker: mapped %" FMT_Word " bytes starting at %p\n", (W_)size, result));
  1872. IF_DEBUG(linker, debugBelch("mmapForLinker: done\n"));
  1873. return result;
  1874. }
  1875. #endif // USE_MMAP
  1876. static ObjectCode*
  1877. mkOc( pathchar *path, char *image, int imageSize,
  1878. char *archiveMemberName
  1879. #ifndef USE_MMAP
  1880. #ifdef darwin_HOST_OS
  1881. , int misalignment
  1882. #endif
  1883. #endif
  1884. ) {
  1885. ObjectCode* oc;
  1886. IF_DEBUG(linker, debugBelch("mkOc: start\n"));
  1887. oc = stgMallocBytes(sizeof(ObjectCode), "loadArchive(oc)");
  1888. # if defined(OBJFORMAT_ELF)
  1889. oc->formatName = "ELF";
  1890. # elif defined(OBJFORMAT_PEi386)
  1891. oc->formatName = "PEi386";
  1892. # elif defined(OBJFORMAT_MACHO)
  1893. oc->formatName = "Mach-O";
  1894. # else
  1895. stgFree(oc);
  1896. barf("loadObj: not implemented on this platform");
  1897. # endif
  1898. oc->image = image;
  1899. oc->fileName = pathdup(path);
  1900. if (archiveMemberName) {
  1901. oc->archiveMemberName = stgMallocBytes( strlen(archiveMemberName)+1, "loadObj" );
  1902. strcpy(oc->archiveMemberName, archiveMemberName);
  1903. }
  1904. else {
  1905. oc->archiveMemberName = NULL;
  1906. }
  1907. oc->fileSize = imageSize;
  1908. oc->symbols = NULL;
  1909. oc->sections = NULL;
  1910. oc->proddables = NULL;
  1911. #ifndef USE_MMAP
  1912. #ifdef darwin_HOST_OS
  1913. oc->misalignment = misalignment;
  1914. #endif
  1915. #endif
  1916. /* chain it onto the list of objects */
  1917. oc->next = objects;
  1918. objects = oc;
  1919. IF_DEBUG(linker, debugBelch("mkOc: done\n"));
  1920. return oc;
  1921. }
  1922. HsInt
  1923. loadArchive( pathchar *path )
  1924. {
  1925. ObjectCode* oc;
  1926. char *image;
  1927. int memberSize;
  1928. FILE *f;
  1929. int n;
  1930. size_t thisFileNameSize;
  1931. char *fileName;
  1932. size_t fileNameSize;
  1933. int isObject, isGnuIndex;
  1934. char tmp[20];
  1935. char *gnuFileIndex;
  1936. int gnuFileIndexSize;
  1937. #if defined(darwin_HOST_OS)
  1938. int i;
  1939. uint32_t nfat_arch, nfat_offset, cputype, cpusubtype;
  1940. #if defined(i386_HOST_ARCH)
  1941. const uint32_t mycputype = CPU_TYPE_X86;
  1942. const uint32_t mycpusubtype = CPU_SUBTYPE_X86_ALL;
  1943. #elif defined(x86_64_HOST_ARCH)
  1944. const uint32_t mycputype = CPU_TYPE_X86_64;
  1945. const uint32_t mycpusubtype = CPU_SUBTYPE_X86_64_ALL;
  1946. #elif defined(powerpc_HOST_ARCH)
  1947. const uint32_t mycputype = CPU_TYPE_POWERPC;
  1948. const uint32_t mycpusubtype = CPU_SUBTYPE_POWERPC_ALL;
  1949. #elif defined(powerpc64_HOST_ARCH)
  1950. const uint32_t mycputype = CPU_TYPE_POWERPC64;
  1951. const uint32_t mycpusubtype = CPU_SUBTYPE_POWERPC_ALL;
  1952. #else
  1953. #error Unknown Darwin architecture
  1954. #endif
  1955. #if !defined(USE_MMAP)
  1956. int misalignment;
  1957. #endif
  1958. #endif
  1959. IF_DEBUG(linker, debugBelch("loadArchive: start\n"));
  1960. IF_DEBUG(linker, debugBelch("loadArchive: Loading archive `%" PATH_FMT" '\n", path));
  1961. if (dynamicByDefault) {
  1962. barf("loadArchive called, but using dynlibs by default (%s)", path);
  1963. }
  1964. gnuFileIndex = NULL;
  1965. gnuFileIndexSize = 0;
  1966. fileNameSize = 32;
  1967. fileName = stgMallocBytes(fileNameSize, "loadArchive(fileName)");
  1968. f = pathopen(path, WSTR("rb"));
  1969. if (!f)
  1970. barf("loadObj: can't read `%s'", path);
  1971. /* Check if this is an archive by looking for the magic "!<arch>\n"
  1972. * string. Usually, if this fails, we barf and quit. On Darwin however,
  1973. * we may have a fat archive, which contains archives for more than
  1974. * one architecture. Fat archives start with the magic number 0xcafebabe,
  1975. * always stored big endian. If we find a fat_header, we scan through
  1976. * the fat_arch structs, searching through for one for our host
  1977. * architecture. If a matching struct is found, we read the offset
  1978. * of our archive data (nfat_offset) and seek forward nfat_offset bytes
  1979. * from the start of the file.
  1980. *
  1981. * A subtlety is that all of the members of the fat_header and fat_arch
  1982. * structs are stored big endian, so we need to call byte order
  1983. * conversion functions.
  1984. *
  1985. * If we find the appropriate architecture in a fat archive, we gobble
  1986. * its magic "!<arch>\n" string and continue processing just as if
  1987. * we had a single architecture archive.
  1988. */
  1989. n = fread ( tmp, 1, 8, f );
  1990. if (n != 8)
  1991. barf("loadArchive: Failed reading header from `%s'", path);
  1992. if (strncmp(tmp, "!<arch>\n", 8) != 0) {
  1993. #if defined(darwin_HOST_OS)
  1994. /* Not a standard archive, look for a fat archive magic number: */
  1995. if (ntohl(*(uint32_t *)tmp) == FAT_MAGIC) {
  1996. nfat_arch = ntohl(*(uint32_t *)(tmp + 4));
  1997. IF_DEBUG(linker, debugBelch("loadArchive: found a fat archive containing %d architectures\n", nfat_arch));
  1998. nfat_offset = 0;
  1999. for (i = 0; i < (int)nfat_arch; i++) {
  2000. /* search for the right arch */
  2001. n = fread( tmp, 1, 20, f );
  2002. if (n != 8)
  2003. barf("loadArchive: Failed reading arch from `%s'", path);
  2004. cputype = ntohl(*(uint32_t *)tmp);
  2005. cpusubtype = ntohl(*(uint32_t *)(tmp + 4));
  2006. if (cputype == mycputype && cpusubtype == mycpusubtype) {
  2007. IF_DEBUG(linker, debugBelch("loadArchive: found my archive in a fat archive\n"));
  2008. nfat_offset = ntohl(*(uint32_t *)(tmp + 8));
  2009. break;
  2010. }
  2011. }
  2012. if (nfat_offset == 0) {
  2013. barf ("loadArchive: searched %d architectures, but no host arch found", (int)nfat_arch);
  2014. }
  2015. else {
  2016. n = fseek( f, nfat_offset, SEEK_SET );
  2017. if (n != 0)
  2018. barf("loadArchive: Failed to seek to arch in `%s'", path);
  2019. n = fread ( tmp, 1, 8, f );
  2020. if (n != 8)
  2021. barf("loadArchive: Failed reading header from `%s'", path);
  2022. if (strncmp(tmp, "!<arch>\n", 8) != 0) {
  2023. barf("loadArchive: couldn't find archive in `%s' at offset %d", path, nfat_offset);
  2024. }
  2025. }
  2026. }
  2027. else {
  2028. barf("loadArchive: Neither an archive, nor a fat archive: `%s'", path);
  2029. }
  2030. #else
  2031. barf("loadArchive: Not an archive: `%s'", path);
  2032. #endif
  2033. }
  2034. IF_DEBUG(linker, debugBelch("loadArchive: loading archive contents\n"));
  2035. while(1) {
  2036. n = fread ( fileName, 1, 16, f );
  2037. if (n != 16) {
  2038. if (feof(f)) {
  2039. IF_DEBUG(linker, debugBelch("loadArchive: EOF while reading from '%" PATH_FMT "'\n", path));
  2040. break;
  2041. }
  2042. else {
  2043. barf("loadArchive: Failed reading file name from `%s'", path);
  2044. }
  2045. }
  2046. #if defined(darwin_HOST_OS)
  2047. if (strncmp(fileName, "!<arch>\n", 8) == 0) {
  2048. IF_DEBUG(linker, debugBelch("loadArchive: found the start of another archive, breaking\n"));
  2049. break;
  2050. }
  2051. #endif
  2052. n = fread ( tmp, 1, 12, f );
  2053. if (n != 12)
  2054. barf("loadArchive: Failed reading mod time from `%s'", path);
  2055. n = fread ( tmp, 1, 6, f );
  2056. if (n != 6)
  2057. barf("loadArchive: Failed reading owner from `%s'", path);
  2058. n = fread ( tmp, 1, 6, f );
  2059. if (n != 6)
  2060. barf("loadArchive: Failed reading group from `%s'", path);
  2061. n = fread ( tmp, 1, 8, f );
  2062. if (n != 8)
  2063. barf("loadArchive: Failed reading mode from `%s'", path);
  2064. n = fread ( tmp, 1, 10, f );
  2065. if (n != 10)
  2066. barf("loadArchive: Failed reading size from `%s'", path);
  2067. tmp[10] = '\0';
  2068. for (n = 0; isdigit(tmp[n]); n++);
  2069. tmp[n] = '\0';
  2070. memberSize = atoi(tmp);
  2071. IF_DEBUG(linker, debugBelch("loadArchive: size of this archive member is %d\n", memberSize));
  2072. n = fread ( tmp, 1, 2, f );
  2073. if (n != 2)
  2074. barf("loadArchive: Failed reading magic from `%s'", path);
  2075. if (strncmp(tmp, "\x60\x0A", 2) != 0)
  2076. barf("loadArchive: Failed reading magic from `%s' at %ld. Got %c%c",
  2077. path, ftell(f), tmp[0], tmp[1]);
  2078. isGnuIndex = 0;
  2079. /* Check for BSD-variant large filenames */
  2080. if (0 == strncmp(fileName, "#1/", 3)) {
  2081. fileName[16] = '\0';
  2082. if (isdigit(fileName[3])) {
  2083. for (n = 4; isdigit(fileName[n]); n++);
  2084. fileName[n] = '\0';
  2085. thisFileNameSize = atoi(fileName + 3);
  2086. memberSize -= thisFileNameSize;
  2087. if (thisFileNameSize >= fileNameSize) {
  2088. /* Double it to avoid potentially continually
  2089. increasing it by 1 */
  2090. fileNameSize = thisFileNameSize * 2;
  2091. fileName = stgReallocBytes(fileName, fileNameSize, "loadArchive(fileName)");
  2092. }
  2093. n = fread ( fileName, 1, thisFileNameSize, f );
  2094. if (n != (int)thisFileNameSize) {
  2095. barf("loadArchive: Failed reading filename from `%s'",
  2096. path);
  2097. }
  2098. fileName[thisFileNameSize] = 0;
  2099. /* On OS X at least, thisFileNameSize is the size of the
  2100. fileName field, not the length of the fileName
  2101. itself. */
  2102. thisFileNameSize = strlen(fileName);
  2103. }
  2104. else {
  2105. barf("loadArchive: BSD-variant filename size not found while reading filename from `%s'", path);
  2106. }
  2107. }
  2108. /* Check for GNU file index file */
  2109. else if (0 == strncmp(fileName, "//", 2)) {
  2110. fileName[0] = '\0';
  2111. thisFileNameSize = 0;
  2112. isGnuIndex = 1;
  2113. }
  2114. /* Check for a file in the GNU file index */
  2115. else if (fileName[0] == '/') {
  2116. if (isdigit(fileName[1])) {
  2117. int i;
  2118. for (n = 2; isdigit(fileName[n]); n++);
  2119. fileName[n] = '\0';
  2120. n = atoi(fileName + 1);
  2121. if (gnuFileIndex == NULL) {
  2122. barf("loadArchive: GNU-variant filename without an index while reading from `%s'", path);
  2123. }
  2124. if (n < 0 || n > gnuFileIndexSize) {
  2125. barf("loadArchive: GNU-variant filename offset %d out of range [0..%d] while reading filename from `%s'", n, gnuFileIndexSize, path);
  2126. }
  2127. if (n != 0 && gnuFileIndex[n - 1] != '\n') {
  2128. barf("loadArchive: GNU-variant filename offset %d invalid (range [0..%d]) while reading filename from `%s'", n, gnuFileIndexSize, path);
  2129. }
  2130. for (i = n; gnuFileIndex[i] != '/'; i++);
  2131. thisFileNameSize = i - n;
  2132. if (thisFileNameSize >= fileNameSize) {
  2133. /* Double it to avoid potentially continually
  2134. increasing it by 1 */
  2135. fileNameSize = thisFileNameSize * 2;
  2136. fileName = stgReallocBytes(fileName, fileNameSize, "loadArchive(fileName)");
  2137. }
  2138. memcpy(fileName, gnuFileIndex + n, thisFileNameSize);
  2139. fileName[thisFileNameSize] = '\0';
  2140. }
  2141. else if (fileName[1] == ' ') {
  2142. fileName[0] = '\0';
  2143. thisFileNameSize = 0;
  2144. }
  2145. else {
  2146. barf("loadArchive: GNU-variant filename offset not found while reading filename from `%s'", path);
  2147. }
  2148. }
  2149. /* Finally, the case where the filename field actually contains
  2150. the filename */
  2151. else {
  2152. /* GNU ar terminates filenames with a '/', this allowing
  2153. spaces in filenames. So first look to see if there is a
  2154. terminating '/'. */
  2155. for (thisFileNameSize = 0;
  2156. thisFileNameSize < 16;
  2157. thisFileNameSize++) {
  2158. if (fileName[thisFileNameSize] == '/') {
  2159. fileName[thisFileNameSize] = '\0';
  2160. break;
  2161. }
  2162. }
  2163. /* If we didn't find a '/', then a space teminates the
  2164. filename. Note that if we don't find one, then
  2165. thisFileNameSize ends up as 16, and we already have the
  2166. '\0' at the end. */
  2167. if (thisFileNameSize == 16) {
  2168. for (thisFileNameSize = 0;
  2169. thisFileNameSize < 16;
  2170. thisFileNameSize++) {
  2171. if (fileName[thisFileNameSize] == ' ') {
  2172. fileName[thisFileNameSize] = '\0';
  2173. break;
  2174. }
  2175. }
  2176. }
  2177. }
  2178. IF_DEBUG(linker,
  2179. debugBelch("loadArchive: Found member file `%s'\n", fileName));
  2180. isObject = thisFileNameSize >= 2
  2181. && fileName[thisFileNameSize - 2] == '.'
  2182. && fileName[thisFileNameSize - 1] == 'o';
  2183. IF_DEBUG(linker, debugBelch("loadArchive: \tthisFileNameSize = %d\n", (int)thisFileNameSize));
  2184. IF_DEBUG(linker, debugBelch("loadArchive: \tisObject = %d\n", isObject));
  2185. if (isObject) {
  2186. char *archiveMemberName;
  2187. IF_DEBUG(linker, debugBelch("loadArchive: Member is an object file...loading...\n"));
  2188. /* We can't mmap from the archive directly, as object
  2189. files need to be 8-byte aligned but files in .ar
  2190. archives are 2-byte aligned. When possible we use mmap
  2191. to get some anonymous memory, as on 64-bit platforms if
  2192. we use malloc then we can be given memory above 2^32.
  2193. In the mmap case we're probably wasting lots of space;
  2194. we could do better. */
  2195. #if defined(USE_MMAP)
  2196. image = mmapForLinker(memberSize, MAP_ANONYMOUS, -1);
  2197. #elif defined(mingw32_HOST_OS)
  2198. // TODO: We would like to use allocateExec here, but allocateExec
  2199. // cannot currently allocate blocks large enough.
  2200. {
  2201. int offset;
  2202. #if defined(x86_64_HOST_ARCH)
  2203. /* We get back 8-byte aligned memory (is that guaranteed?), but
  2204. the offsets to the sections within the file are all 4 mod 8
  2205. (is that guaranteed?). We therefore need to offset the image
  2206. by 4, so that all the pointers are 8-byte aligned, so that
  2207. pointer tagging works. */
  2208. offset = 4;
  2209. #else
  2210. offset = 0;
  2211. #endif
  2212. image = VirtualAlloc(NULL, memberSize + offset,
  2213. MEM_RESERVE | MEM_COMMIT,
  2214. PAGE_EXECUTE_READWRITE);
  2215. image += offset;
  2216. }
  2217. #elif defined(darwin_HOST_OS)
  2218. /* See loadObj() */
  2219. misalignment = machoGetMisalignment(f);
  2220. image = stgMallocBytes(memberSize + misalignment, "loadArchive(image)");
  2221. image += misalignment;
  2222. #else
  2223. image = stgMallocBytes(memberSize, "loadArchive(image)");
  2224. #endif
  2225. n = fread ( image, 1, memberSize, f );
  2226. if (n != memberSize) {
  2227. barf("loadArchive: error whilst reading `%s'", path);
  2228. }
  2229. archiveMemberName = stgMallocBytes(pathlen(path) + thisFileNameSize + 3,
  2230. "loadArchive(file)");
  2231. sprintf(archiveMemberName, "%" PATH_FMT "(%.*s)",
  2232. path, (int)thisFileNameSize, fileName);
  2233. oc = mkOc(path, image, memberSize, archiveMemberName
  2234. #ifndef USE_MMAP
  2235. #ifdef darwin_HOST_OS
  2236. , misalignment
  2237. #endif
  2238. #endif
  2239. );
  2240. stgFree(archiveMemberName);
  2241. if (0 == loadOc(oc)) {
  2242. stgFree(fileName);
  2243. return 0;
  2244. }
  2245. }
  2246. else if (isGnuIndex) {
  2247. if (gnuFileIndex != NULL) {
  2248. barf("loadArchive: GNU-variant index found, but already have an index, while reading filename from `%s'", path);
  2249. }
  2250. IF_DEBUG(linker, debugBelch("loadArchive: Found GNU-variant file index\n"));
  2251. #ifdef USE_MMAP
  2252. gnuFileIndex = mmapForLinker(memberSize + 1, MAP_ANONYMOUS, -1);
  2253. #else
  2254. gnuFileIndex = stgMallocBytes(memberSize + 1, "loadArchive(image)");
  2255. #endif
  2256. n = fread ( gnuFileIndex, 1, memberSize, f );
  2257. if (n != memberSize) {
  2258. barf("loadArchive: error whilst reading `%s'", path);
  2259. }
  2260. gnuFileIndex[memberSize] = '/';
  2261. gnuFileIndexSize = memberSize;
  2262. }
  2263. else {
  2264. IF_DEBUG(linker, debugBelch("loadArchive: '%s' does not appear to be an object file\n", fileName));
  2265. n = fseek(f, memberSize, SEEK_CUR);
  2266. if (n != 0)
  2267. barf("loadArchive: error whilst seeking by %d in `%s'",
  2268. memberSize, path);
  2269. }
  2270. /* .ar files are 2-byte aligned */
  2271. if (memberSize % 2) {
  2272. IF_DEBUG(linker, debugBelch("loadArchive: trying to read one pad byte\n"));
  2273. n = fread ( tmp, 1, 1, f );
  2274. if (n != 1) {
  2275. if (feof(f)) {
  2276. IF_DEBUG(linker, debugBelch("loadArchive: found EOF while reading one pad byte\n"));
  2277. break;
  2278. }
  2279. else {
  2280. barf("loadArchive: Failed reading padding from `%s'", path);
  2281. }
  2282. }
  2283. IF_DEBUG(linker, debugBelch("loadArchive: successfully read one pad byte\n"));
  2284. }
  2285. IF_DEBUG(linker, debugBelch("loadArchive: reached end of archive loading while loop\n"));
  2286. }
  2287. fclose(f);
  2288. stgFree(fileName);
  2289. if (gnuFileIndex != NULL) {
  2290. #ifdef USE_MMAP
  2291. munmap(gnuFileIndex, gnuFileIndexSize + 1);
  2292. #else
  2293. stgFree(gnuFileIndex);
  2294. #endif
  2295. }
  2296. IF_DEBUG(linker, debugBelch("loadArchive: done\n"));
  2297. return 1;
  2298. }
  2299. /* -----------------------------------------------------------------------------
  2300. * Load an obj (populate the global symbol table, but don't resolve yet)
  2301. *
  2302. * Returns: 1 if ok, 0 on error.
  2303. */
  2304. HsInt
  2305. loadObj( pathchar *path )
  2306. {
  2307. ObjectCode* oc;
  2308. char *image;
  2309. int fileSize;
  2310. struct_stat st;
  2311. int r;
  2312. #ifdef USE_MMAP
  2313. int fd;
  2314. #else
  2315. FILE *f;
  2316. # if defined(darwin_HOST_OS)
  2317. int misalignment;
  2318. # endif
  2319. #endif
  2320. IF_DEBUG(linker, debugBelch("loadObj %" PATH_FMT "\n", path));
  2321. if (dynamicByDefault) {
  2322. barf("loadObj called, but using dynlibs by default (%s)", path);
  2323. }
  2324. initLinker();
  2325. /* debugBelch("loadObj %s\n", path ); */
  2326. /* Check that we haven't already loaded this object.
  2327. Ignore requests to load multiple times */
  2328. {
  2329. ObjectCode *o;
  2330. int is_dup = 0;
  2331. for (o = objects; o; o = o->next) {
  2332. if (0 == pathcmp(o->fileName, path)) {
  2333. is_dup = 1;
  2334. break; /* don't need to search further */
  2335. }
  2336. }
  2337. if (is_dup) {
  2338. IF_DEBUG(linker, debugBelch(
  2339. "GHCi runtime linker: warning: looks like you're trying to load the\n"
  2340. "same object file twice:\n"
  2341. " %" PATH_FMT "\n"
  2342. "GHCi will ignore this, but be warned.\n"
  2343. , path));
  2344. return 1; /* success */
  2345. }
  2346. }
  2347. r = pathstat(path, &st);
  2348. if (r == -1) {
  2349. IF_DEBUG(linker, debugBelch("File doesn't exist\n"));
  2350. return 0;
  2351. }
  2352. fileSize = st.st_size;
  2353. #ifdef USE_MMAP
  2354. /* On many architectures malloc'd memory isn't executable, so we need to use mmap. */
  2355. #if defined(openbsd_HOST_OS)
  2356. fd = open(path, O_RDONLY, S_IRUSR);
  2357. #else
  2358. fd = open(path, O_RDONLY);
  2359. #endif
  2360. if (fd == -1)
  2361. barf("loadObj: can't open `%s'", path);
  2362. image = mmapForLinker(fileSize, 0, fd);
  2363. close(fd);
  2364. #else /* !USE_MMAP */
  2365. /* load the image into memory */
  2366. f = pathopen(path, WSTR("rb"));
  2367. if (!f)
  2368. barf("loadObj: can't read `%" PATH_FMT "'", path);
  2369. # if defined(mingw32_HOST_OS)
  2370. // TODO: We would like to use allocateExec here, but allocateExec
  2371. // cannot currently allocate blocks large enough.
  2372. {
  2373. int offset;
  2374. #if defined(x86_64_HOST_ARCH)
  2375. /* We get back 8-byte aligned memory (is that guaranteed?), but
  2376. the offsets to the sections within the file are all 4 mod 8
  2377. (is that guaranteed?). We therefore need to offset the image
  2378. by 4, so that all the pointers are 8-byte aligned, so that
  2379. pointer tagging works. */
  2380. offset = 4;
  2381. #else
  2382. offset = 0;
  2383. #endif
  2384. image = VirtualAlloc(NULL, fileSize + offset, MEM_RESERVE | MEM_COMMIT,
  2385. PAGE_EXECUTE_READWRITE);
  2386. image += offset;
  2387. }
  2388. # elif defined(darwin_HOST_OS)
  2389. // In a Mach-O .o file, all sections can and will be misaligned
  2390. // if the total size of the headers is not a multiple of the
  2391. // desired alignment. This is fine for .o files that only serve
  2392. // as input for the static linker, but it's not fine for us,
  2393. // as SSE (used by gcc for floating point) and Altivec require
  2394. // 16-byte alignment.
  2395. // We calculate the correct alignment from the header before
  2396. // reading the file, and then we misalign image on purpose so
  2397. // that the actual sections end up aligned again.
  2398. misalignment = machoGetMisalignment(f);
  2399. image = stgMallocBytes(fileSize + misalignment, "loadObj(image)");
  2400. image += misalignment;
  2401. # else
  2402. image = stgMallocBytes(fileSize, "loadObj(image)");
  2403. # endif
  2404. {
  2405. int n;
  2406. n = fread ( image, 1, fileSize, f );
  2407. if (n != fileSize)
  2408. barf("loadObj: error whilst reading `%s'", path);
  2409. }
  2410. fclose(f);
  2411. #endif /* USE_MMAP */
  2412. oc = mkOc(path, image, fileSize, NULL
  2413. #ifndef USE_MMAP
  2414. #ifdef darwin_HOST_OS
  2415. , misalignment
  2416. #endif
  2417. #endif
  2418. );
  2419. return loadOc(oc);
  2420. }
  2421. static HsInt
  2422. loadOc( ObjectCode* oc ) {
  2423. int r;
  2424. IF_DEBUG(linker, debugBelch("loadOc: start\n"));
  2425. # if defined(OBJFORMAT_MACHO) && (defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH))
  2426. r = ocAllocateSymbolExtras_MachO ( oc );
  2427. if (!r) {
  2428. IF_DEBUG(linker, debugBelch("loadOc: ocAllocateSymbolExtras_MachO failed\n"));
  2429. return r;
  2430. }
  2431. # elif defined(OBJFORMAT_ELF) && (defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH) || defined(arm_HOST_ARCH))
  2432. r = ocAllocateSymbolExtras_ELF ( oc );
  2433. if (!r) {
  2434. IF_DEBUG(linker, debugBelch("loadOc: ocAllocateSymbolExtras_ELF failed\n"));
  2435. return r;
  2436. }
  2437. #endif
  2438. /* verify the in-memory image */
  2439. # if defined(OBJFORMAT_ELF)
  2440. r = ocVerifyImage_ELF ( oc );
  2441. # elif defined(OBJFORMAT_PEi386)
  2442. r = ocVerifyImage_PEi386 ( oc );
  2443. # elif defined(OBJFORMAT_MACHO)
  2444. r = ocVerifyImage_MachO ( oc );
  2445. # else
  2446. barf("loadObj: no verify method");
  2447. # endif
  2448. if (!r) {
  2449. IF_DEBUG(linker, debugBelch("loadOc: ocVerifyImage_* failed\n"));
  2450. return r;
  2451. }
  2452. /* build the symbol list for this image */
  2453. # if defined(OBJFORMAT_ELF)
  2454. r = ocGetNames_ELF ( oc );
  2455. # elif defined(OBJFORMAT_PEi386)
  2456. r = ocGetNames_PEi386 ( oc );
  2457. # elif defined(OBJFORMAT_MACHO)
  2458. r = ocGetNames_MachO ( oc );
  2459. # else
  2460. barf("loadObj: no getNames method");
  2461. # endif
  2462. if (!r) {
  2463. IF_DEBUG(linker, debugBelch("loadOc: ocGetNames_* failed\n"));
  2464. return r;
  2465. }
  2466. /* loaded, but not resolved yet */
  2467. oc->status = OBJECT_LOADED;
  2468. IF_DEBUG(linker, debugBelch("loadOc: done.\n"));
  2469. return 1;
  2470. }
  2471. /* -----------------------------------------------------------------------------
  2472. * resolve all the currently unlinked objects in memory
  2473. *
  2474. * Returns: 1 if ok, 0 on error.
  2475. */
  2476. HsInt
  2477. resolveObjs( void )
  2478. {
  2479. ObjectCode *oc;
  2480. int r;
  2481. IF_DEBUG(linker, debugBelch("resolveObjs: start\n"));
  2482. initLinker();
  2483. for (oc = objects; oc; oc = oc->next) {
  2484. if (oc->status != OBJECT_RESOLVED) {
  2485. # if defined(OBJFORMAT_ELF)
  2486. r = ocResolve_ELF ( oc );
  2487. # elif defined(OBJFORMAT_PEi386)
  2488. r = ocResolve_PEi386 ( oc );
  2489. # elif defined(OBJFORMAT_MACHO)
  2490. r = ocResolve_MachO ( oc );
  2491. # else
  2492. barf("resolveObjs: not implemented on this platform");
  2493. # endif
  2494. if (!r) { return r; }
  2495. oc->status = OBJECT_RESOLVED;
  2496. }
  2497. }
  2498. IF_DEBUG(linker, debugBelch("resolveObjs: done\n"));
  2499. return 1;
  2500. }
  2501. /* -----------------------------------------------------------------------------
  2502. * delete an object from the pool
  2503. */
  2504. HsInt
  2505. unloadObj( pathchar *path )
  2506. {
  2507. ObjectCode *oc, *prev;
  2508. HsBool unloadedAnyObj = HS_BOOL_FALSE;
  2509. ASSERT(symhash != NULL);
  2510. ASSERT(objects != NULL);
  2511. initLinker();
  2512. prev = NULL;
  2513. for (oc = objects; oc; prev = oc, oc = oc->next) {
  2514. if (!pathcmp(oc->fileName,path)) {
  2515. /* Remove all the mappings for the symbols within this
  2516. * object..
  2517. */
  2518. {
  2519. int i;
  2520. for (i = 0; i < oc->n_symbols; i++) {
  2521. if (oc->symbols[i] != NULL) {
  2522. removeStrHashTable(symhash, oc->symbols[i], NULL);
  2523. }
  2524. }
  2525. }
  2526. if (prev == NULL) {
  2527. objects = oc->next;
  2528. } else {
  2529. prev->next = oc->next;
  2530. }
  2531. // We're going to leave this in place, in case there are
  2532. // any pointers from the heap into it:
  2533. // #ifdef mingw32_HOST_OS
  2534. // If uncommenting, note that currently oc->image is
  2535. // not the right address to free on Win64, as we added
  2536. // 4 bytes of padding at the start
  2537. // VirtualFree(oc->image);
  2538. // #else
  2539. // stgFree(oc->image);
  2540. // #endif
  2541. stgFree(oc->fileName);
  2542. stgFree(oc->archiveMemberName);
  2543. stgFree(oc->symbols);
  2544. stgFree(oc->sections);
  2545. stgFree(oc);
  2546. /* This could be a member of an archive so continue
  2547. * unloading other members. */
  2548. unloadedAnyObj = HS_BOOL_TRUE;
  2549. }
  2550. }
  2551. if (unloadedAnyObj) {
  2552. return 1;
  2553. }
  2554. else {
  2555. errorBelch("unloadObj: can't find `%" PATH_FMT "' to unload", path);
  2556. return 0;
  2557. }
  2558. }
  2559. /* -----------------------------------------------------------------------------
  2560. * Sanity checking. For each ObjectCode, maintain a list of address ranges
  2561. * which may be prodded during relocation, and abort if we try and write
  2562. * outside any of these.
  2563. */
  2564. static void
  2565. addProddableBlock ( ObjectCode* oc, void* start, int size )
  2566. {
  2567. ProddableBlock* pb
  2568. = stgMallocBytes(sizeof(ProddableBlock), "addProddableBlock");
  2569. IF_DEBUG(linker, debugBelch("addProddableBlock: %p %p %d\n", oc, start, size));
  2570. ASSERT(size > 0);
  2571. pb->start = start;
  2572. pb->size = size;
  2573. pb->next = oc->proddables;
  2574. oc->proddables = pb;
  2575. }
  2576. static void
  2577. checkProddableBlock (ObjectCode *oc, void *addr, size_t size )
  2578. {
  2579. ProddableBlock* pb;
  2580. for (pb = oc->proddables; pb != NULL; pb = pb->next) {
  2581. char* s = (char*)(pb->start);
  2582. char* e = s + pb->size;
  2583. char* a = (char*)addr;
  2584. if (a >= s && (a+size) <= e) return;
  2585. }
  2586. barf("checkProddableBlock: invalid fixup in runtime linker: %p", addr);
  2587. }
  2588. /* -----------------------------------------------------------------------------
  2589. * Section management.
  2590. */
  2591. static void
  2592. addSection ( ObjectCode* oc, SectionKind kind,
  2593. void* start, void* end )
  2594. {
  2595. Section* s = stgMallocBytes(sizeof(Section), "addSection");
  2596. s->start = start;
  2597. s->end = end;
  2598. s->kind = kind;
  2599. s->next = oc->sections;
  2600. oc->sections = s;
  2601. IF_DEBUG(linker, debugBelch("addSection: %p-%p (size %lld), kind %d\n",
  2602. start, ((char*)end)-1, ((long long)(size_t)end) - ((long long)(size_t)start) + 1, kind ));
  2603. }
  2604. /* --------------------------------------------------------------------------
  2605. * Symbol Extras.
  2606. * This is about allocating a small chunk of memory for every symbol in the
  2607. * object file. We make sure that the SymboLExtras are always "in range" of
  2608. * limited-range PC-relative instructions on various platforms by allocating
  2609. * them right next to the object code itself.
  2610. */
  2611. #if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH) || defined(arm_HOST_ARCH)
  2612. #if !defined(x86_64_HOST_ARCH) || !defined(mingw32_HOST_OS)
  2613. /*
  2614. ocAllocateSymbolExtras
  2615. Allocate additional space at the end of the object file image to make room
  2616. for jump islands (powerpc, x86_64, arm) and GOT entries (x86_64).
  2617. PowerPC relative branch instructions have a 24 bit displacement field.
  2618. As PPC code is always 4-byte-aligned, this yields a +-32MB range.
  2619. If a particular imported symbol is outside this range, we have to redirect
  2620. the jump to a short piece of new code that just loads the 32bit absolute
  2621. address and jumps there.
  2622. On x86_64, PC-relative jumps and PC-relative accesses to the GOT are limited
  2623. to 32 bits (+-2GB).
  2624. This function just allocates space for one SymbolExtra for every
  2625. undefined symbol in the object file. The code for the jump islands is
  2626. filled in by makeSymbolExtra below.
  2627. */
  2628. static int ocAllocateSymbolExtras( ObjectCode* oc, int count, int first )
  2629. {
  2630. #ifdef USE_MMAP
  2631. int pagesize, n, m;
  2632. #endif
  2633. int aligned;
  2634. #ifndef USE_MMAP
  2635. int misalignment = 0;
  2636. #ifdef darwin_HOST_OS
  2637. misalignment = oc->misalignment;
  2638. #endif
  2639. #endif
  2640. if( count > 0 )
  2641. {
  2642. // round up to the nearest 4
  2643. aligned = (oc->fileSize + 3) & ~3;
  2644. #ifdef USE_MMAP
  2645. pagesize = getpagesize();
  2646. n = ROUND_UP( oc->fileSize, pagesize );
  2647. m = ROUND_UP( aligned + sizeof (SymbolExtra) * count, pagesize );
  2648. /* we try to use spare space at the end of the last page of the
  2649. * image for the jump islands, but if there isn't enough space
  2650. * then we have to map some (anonymously, remembering MAP_32BIT).
  2651. */
  2652. if( m > n ) // we need to allocate more pages
  2653. {
  2654. if (USE_CONTIGUOUS_MMAP)
  2655. {
  2656. /* Keep image and symbol_extras contiguous */
  2657. void *new = mmapForLinker(n + (sizeof(SymbolExtra) * count),
  2658. MAP_ANONYMOUS, -1);
  2659. if (new)
  2660. {
  2661. memcpy(new, oc->image, oc->fileSize);
  2662. munmap(oc->image, n);
  2663. oc->image = new;
  2664. oc->symbol_extras = (SymbolExtra *) (oc->image + n);
  2665. }
  2666. else
  2667. oc->symbol_extras = NULL;
  2668. }
  2669. else
  2670. {
  2671. oc->symbol_extras = mmapForLinker(sizeof(SymbolExtra) * count,
  2672. MAP_ANONYMOUS, -1);
  2673. }
  2674. }
  2675. else
  2676. {
  2677. oc->symbol_extras = (SymbolExtra *) (oc->image + aligned);
  2678. }
  2679. #else
  2680. oc->image -= misalignment;
  2681. oc->image = stgReallocBytes( oc->image,
  2682. misalignment +
  2683. aligned + sizeof (SymbolExtra) * count,
  2684. "ocAllocateSymbolExtras" );
  2685. oc->image += misalignment;
  2686. oc->symbol_extras = (SymbolExtra *) (oc->image + aligned);
  2687. #endif /* USE_MMAP */
  2688. memset( oc->symbol_extras, 0, sizeof (SymbolExtra) * count );
  2689. }
  2690. else
  2691. oc->symbol_extras = NULL;
  2692. oc->first_symbol_extra = first;
  2693. oc->n_symbol_extras = count;
  2694. return 1;
  2695. }
  2696. #endif
  2697. #endif // defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH) || defined(arm_HOST_ARCH)
  2698. #if defined(arm_HOST_ARCH)
  2699. static void
  2700. ocFlushInstructionCache( ObjectCode *oc )
  2701. {
  2702. // Object code
  2703. __clear_cache(oc->image, oc->image + oc->fileSize);
  2704. // Jump islands
  2705. __clear_cache(oc->symbol_extras, &oc->symbol_extras[oc->n_symbol_extras]);
  2706. }
  2707. #endif
  2708. #if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
  2709. #if !defined(x86_64_HOST_ARCH) || !defined(mingw32_HOST_OS)
  2710. static SymbolExtra* makeSymbolExtra( ObjectCode* oc,
  2711. unsigned long symbolNumber,
  2712. unsigned long target )
  2713. {
  2714. SymbolExtra *extra;
  2715. ASSERT( symbolNumber >= oc->first_symbol_extra
  2716. && symbolNumber - oc->first_symbol_extra < oc->n_symbol_extras);
  2717. extra = &oc->symbol_extras[symbolNumber - oc->first_symbol_extra];
  2718. #ifdef powerpc_HOST_ARCH
  2719. // lis r12, hi16(target)
  2720. extra->jumpIsland.lis_r12 = 0x3d80;
  2721. extra->jumpIsland.hi_addr = target >> 16;
  2722. // ori r12, r12, lo16(target)
  2723. extra->jumpIsland.ori_r12_r12 = 0x618c;
  2724. extra->jumpIsland.lo_addr = target & 0xffff;
  2725. // mtctr r12
  2726. extra->jumpIsland.mtctr_r12 = 0x7d8903a6;
  2727. // bctr
  2728. extra->jumpIsland.bctr = 0x4e800420;
  2729. #endif
  2730. #ifdef x86_64_HOST_ARCH
  2731. // jmp *-14(%rip)
  2732. static uint8_t jmp[] = { 0xFF, 0x25, 0xF2, 0xFF, 0xFF, 0xFF };
  2733. extra->addr = target;
  2734. memcpy(extra->jumpIsland, jmp, 6);
  2735. #endif
  2736. return extra;
  2737. }
  2738. #endif
  2739. #endif // defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
  2740. #ifdef arm_HOST_ARCH
  2741. static SymbolExtra* makeArmSymbolExtra( ObjectCode* oc,
  2742. unsigned long symbolNumber,
  2743. unsigned long target,
  2744. int fromThumb,
  2745. int toThumb )
  2746. {
  2747. SymbolExtra *extra;
  2748. ASSERT( symbolNumber >= oc->first_symbol_extra
  2749. && symbolNumber - oc->first_symbol_extra < oc->n_symbol_extras);
  2750. extra = &oc->symbol_extras[symbolNumber - oc->first_symbol_extra];
  2751. // Make sure instruction mode bit is set properly
  2752. if (toThumb)
  2753. target |= 1;
  2754. else
  2755. target &= ~1;
  2756. if (!fromThumb) {
  2757. // In ARM encoding:
  2758. // movw r12, #0
  2759. // movt r12, #0
  2760. // bx r12
  2761. uint32_t code[] = { 0xe300c000, 0xe340c000, 0xe12fff1c };
  2762. // Patch lower half-word into movw
  2763. code[0] |= ((target>>12) & 0xf) << 16;
  2764. code[0] |= target & 0xfff;
  2765. // Patch upper half-word into movt
  2766. target >>= 16;
  2767. code[1] |= ((target>>12) & 0xf) << 16;
  2768. code[1] |= target & 0xfff;
  2769. memcpy(extra->jumpIsland, code, 12);
  2770. } else {
  2771. // In Thumb encoding:
  2772. // movw r12, #0
  2773. // movt r12, #0
  2774. // bx r12
  2775. uint16_t code[] = { 0xf240, 0x0c00,
  2776. 0xf2c0, 0x0c00,
  2777. 0x4760 };
  2778. // Patch lower half-word into movw
  2779. code[0] |= (target>>12) & 0xf;
  2780. code[0] |= ((target>>11) & 0x1) << 10;
  2781. code[1] |= ((target>>8) & 0x7) << 12;
  2782. code[1] |= target & 0xff;
  2783. // Patch upper half-word into movt
  2784. target >>= 16;
  2785. code[2] |= (target>>12) & 0xf;
  2786. code[2] |= ((target>>11) & 0x1) << 10;
  2787. code[3] |= ((target>>8) & 0x7) << 12;
  2788. code[3] |= target & 0xff;
  2789. memcpy(extra->jumpIsland, code, 10);
  2790. }
  2791. return extra;
  2792. }
  2793. #endif // arm_HOST_ARCH
  2794. /* --------------------------------------------------------------------------
  2795. * PowerPC specifics (instruction cache flushing)
  2796. * ------------------------------------------------------------------------*/
  2797. #ifdef powerpc_HOST_ARCH
  2798. /*
  2799. ocFlushInstructionCache
  2800. Flush the data & instruction caches.
  2801. Because the PPC has split data/instruction caches, we have to
  2802. do that whenever we modify code at runtime.
  2803. */
  2804. static void
  2805. ocFlushInstructionCacheFrom(void* begin, size_t length)
  2806. {
  2807. size_t n = (length + 3) / 4;
  2808. unsigned long* p = begin;
  2809. while (n--)
  2810. {
  2811. __asm__ volatile ( "dcbf 0,%0\n\t"
  2812. "sync\n\t"
  2813. "icbi 0,%0"
  2814. :
  2815. : "r" (p)
  2816. );
  2817. p++;
  2818. }
  2819. __asm__ volatile ( "sync\n\t"
  2820. "isync"
  2821. );
  2822. }
  2823. static void
  2824. ocFlushInstructionCache( ObjectCode *oc )
  2825. {
  2826. /* The main object code */
  2827. ocFlushInstructionCacheFrom(oc->image
  2828. #ifdef darwin_HOST_OS
  2829. + oc->misalignment
  2830. #endif
  2831. , oc->fileSize);
  2832. /* Jump Islands */
  2833. ocFlushInstructionCacheFrom(oc->symbol_extras, sizeof(SymbolExtra) * oc->n_symbol_extras);
  2834. }
  2835. #endif /* powerpc_HOST_ARCH */
  2836. /* --------------------------------------------------------------------------
  2837. * PEi386 specifics (Win32 targets)
  2838. * ------------------------------------------------------------------------*/
  2839. /* The information for this linker comes from
  2840. Microsoft Portable Executable
  2841. and Common Object File Format Specification
  2842. revision 5.1 January 1998
  2843. which SimonM says comes from the MS Developer Network CDs.
  2844. It can be found there (on older CDs), but can also be found
  2845. online at:
  2846. http://www.microsoft.com/hwdev/hardware/PECOFF.asp
  2847. (this is Rev 6.0 from February 1999).
  2848. Things move, so if that fails, try searching for it via
  2849. http://www.google.com/search?q=PE+COFF+specification
  2850. The ultimate reference for the PE format is the Winnt.h
  2851. header file that comes with the Platform SDKs; as always,
  2852. implementations will drift wrt their documentation.
  2853. A good background article on the PE format is Matt Pietrek's
  2854. March 1994 article in Microsoft System Journal (MSJ)
  2855. (Vol.9, No. 3): "Peering Inside the PE: A Tour of the
  2856. Win32 Portable Executable File Format." The info in there
  2857. has recently been updated in a two part article in
  2858. MSDN magazine, issues Feb and March 2002,
  2859. "Inside Windows: An In-Depth Look into the Win32 Portable
  2860. Executable File Format"
  2861. John Levine's book "Linkers and Loaders" contains useful
  2862. info on PE too.
  2863. */
  2864. #if defined(OBJFORMAT_PEi386)
  2865. typedef unsigned char UChar;
  2866. typedef unsigned short UInt16;
  2867. typedef unsigned int UInt32;
  2868. typedef int Int32;
  2869. typedef unsigned long long int UInt64;
  2870. typedef
  2871. struct {
  2872. UInt16 Machine;
  2873. UInt16 NumberOfSections;
  2874. UInt32 TimeDateStamp;
  2875. UInt32 PointerToSymbolTable;
  2876. UInt32 NumberOfSymbols;
  2877. UInt16 SizeOfOptionalHeader;
  2878. UInt16 Characteristics;
  2879. }
  2880. COFF_header;
  2881. #define sizeof_COFF_header 20
  2882. typedef
  2883. struct {
  2884. UChar Name[8];
  2885. UInt32 VirtualSize;
  2886. UInt32 VirtualAddress;
  2887. UInt32 SizeOfRawData;
  2888. UInt32 PointerToRawData;
  2889. UInt32 PointerToRelocations;
  2890. UInt32 PointerToLinenumbers;
  2891. UInt16 NumberOfRelocations;
  2892. UInt16 NumberOfLineNumbers;
  2893. UInt32 Characteristics;
  2894. }
  2895. COFF_section;
  2896. #define sizeof_COFF_section 40
  2897. typedef
  2898. struct {
  2899. UChar Name[8];
  2900. UInt32 Value;
  2901. UInt16 SectionNumber;
  2902. UInt16 Type;
  2903. UChar StorageClass;
  2904. UChar NumberOfAuxSymbols;
  2905. }
  2906. COFF_symbol;
  2907. #define sizeof_COFF_symbol 18
  2908. typedef
  2909. struct {
  2910. UInt32 VirtualAddress;
  2911. UInt32 SymbolTableIndex;
  2912. UInt16 Type;
  2913. }
  2914. COFF_reloc;
  2915. #define sizeof_COFF_reloc 10
  2916. /* From PE spec doc, section 3.3.2 */
  2917. /* Note use of MYIMAGE_* since IMAGE_* are already defined in
  2918. windows.h -- for the same purpose, but I want to know what I'm
  2919. getting, here. */
  2920. #define MYIMAGE_FILE_RELOCS_STRIPPED 0x0001
  2921. #define MYIMAGE_FILE_EXECUTABLE_IMAGE 0x0002
  2922. #define MYIMAGE_FILE_DLL 0x2000
  2923. #define MYIMAGE_FILE_SYSTEM 0x1000
  2924. #define MYIMAGE_FILE_BYTES_REVERSED_HI 0x8000
  2925. #define MYIMAGE_FILE_BYTES_REVERSED_LO 0x0080
  2926. #define MYIMAGE_FILE_32BIT_MACHINE 0x0100
  2927. /* From PE spec doc, section 5.4.2 and 5.4.4 */
  2928. #define MYIMAGE_SYM_CLASS_EXTERNAL 2
  2929. #define MYIMAGE_SYM_CLASS_STATIC 3
  2930. #define MYIMAGE_SYM_UNDEFINED 0
  2931. /* From PE spec doc, section 4.1 */
  2932. #define MYIMAGE_SCN_CNT_CODE 0x00000020
  2933. #define MYIMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
  2934. #define MYIMAGE_SCN_LNK_NRELOC_OVFL 0x01000000
  2935. /* From PE spec doc, section 5.2.1 */
  2936. #define MYIMAGE_REL_I386_DIR32 0x0006
  2937. #define MYIMAGE_REL_I386_REL32 0x0014
  2938. /* We use myindex to calculate array addresses, rather than
  2939. simply doing the normal subscript thing. That's because
  2940. some of the above structs have sizes which are not
  2941. a whole number of words. GCC rounds their sizes up to a
  2942. whole number of words, which means that the address calcs
  2943. arising from using normal C indexing or pointer arithmetic
  2944. are just plain wrong. Sigh.
  2945. */
  2946. static UChar *
  2947. myindex ( int scale, void* base, int index )
  2948. {
  2949. return
  2950. ((UChar*)base) + scale * index;
  2951. }
  2952. static void
  2953. printName ( UChar* name, UChar* strtab )
  2954. {
  2955. if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
  2956. UInt32 strtab_offset = * (UInt32*)(name+4);
  2957. debugBelch("%s", strtab + strtab_offset );
  2958. } else {
  2959. int i;
  2960. for (i = 0; i < 8; i++) {
  2961. if (name[i] == 0) break;
  2962. debugBelch("%c", name[i] );
  2963. }
  2964. }
  2965. }
  2966. static void
  2967. copyName ( UChar* name, UChar* strtab, UChar* dst, int dstSize )
  2968. {
  2969. if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
  2970. UInt32 strtab_offset = * (UInt32*)(name+4);
  2971. strncpy ( (char*)dst, (char*)strtab+strtab_offset, dstSize );
  2972. dst[dstSize-1] = 0;
  2973. } else {
  2974. int i = 0;
  2975. while (1) {
  2976. if (i >= 8) break;
  2977. if (name[i] == 0) break;
  2978. dst[i] = name[i];
  2979. i++;
  2980. }
  2981. dst[i] = 0;
  2982. }
  2983. }
  2984. static UChar *
  2985. cstring_from_COFF_symbol_name ( UChar* name, UChar* strtab )
  2986. {
  2987. UChar* newstr;
  2988. /* If the string is longer than 8 bytes, look in the
  2989. string table for it -- this will be correctly zero terminated.
  2990. */
  2991. if (name[0]==0 && name[1]==0 && name[2]==0 && name[3]==0) {
  2992. UInt32 strtab_offset = * (UInt32*)(name+4);
  2993. return ((UChar*)strtab) + strtab_offset;
  2994. }
  2995. /* Otherwise, if shorter than 8 bytes, return the original,
  2996. which by defn is correctly terminated.
  2997. */
  2998. if (name[7]==0) return name;
  2999. /* The annoying case: 8 bytes. Copy into a temporary
  3000. (XXX which is never freed ...)
  3001. */
  3002. newstr = stgMallocBytes(9, "cstring_from_COFF_symbol_name");
  3003. ASSERT(newstr);
  3004. strncpy((char*)newstr,(char*)name,8);
  3005. newstr[8] = 0;
  3006. return newstr;
  3007. }
  3008. /* Getting the name of a section is mildly tricky, so we make a
  3009. function for it. Sadly, in one case we have to copy the string
  3010. (when it is exactly 8 bytes long there's no trailing '\0'), so for
  3011. consistency we *always* copy the string; the caller must free it
  3012. */
  3013. static char *
  3014. cstring_from_section_name (UChar* name, UChar* strtab)
  3015. {
  3016. char *newstr;
  3017. if (name[0]=='/') {
  3018. int strtab_offset = strtol((char*)name+1,NULL,10);
  3019. int len = strlen(((char*)strtab) + strtab_offset);
  3020. newstr = stgMallocBytes(len+1, "cstring_from_section_symbol_name");
  3021. strcpy((char*)newstr, (char*)((UChar*)strtab) + strtab_offset);
  3022. return newstr;
  3023. }
  3024. else
  3025. {
  3026. newstr = stgMallocBytes(9, "cstring_from_section_symbol_name");
  3027. ASSERT(newstr);
  3028. strncpy((char*)newstr,(char*)name,8);
  3029. newstr[8] = 0;
  3030. return newstr;
  3031. }
  3032. }
  3033. /* Just compares the short names (first 8 chars) */
  3034. static COFF_section *
  3035. findPEi386SectionCalled ( ObjectCode* oc, UChar* name )
  3036. {
  3037. int i;
  3038. COFF_header* hdr
  3039. = (COFF_header*)(oc->image);
  3040. COFF_section* sectab
  3041. = (COFF_section*) (
  3042. ((UChar*)(oc->image))
  3043. + sizeof_COFF_header + hdr->SizeOfOptionalHeader
  3044. );
  3045. for (i = 0; i < hdr->NumberOfSections; i++) {
  3046. UChar* n1;
  3047. UChar* n2;
  3048. COFF_section* section_i
  3049. = (COFF_section*)
  3050. myindex ( sizeof_COFF_section, sectab, i );
  3051. n1 = (UChar*) &(section_i->Name);
  3052. n2 = name;
  3053. if (n1[0]==n2[0] && n1[1]==n2[1] && n1[2]==n2[2] &&
  3054. n1[3]==n2[3] && n1[4]==n2[4] && n1[5]==n2[5] &&
  3055. n1[6]==n2[6] && n1[7]==n2[7])
  3056. return section_i;
  3057. }
  3058. return NULL;
  3059. }
  3060. static void
  3061. zapTrailingAtSign ( UChar* sym )
  3062. {
  3063. # define my_isdigit(c) ((c) >= '0' && (c) <= '9')
  3064. int i, j;
  3065. if (sym[0] == 0) return;
  3066. i = 0;
  3067. while (sym[i] != 0) i++;
  3068. i--;
  3069. j = i;
  3070. while (j > 0 && my_isdigit(sym[j])) j--;
  3071. if (j > 0 && sym[j] == '@' && j != i) sym[j] = 0;
  3072. # undef my_isdigit
  3073. }
  3074. static void *
  3075. lookupSymbolInDLLs ( UChar *lbl )
  3076. {
  3077. OpenedDLL* o_dll;
  3078. void *sym;
  3079. for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
  3080. /* debugBelch("look in %s for %s\n", o_dll->name, lbl); */
  3081. if (lbl[0] == '_') {
  3082. /* HACK: if the name has an initial underscore, try stripping
  3083. it off & look that up first. I've yet to verify whether there's
  3084. a Rule that governs whether an initial '_' *should always* be
  3085. stripped off when mapping from import lib name to the DLL name.
  3086. */
  3087. sym = GetProcAddress(o_dll->instance, (char*)(lbl+1));
  3088. if (sym != NULL) {
  3089. /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/
  3090. return sym;
  3091. }
  3092. }
  3093. sym = GetProcAddress(o_dll->instance, (char*)lbl);
  3094. if (sym != NULL) {
  3095. /*debugBelch("found %s in %s\n", lbl,o_dll->name);*/
  3096. return sym;
  3097. }
  3098. }
  3099. return NULL;
  3100. }
  3101. static int
  3102. ocVerifyImage_PEi386 ( ObjectCode* oc )
  3103. {
  3104. int i;
  3105. UInt32 j, noRelocs;
  3106. COFF_header* hdr;
  3107. COFF_section* sectab;
  3108. COFF_symbol* symtab;
  3109. UChar* strtab;
  3110. /* debugBelch("\nLOADING %s\n", oc->fileName); */
  3111. hdr = (COFF_header*)(oc->image);
  3112. sectab = (COFF_section*) (
  3113. ((UChar*)(oc->image))
  3114. + sizeof_COFF_header + hdr->SizeOfOptionalHeader
  3115. );
  3116. symtab = (COFF_symbol*) (
  3117. ((UChar*)(oc->image))
  3118. + hdr->PointerToSymbolTable
  3119. );
  3120. strtab = ((UChar*)symtab)
  3121. + hdr->NumberOfSymbols * sizeof_COFF_symbol;
  3122. #if defined(i386_HOST_ARCH)
  3123. if (hdr->Machine != 0x14c) {
  3124. errorBelch("%" PATH_FMT ": Not x86 PEi386", oc->fileName);
  3125. return 0;
  3126. }
  3127. #elif defined(x86_64_HOST_ARCH)
  3128. if (hdr->Machine != 0x8664) {
  3129. errorBelch("%" PATH_FMT ": Not x86_64 PEi386", oc->fileName);
  3130. return 0;
  3131. }
  3132. #else
  3133. errorBelch("PEi386 not supported on this arch");
  3134. #endif
  3135. if (hdr->SizeOfOptionalHeader != 0) {
  3136. errorBelch("%" PATH_FMT ": PEi386 with nonempty optional header", oc->fileName);
  3137. return 0;
  3138. }
  3139. if ( /* (hdr->Characteristics & MYIMAGE_FILE_RELOCS_STRIPPED) || */
  3140. (hdr->Characteristics & MYIMAGE_FILE_EXECUTABLE_IMAGE) ||
  3141. (hdr->Characteristics & MYIMAGE_FILE_DLL) ||
  3142. (hdr->Characteristics & MYIMAGE_FILE_SYSTEM) ) {
  3143. errorBelch("%" PATH_FMT ": Not a PEi386 object file", oc->fileName);
  3144. return 0;
  3145. }
  3146. if ( (hdr->Characteristics & MYIMAGE_FILE_BYTES_REVERSED_HI)
  3147. /* || !(hdr->Characteristics & MYIMAGE_FILE_32BIT_MACHINE) */ ) {
  3148. errorBelch("%" PATH_FMT ": Invalid PEi386 word size or endiannness: %d",
  3149. oc->fileName,
  3150. (int)(hdr->Characteristics));
  3151. return 0;
  3152. }
  3153. /* If the string table size is way crazy, this might indicate that
  3154. there are more than 64k relocations, despite claims to the
  3155. contrary. Hence this test. */
  3156. /* debugBelch("strtab size %d\n", * (UInt32*)strtab); */
  3157. #if 0
  3158. if ( (*(UInt32*)strtab) > 600000 ) {
  3159. /* Note that 600k has no special significance other than being
  3160. big enough to handle the almost-2MB-sized lumps that
  3161. constitute HSwin32*.o. */
  3162. debugBelch("PEi386 object has suspiciously large string table; > 64k relocs?");
  3163. return 0;
  3164. }
  3165. #endif
  3166. /* No further verification after this point; only debug printing. */
  3167. i = 0;
  3168. IF_DEBUG(linker, i=1);
  3169. if (i == 0) return 1;
  3170. debugBelch( "sectab offset = %" FMT_Int "\n", ((UChar*)sectab) - ((UChar*)hdr) );
  3171. debugBelch( "symtab offset = %" FMT_Int "\n", ((UChar*)symtab) - ((UChar*)hdr) );
  3172. debugBelch( "strtab offset = %" FMT_Int "\n", ((UChar*)strtab) - ((UChar*)hdr) );
  3173. debugBelch("\n" );
  3174. debugBelch( "Machine: 0x%x\n", (UInt32)(hdr->Machine) );
  3175. debugBelch( "# sections: %d\n", (UInt32)(hdr->NumberOfSections) );
  3176. debugBelch( "time/date: 0x%x\n", (UInt32)(hdr->TimeDateStamp) );
  3177. debugBelch( "symtab offset: %d\n", (UInt32)(hdr->PointerToSymbolTable) );
  3178. debugBelch( "# symbols: %d\n", (UInt32)(hdr->NumberOfSymbols) );
  3179. debugBelch( "sz of opt hdr: %d\n", (UInt32)(hdr->SizeOfOptionalHeader) );
  3180. debugBelch( "characteristics: 0x%x\n", (UInt32)(hdr->Characteristics) );
  3181. /* Print the section table. */
  3182. debugBelch("\n" );
  3183. for (i = 0; i < hdr->NumberOfSections; i++) {
  3184. COFF_reloc* reltab;
  3185. COFF_section* sectab_i
  3186. = (COFF_section*)
  3187. myindex ( sizeof_COFF_section, sectab, i );
  3188. debugBelch(
  3189. "\n"
  3190. "section %d\n"
  3191. " name `",
  3192. i
  3193. );
  3194. printName ( sectab_i->Name, strtab );
  3195. debugBelch(
  3196. "'\n"
  3197. " vsize %d\n"
  3198. " vaddr %d\n"
  3199. " data sz %d\n"
  3200. " data off %d\n"
  3201. " num rel %d\n"
  3202. " off rel %d\n"
  3203. " ptr raw 0x%x\n",
  3204. sectab_i->VirtualSize,
  3205. sectab_i->VirtualAddress,
  3206. sectab_i->SizeOfRawData,
  3207. sectab_i->PointerToRawData,
  3208. sectab_i->NumberOfRelocations,
  3209. sectab_i->PointerToRelocations,
  3210. sectab_i->PointerToRawData
  3211. );
  3212. reltab = (COFF_reloc*) (
  3213. ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
  3214. );
  3215. if ( sectab_i->Characteristics & MYIMAGE_SCN_LNK_NRELOC_OVFL ) {
  3216. /* If the relocation field (a short) has overflowed, the
  3217. * real count can be found in the first reloc entry.
  3218. *
  3219. * See Section 4.1 (last para) of the PE spec (rev6.0).
  3220. */
  3221. COFF_reloc* rel = (COFF_reloc*)
  3222. myindex ( sizeof_COFF_reloc, reltab, 0 );
  3223. noRelocs = rel->VirtualAddress;
  3224. j = 1;
  3225. } else {
  3226. noRelocs = sectab_i->NumberOfRelocations;
  3227. j = 0;
  3228. }
  3229. for (; j < noRelocs; j++) {
  3230. COFF_symbol* sym;
  3231. COFF_reloc* rel = (COFF_reloc*)
  3232. myindex ( sizeof_COFF_reloc, reltab, j );
  3233. debugBelch(
  3234. " type 0x%-4x vaddr 0x%-8x name `",
  3235. (UInt32)rel->Type,
  3236. rel->VirtualAddress );
  3237. sym = (COFF_symbol*)
  3238. myindex ( sizeof_COFF_symbol, symtab, rel->SymbolTableIndex );
  3239. /* Hmm..mysterious looking offset - what's it for? SOF */
  3240. printName ( sym->Name, strtab -10 );
  3241. debugBelch("'\n" );
  3242. }
  3243. debugBelch("\n" );
  3244. }
  3245. debugBelch("\n" );
  3246. debugBelch("string table has size 0x%x\n", * (UInt32*)strtab );
  3247. debugBelch("---START of string table---\n");
  3248. for (i = 4; i < *(Int32*)strtab; i++) {
  3249. if (strtab[i] == 0)
  3250. debugBelch("\n"); else
  3251. debugBelch("%c", strtab[i] );
  3252. }
  3253. debugBelch("--- END of string table---\n");
  3254. debugBelch("\n" );
  3255. i = 0;
  3256. while (1) {
  3257. COFF_symbol* symtab_i;
  3258. if (i >= (Int32)(hdr->NumberOfSymbols)) break;
  3259. symtab_i = (COFF_symbol*)
  3260. myindex ( sizeof_COFF_symbol, symtab, i );
  3261. debugBelch(
  3262. "symbol %d\n"
  3263. " name `",
  3264. i
  3265. );
  3266. printName ( symtab_i->Name, strtab );
  3267. debugBelch(
  3268. "'\n"
  3269. " value 0x%x\n"
  3270. " 1+sec# %d\n"
  3271. " type 0x%x\n"
  3272. " sclass 0x%x\n"
  3273. " nAux %d\n",
  3274. symtab_i->Value,
  3275. (Int32)(symtab_i->SectionNumber),
  3276. (UInt32)symtab_i->Type,
  3277. (UInt32)symtab_i->StorageClass,
  3278. (UInt32)symtab_i->NumberOfAuxSymbols
  3279. );
  3280. i += symtab_i->NumberOfAuxSymbols;
  3281. i++;
  3282. }
  3283. debugBelch("\n" );
  3284. return 1;
  3285. }
  3286. static int
  3287. ocGetNames_PEi386 ( ObjectCode* oc )
  3288. {
  3289. COFF_header* hdr;
  3290. COFF_section* sectab;
  3291. COFF_symbol* symtab;
  3292. UChar* strtab;
  3293. UChar* sname;
  3294. void* addr;
  3295. int i;
  3296. hdr = (COFF_header*)(oc->image);
  3297. sectab = (COFF_section*) (
  3298. ((UChar*)(oc->image))
  3299. + sizeof_COFF_header + hdr->SizeOfOptionalHeader
  3300. );
  3301. symtab = (COFF_symbol*) (
  3302. ((UChar*)(oc->image))
  3303. + hdr->PointerToSymbolTable
  3304. );
  3305. strtab = ((UChar*)(oc->image))
  3306. + hdr->PointerToSymbolTable
  3307. + hdr->NumberOfSymbols * sizeof_COFF_symbol;
  3308. /* Allocate space for any (local, anonymous) .bss sections. */
  3309. for (i = 0; i < hdr->NumberOfSections; i++) {
  3310. UInt32 bss_sz;
  3311. UChar* zspace;
  3312. COFF_section* sectab_i
  3313. = (COFF_section*)
  3314. myindex ( sizeof_COFF_section, sectab, i );
  3315. char *secname = cstring_from_section_name(sectab_i->Name, strtab);
  3316. if (0 != strcmp(secname, ".bss")) {
  3317. stgFree(secname);
  3318. continue;
  3319. }
  3320. stgFree(secname);
  3321. /* sof 10/05: the PE spec text isn't too clear regarding what
  3322. * the SizeOfRawData field is supposed to hold for object
  3323. * file sections containing just uninitialized data -- for executables,
  3324. * it is supposed to be zero; unclear what it's supposed to be
  3325. * for object files. However, VirtualSize is guaranteed to be
  3326. * zero for object files, which definitely suggests that SizeOfRawData
  3327. * will be non-zero (where else would the size of this .bss section be
  3328. * stored?) Looking at the COFF_section info for incoming object files,
  3329. * this certainly appears to be the case.
  3330. *
  3331. * => I suspect we've been incorrectly handling .bss sections in (relocatable)
  3332. * object files up until now. This turned out to bite us with ghc-6.4.1's use
  3333. * of gcc-3.4.x, which has started to emit initially-zeroed-out local 'static'
  3334. * variable decls into to the .bss section. (The specific function in Q which
  3335. * triggered this is libraries/base/cbits/dirUtils.c:__hscore_getFolderPath())
  3336. */
  3337. if (sectab_i->VirtualSize == 0 && sectab_i->SizeOfRawData == 0) continue;
  3338. /* This is a non-empty .bss section. Allocate zeroed space for
  3339. it, and set its PointerToRawData field such that oc->image +
  3340. PointerToRawData == addr_of_zeroed_space. */
  3341. bss_sz = sectab_i->VirtualSize;
  3342. if ( bss_sz < sectab_i->SizeOfRawData) { bss_sz = sectab_i->SizeOfRawData; }
  3343. zspace = stgCallocBytes(1, bss_sz, "ocGetNames_PEi386(anonymous bss)");
  3344. sectab_i->PointerToRawData = ((UChar*)zspace) - ((UChar*)(oc->image));
  3345. addProddableBlock(oc, zspace, bss_sz);
  3346. /* debugBelch("BSS anon section at 0x%x\n", zspace); */
  3347. }
  3348. /* Copy section information into the ObjectCode. */
  3349. for (i = 0; i < hdr->NumberOfSections; i++) {
  3350. UChar* start;
  3351. UChar* end;
  3352. UInt32 sz;
  3353. SectionKind kind
  3354. = SECTIONKIND_OTHER;
  3355. COFF_section* sectab_i
  3356. = (COFF_section*)
  3357. myindex ( sizeof_COFF_section, sectab, i );
  3358. char *secname = cstring_from_section_name(sectab_i->Name, strtab);
  3359. IF_DEBUG(linker, debugBelch("section name = %s\n", secname ));
  3360. # if 0
  3361. /* I'm sure this is the Right Way to do it. However, the
  3362. alternative of testing the sectab_i->Name field seems to
  3363. work ok with Cygwin.
  3364. */
  3365. if (sectab_i->Characteristics & MYIMAGE_SCN_CNT_CODE ||
  3366. sectab_i->Characteristics & MYIMAGE_SCN_CNT_INITIALIZED_DATA)
  3367. kind = SECTIONKIND_CODE_OR_RODATA;
  3368. # endif
  3369. if (0==strcmp(".text",(char*)secname) ||
  3370. 0==strcmp(".text.startup",(char*)secname) ||
  3371. 0==strcmp(".rdata",(char*)secname)||
  3372. 0==strcmp(".rodata",(char*)secname))
  3373. kind = SECTIONKIND_CODE_OR_RODATA;
  3374. if (0==strcmp(".data",(char*)secname) ||
  3375. 0==strcmp(".bss",(char*)secname))
  3376. kind = SECTIONKIND_RWDATA;
  3377. ASSERT(sectab_i->SizeOfRawData == 0 || sectab_i->VirtualSize == 0);
  3378. sz = sectab_i->SizeOfRawData;
  3379. if (sz < sectab_i->VirtualSize) sz = sectab_i->VirtualSize;
  3380. start = ((UChar*)(oc->image)) + sectab_i->PointerToRawData;
  3381. end = start + sz - 1;
  3382. if (kind == SECTIONKIND_OTHER
  3383. /* Ignore sections called which contain stabs debugging
  3384. information. */
  3385. && 0 != strcmp(".stab", (char*)secname)
  3386. && 0 != strcmp(".stabstr", (char*)secname)
  3387. /* Ignore sections called which contain exception information. */
  3388. && 0 != strcmp(".pdata", (char*)secname)
  3389. && 0 != strcmp(".xdata", (char*)secname)
  3390. /* ignore constructor section for now */
  3391. && 0 != strcmp(".ctors", (char*)secname)
  3392. /* ignore section generated from .ident */
  3393. && 0!= strncmp(".debug", (char*)secname, 6)
  3394. /* ignore unknown section that appeared in gcc 3.4.5(?) */
  3395. && 0!= strcmp(".reloc", (char*)secname)
  3396. && 0 != strcmp(".rdata$zzz", (char*)secname)
  3397. ) {
  3398. errorBelch("Unknown PEi386 section name `%s' (while processing: %" PATH_FMT")", secname, oc->fileName);
  3399. stgFree(secname);
  3400. return 0;
  3401. }
  3402. if (kind != SECTIONKIND_OTHER && end >= start) {
  3403. if ((((size_t)(start)) % sizeof(void *)) != 0) {
  3404. barf("Misaligned section: %p", start);
  3405. }
  3406. addSection(oc, kind, start, end);
  3407. addProddableBlock(oc, start, end - start + 1);
  3408. }
  3409. stgFree(secname);
  3410. }
  3411. /* Copy exported symbols into the ObjectCode. */
  3412. oc->n_symbols = hdr->NumberOfSymbols;
  3413. oc->symbols = stgMallocBytes(oc->n_symbols * sizeof(char*),
  3414. "ocGetNames_PEi386(oc->symbols)");
  3415. /* Call me paranoid; I don't care. */
  3416. for (i = 0; i < oc->n_symbols; i++)
  3417. oc->symbols[i] = NULL;
  3418. i = 0;
  3419. while (1) {
  3420. COFF_symbol* symtab_i;
  3421. if (i >= (Int32)(hdr->NumberOfSymbols)) break;
  3422. symtab_i = (COFF_symbol*)
  3423. myindex ( sizeof_COFF_symbol, symtab, i );
  3424. addr = NULL;
  3425. if (symtab_i->StorageClass == MYIMAGE_SYM_CLASS_EXTERNAL
  3426. && symtab_i->SectionNumber != MYIMAGE_SYM_UNDEFINED) {
  3427. /* This symbol is global and defined, viz, exported */
  3428. /* for MYIMAGE_SYMCLASS_EXTERNAL
  3429. && !MYIMAGE_SYM_UNDEFINED,
  3430. the address of the symbol is:
  3431. address of relevant section + offset in section
  3432. */
  3433. COFF_section* sectabent
  3434. = (COFF_section*) myindex ( sizeof_COFF_section,
  3435. sectab,
  3436. symtab_i->SectionNumber-1 );
  3437. addr = ((UChar*)(oc->image))
  3438. + (sectabent->PointerToRawData
  3439. + symtab_i->Value);
  3440. }
  3441. else
  3442. if (symtab_i->SectionNumber == MYIMAGE_SYM_UNDEFINED
  3443. && symtab_i->Value > 0) {
  3444. /* This symbol isn't in any section at all, ie, global bss.
  3445. Allocate zeroed space for it. */
  3446. addr = stgCallocBytes(1, symtab_i->Value,
  3447. "ocGetNames_PEi386(non-anonymous bss)");
  3448. addSection(oc, SECTIONKIND_RWDATA, addr,
  3449. ((UChar*)addr) + symtab_i->Value - 1);
  3450. addProddableBlock(oc, addr, symtab_i->Value);
  3451. /* debugBelch("BSS section at 0x%x\n", addr); */
  3452. }
  3453. if (addr != NULL ) {
  3454. sname = cstring_from_COFF_symbol_name ( symtab_i->Name, strtab );
  3455. /* debugBelch("addSymbol %p `%s \n", addr,sname); */
  3456. IF_DEBUG(linker, debugBelch("addSymbol %p `%s'\n", addr,sname);)
  3457. ASSERT(i >= 0 && i < oc->n_symbols);
  3458. /* cstring_from_COFF_symbol_name always succeeds. */
  3459. oc->symbols[i] = (char*)sname;
  3460. ghciInsertStrHashTable(oc->fileName, symhash, (char*)sname, addr);
  3461. } else {
  3462. # if 0
  3463. debugBelch(
  3464. "IGNORING symbol %d\n"
  3465. " name `",
  3466. i
  3467. );
  3468. printName ( symtab_i->Name, strtab );
  3469. debugBelch(
  3470. "'\n"
  3471. " value 0x%x\n"
  3472. " 1+sec# %d\n"
  3473. " type 0x%x\n"
  3474. " sclass 0x%x\n"
  3475. " nAux %d\n",
  3476. symtab_i->Value,
  3477. (Int32)(symtab_i->SectionNumber),
  3478. (UInt32)symtab_i->Type,
  3479. (UInt32)symtab_i->StorageClass,
  3480. (UInt32)symtab_i->NumberOfAuxSymbols
  3481. );
  3482. # endif
  3483. }
  3484. i += symtab_i->NumberOfAuxSymbols;
  3485. i++;
  3486. }
  3487. return 1;
  3488. }
  3489. static int
  3490. ocResolve_PEi386 ( ObjectCode* oc )
  3491. {
  3492. COFF_header* hdr;
  3493. COFF_section* sectab;
  3494. COFF_symbol* symtab;
  3495. UChar* strtab;
  3496. UInt32 A;
  3497. size_t S;
  3498. void * pP;
  3499. int i;
  3500. UInt32 j, noRelocs;
  3501. /* ToDo: should be variable-sized? But is at least safe in the
  3502. sense of buffer-overrun-proof. */
  3503. UChar symbol[1000];
  3504. /* debugBelch("resolving for %s\n", oc->fileName); */
  3505. hdr = (COFF_header*)(oc->image);
  3506. sectab = (COFF_section*) (
  3507. ((UChar*)(oc->image))
  3508. + sizeof_COFF_header + hdr->SizeOfOptionalHeader
  3509. );
  3510. symtab = (COFF_symbol*) (
  3511. ((UChar*)(oc->image))
  3512. + hdr->PointerToSymbolTable
  3513. );
  3514. strtab = ((UChar*)(oc->image))
  3515. + hdr->PointerToSymbolTable
  3516. + hdr->NumberOfSymbols * sizeof_COFF_symbol;
  3517. for (i = 0; i < hdr->NumberOfSections; i++) {
  3518. COFF_section* sectab_i
  3519. = (COFF_section*)
  3520. myindex ( sizeof_COFF_section, sectab, i );
  3521. COFF_reloc* reltab
  3522. = (COFF_reloc*) (
  3523. ((UChar*)(oc->image)) + sectab_i->PointerToRelocations
  3524. );
  3525. char *secname = cstring_from_section_name(sectab_i->Name, strtab);
  3526. /* Ignore sections called which contain stabs debugging
  3527. information. */
  3528. if (0 == strcmp(".stab", (char*)secname)
  3529. || 0 == strcmp(".stabstr", (char*)secname)
  3530. || 0 == strcmp(".pdata", (char*)secname)
  3531. || 0 == strcmp(".xdata", (char*)secname)
  3532. || 0 == strcmp(".ctors", (char*)secname)
  3533. || 0 == strncmp(".debug", (char*)secname, 6)
  3534. || 0 == strcmp(".rdata$zzz", (char*)secname)) {
  3535. stgFree(secname);
  3536. continue;
  3537. }
  3538. stgFree(secname);
  3539. if ( sectab_i->Characteristics & MYIMAGE_SCN_LNK_NRELOC_OVFL ) {
  3540. /* If the relocation field (a short) has overflowed, the
  3541. * real count can be found in the first reloc entry.
  3542. *
  3543. * See Section 4.1 (last para) of the PE spec (rev6.0).
  3544. *
  3545. * Nov2003 update: the GNU linker still doesn't correctly
  3546. * handle the generation of relocatable object files with
  3547. * overflown relocations. Hence the output to warn of potential
  3548. * troubles.
  3549. */
  3550. COFF_reloc* rel = (COFF_reloc*)
  3551. myindex ( sizeof_COFF_reloc, reltab, 0 );
  3552. noRelocs = rel->VirtualAddress;
  3553. /* 10/05: we now assume (and check for) a GNU ld that is capable
  3554. * of handling object files with (>2^16) of relocs.
  3555. */
  3556. #if 0
  3557. debugBelch("WARNING: Overflown relocation field (# relocs found: %u)\n",
  3558. noRelocs);
  3559. #endif
  3560. j = 1;
  3561. } else {
  3562. noRelocs = sectab_i->NumberOfRelocations;
  3563. j = 0;
  3564. }
  3565. for (; j < noRelocs; j++) {
  3566. COFF_symbol* sym;
  3567. COFF_reloc* reltab_j
  3568. = (COFF_reloc*)
  3569. myindex ( sizeof_COFF_reloc, reltab, j );
  3570. /* the location to patch */
  3571. pP = (
  3572. ((UChar*)(oc->image))
  3573. + (sectab_i->PointerToRawData
  3574. + reltab_j->VirtualAddress
  3575. - sectab_i->VirtualAddress )
  3576. );
  3577. /* the existing contents of pP */
  3578. A = *(UInt32*)pP;
  3579. /* the symbol to connect to */
  3580. sym = (COFF_symbol*)
  3581. myindex ( sizeof_COFF_symbol,
  3582. symtab, reltab_j->SymbolTableIndex );
  3583. IF_DEBUG(linker,
  3584. debugBelch(
  3585. "reloc sec %2d num %3d: type 0x%-4x "
  3586. "vaddr 0x%-8x name `",
  3587. i, j,
  3588. (UInt32)reltab_j->Type,
  3589. reltab_j->VirtualAddress );
  3590. printName ( sym->Name, strtab );
  3591. debugBelch("'\n" ));
  3592. if (sym->StorageClass == MYIMAGE_SYM_CLASS_STATIC) {
  3593. COFF_section* section_sym
  3594. = findPEi386SectionCalled ( oc, sym->Name );
  3595. if (!section_sym) {
  3596. errorBelch("%" PATH_FMT ": can't find section `%s'", oc->fileName, sym->Name);
  3597. return 0;
  3598. }
  3599. S = ((size_t)(oc->image))
  3600. + ((size_t)(section_sym->PointerToRawData))
  3601. + ((size_t)(sym->Value));
  3602. } else {
  3603. copyName ( sym->Name, strtab, symbol, 1000-1 );
  3604. S = (size_t) lookupSymbol( (char*)symbol );
  3605. if ((void*)S != NULL) goto foundit;
  3606. errorBelch("%" PATH_FMT ": unknown symbol `%s'", oc->fileName, symbol);
  3607. return 0;
  3608. foundit:;
  3609. }
  3610. /* All supported relocations write at least 4 bytes */
  3611. checkProddableBlock(oc, pP, 4);
  3612. switch (reltab_j->Type) {
  3613. #if defined(i386_HOST_ARCH)
  3614. case MYIMAGE_REL_I386_DIR32:
  3615. *(UInt32 *)pP = ((UInt32)S) + A;
  3616. break;
  3617. case MYIMAGE_REL_I386_REL32:
  3618. /* Tricky. We have to insert a displacement at
  3619. pP which, when added to the PC for the _next_
  3620. insn, gives the address of the target (S).
  3621. Problem is to know the address of the next insn
  3622. when we only know pP. We assume that this
  3623. literal field is always the last in the insn,
  3624. so that the address of the next insn is pP+4
  3625. -- hence the constant 4.
  3626. Also I don't know if A should be added, but so
  3627. far it has always been zero.
  3628. SOF 05/2005: 'A' (old contents of *pP) have been observed
  3629. to contain values other than zero (the 'wx' object file
  3630. that came with wxhaskell-0.9.4; dunno how it was compiled..).
  3631. So, add displacement to old value instead of asserting
  3632. A to be zero. Fixes wxhaskell-related crashes, and no other
  3633. ill effects have been observed.
  3634. Update: the reason why we're seeing these more elaborate
  3635. relocations is due to a switch in how the NCG compiles SRTs
  3636. and offsets to them from info tables. SRTs live in .(ro)data,
  3637. while info tables live in .text, causing GAS to emit REL32/DISP32
  3638. relocations with non-zero values. Adding the displacement is
  3639. the right thing to do.
  3640. */
  3641. *(UInt32 *)pP = ((UInt32)S) + A - ((UInt32)(size_t)pP) - 4;
  3642. break;
  3643. #elif defined(x86_64_HOST_ARCH)
  3644. case 2: /* R_X86_64_32 */
  3645. case 17: /* R_X86_64_32S */
  3646. {
  3647. size_t v;
  3648. v = S + ((size_t)A);
  3649. if (v >> 32) {
  3650. copyName ( sym->Name, strtab, symbol, 1000-1 );
  3651. barf("R_X86_64_32[S]: High bits are set in %zx for %s",
  3652. v, (char *)symbol);
  3653. }
  3654. *(UInt32 *)pP = (UInt32)v;
  3655. break;
  3656. }
  3657. case 4: /* R_X86_64_PC32 */
  3658. {
  3659. intptr_t v;
  3660. v = ((intptr_t)S) + ((intptr_t)(Int32)A) - ((intptr_t)pP) - 4;
  3661. if ((v >> 32) && ((-v) >> 32)) {
  3662. copyName ( sym->Name, strtab, symbol, 1000-1 );
  3663. barf("R_X86_64_PC32: High bits are set in %zx for %s",
  3664. v, (char *)symbol);
  3665. }
  3666. *(UInt32 *)pP = (UInt32)v;
  3667. break;
  3668. }
  3669. case 1: /* R_X86_64_64 */
  3670. {
  3671. UInt64 A;
  3672. checkProddableBlock(oc, pP, 8);
  3673. A = *(UInt64*)pP;
  3674. *(UInt64 *)pP = ((UInt64)S) + ((UInt64)A);
  3675. break;
  3676. }
  3677. #endif
  3678. default:
  3679. debugBelch("%" PATH_FMT ": unhandled PEi386 relocation type %d",
  3680. oc->fileName, reltab_j->Type);
  3681. return 0;
  3682. }
  3683. }
  3684. }
  3685. IF_DEBUG(linker, debugBelch("completed %" PATH_FMT, oc->fileName));
  3686. return 1;
  3687. }
  3688. #endif /* defined(OBJFORMAT_PEi386) */
  3689. /* --------------------------------------------------------------------------
  3690. * ELF specifics
  3691. * ------------------------------------------------------------------------*/
  3692. #if defined(OBJFORMAT_ELF)
  3693. #define FALSE 0
  3694. #define TRUE 1
  3695. #if defined(sparc_HOST_ARCH)
  3696. # define ELF_TARGET_SPARC /* Used inside <elf.h> */
  3697. #elif defined(i386_HOST_ARCH)
  3698. # define ELF_TARGET_386 /* Used inside <elf.h> */
  3699. #elif defined(x86_64_HOST_ARCH)
  3700. # define ELF_TARGET_X64_64
  3701. # define ELF_64BIT
  3702. # define ELF_TARGET_AMD64 /* Used inside <elf.h> on Solaris 11 */
  3703. #elif defined(powerpc64_HOST_ARCH)
  3704. # define ELF_64BIT
  3705. #endif
  3706. #if !defined(openbsd_HOST_OS)
  3707. # include <elf.h>
  3708. #else
  3709. /* openbsd elf has things in different places, with diff names */
  3710. # include <elf_abi.h>
  3711. # include <machine/reloc.h>
  3712. # define R_386_32 RELOC_32
  3713. # define R_386_PC32 RELOC_PC32
  3714. #endif
  3715. /* If elf.h doesn't define it */
  3716. # ifndef R_X86_64_PC64
  3717. # define R_X86_64_PC64 24
  3718. # endif
  3719. /*
  3720. * Workaround for libc implementations (e.g. eglibc) with incomplete
  3721. * relocation lists
  3722. */
  3723. #ifndef R_ARM_THM_CALL
  3724. # define R_ARM_THM_CALL 10
  3725. #endif
  3726. #ifndef R_ARM_CALL
  3727. # define R_ARM_CALL 28
  3728. #endif
  3729. #ifndef R_ARM_JUMP24
  3730. # define R_ARM_JUMP24 29
  3731. #endif
  3732. #ifndef R_ARM_THM_JUMP24
  3733. # define R_ARM_THM_JUMP24 30
  3734. #endif
  3735. #ifndef R_ARM_TARGET1
  3736. # define R_ARM_TARGET1 38
  3737. #endif
  3738. #ifndef R_ARM_MOVW_ABS_NC
  3739. # define R_ARM_MOVW_ABS_NC 43
  3740. #endif
  3741. #ifndef R_ARM_MOVT_ABS
  3742. # define R_ARM_MOVT_ABS 44
  3743. #endif
  3744. #ifndef R_ARM_THM_MOVW_ABS_NC
  3745. # define R_ARM_THM_MOVW_ABS_NC 47
  3746. #endif
  3747. #ifndef R_ARM_THM_MOVT_ABS
  3748. # define R_ARM_THM_MOVT_ABS 48
  3749. #endif
  3750. #ifndef R_ARM_THM_JUMP11
  3751. # define R_ARM_THM_JUMP11 102
  3752. #endif
  3753. #ifndef R_ARM_THM_JUMP8
  3754. # define R_ARM_THM_JUMP8 103
  3755. #endif
  3756. /*
  3757. * Define a set of types which can be used for both ELF32 and ELF64
  3758. */
  3759. #ifdef ELF_64BIT
  3760. #define ELFCLASS ELFCLASS64
  3761. #define Elf_Addr Elf64_Addr
  3762. #define Elf_Word Elf64_Word
  3763. #define Elf_Sword Elf64_Sword
  3764. #define Elf_Ehdr Elf64_Ehdr
  3765. #define Elf_Phdr Elf64_Phdr
  3766. #define Elf_Shdr Elf64_Shdr
  3767. #define Elf_Sym Elf64_Sym
  3768. #define Elf_Rel Elf64_Rel
  3769. #define Elf_Rela Elf64_Rela
  3770. #ifndef ELF_ST_TYPE
  3771. #define ELF_ST_TYPE ELF64_ST_TYPE
  3772. #endif
  3773. #ifndef ELF_ST_BIND
  3774. #define ELF_ST_BIND ELF64_ST_BIND
  3775. #endif
  3776. #ifndef ELF_R_TYPE
  3777. #define ELF_R_TYPE ELF64_R_TYPE
  3778. #endif
  3779. #ifndef ELF_R_SYM
  3780. #define ELF_R_SYM ELF64_R_SYM
  3781. #endif
  3782. #else
  3783. #define ELFCLASS ELFCLASS32
  3784. #define Elf_Addr Elf32_Addr
  3785. #define Elf_Word Elf32_Word
  3786. #define Elf_Sword Elf32_Sword
  3787. #define Elf_Ehdr Elf32_Ehdr
  3788. #define Elf_Phdr Elf32_Phdr
  3789. #define Elf_Shdr Elf32_Shdr
  3790. #define Elf_Sym Elf32_Sym
  3791. #define Elf_Rel Elf32_Rel
  3792. #define Elf_Rela Elf32_Rela
  3793. #ifndef ELF_ST_TYPE
  3794. #define ELF_ST_TYPE ELF32_ST_TYPE
  3795. #endif
  3796. #ifndef ELF_ST_BIND
  3797. #define ELF_ST_BIND ELF32_ST_BIND
  3798. #endif
  3799. #ifndef ELF_R_TYPE
  3800. #define ELF_R_TYPE ELF32_R_TYPE
  3801. #endif
  3802. #ifndef ELF_R_SYM
  3803. #define ELF_R_SYM ELF32_R_SYM
  3804. #endif
  3805. #endif
  3806. /*
  3807. * Functions to allocate entries in dynamic sections. Currently we simply
  3808. * preallocate a large number, and we don't check if a entry for the given
  3809. * target already exists (a linear search is too slow). Ideally these
  3810. * entries would be associated with symbols.
  3811. */
  3812. /* These sizes sufficient to load HSbase + HShaskell98 + a few modules */
  3813. #define GOT_SIZE 0x20000
  3814. #define FUNCTION_TABLE_SIZE 0x10000
  3815. #define PLT_SIZE 0x08000
  3816. #ifdef ELF_NEED_GOT
  3817. static Elf_Addr got[GOT_SIZE];
  3818. static unsigned int gotIndex;
  3819. static Elf_Addr gp_val = (Elf_Addr)got;
  3820. static Elf_Addr
  3821. allocateGOTEntry(Elf_Addr target)
  3822. {
  3823. Elf_Addr *entry;
  3824. if (gotIndex >= GOT_SIZE)
  3825. barf("Global offset table overflow");
  3826. entry = &got[gotIndex++];
  3827. *entry = target;
  3828. return (Elf_Addr)entry;
  3829. }
  3830. #endif
  3831. #ifdef ELF_FUNCTION_DESC
  3832. typedef struct {
  3833. Elf_Addr ip;
  3834. Elf_Addr gp;
  3835. } FunctionDesc;
  3836. static FunctionDesc functionTable[FUNCTION_TABLE_SIZE];
  3837. static unsigned int functionTableIndex;
  3838. static Elf_Addr
  3839. allocateFunctionDesc(Elf_Addr target)
  3840. {
  3841. FunctionDesc *entry;
  3842. if (functionTableIndex >= FUNCTION_TABLE_SIZE)
  3843. barf("Function table overflow");
  3844. entry = &functionTable[functionTableIndex++];
  3845. entry->ip = target;
  3846. entry->gp = (Elf_Addr)gp_val;
  3847. return (Elf_Addr)entry;
  3848. }
  3849. static Elf_Addr
  3850. copyFunctionDesc(Elf_Addr target)
  3851. {
  3852. FunctionDesc *olddesc = (FunctionDesc *)target;
  3853. FunctionDesc *newdesc;
  3854. newdesc = (FunctionDesc *)allocateFunctionDesc(olddesc->ip);
  3855. newdesc->gp = olddesc->gp;
  3856. return (Elf_Addr)newdesc;
  3857. }
  3858. #endif
  3859. #ifdef ELF_NEED_PLT
  3860. typedef struct {
  3861. unsigned char code[sizeof(plt_code)];
  3862. } PLTEntry;
  3863. static Elf_Addr
  3864. allocatePLTEntry(Elf_Addr target, ObjectCode *oc)
  3865. {
  3866. PLTEntry *plt = (PLTEntry *)oc->plt;
  3867. PLTEntry *entry;
  3868. if (oc->pltIndex >= PLT_SIZE)
  3869. barf("Procedure table overflow");
  3870. entry = &plt[oc->pltIndex++];
  3871. memcpy(entry->code, plt_code, sizeof(entry->code));
  3872. PLT_RELOC(entry->code, target);
  3873. return (Elf_Addr)entry;
  3874. }
  3875. static unsigned int
  3876. PLTSize(void)
  3877. {
  3878. return (PLT_SIZE * sizeof(PLTEntry));
  3879. }
  3880. #endif
  3881. /*
  3882. * Generic ELF functions
  3883. */
  3884. static int
  3885. ocVerifyImage_ELF ( ObjectCode* oc )
  3886. {
  3887. Elf_Shdr* shdr;
  3888. Elf_Sym* stab;
  3889. int i, j, nent, nstrtab, nsymtabs;
  3890. char* sh_strtab;
  3891. char* ehdrC = (char*)(oc->image);
  3892. Elf_Ehdr* ehdr = (Elf_Ehdr*)ehdrC;
  3893. if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
  3894. ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
  3895. ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
  3896. ehdr->e_ident[EI_MAG3] != ELFMAG3) {
  3897. errorBelch("%s: not an ELF object", oc->fileName);
  3898. return 0;
  3899. }
  3900. if (ehdr->e_ident[EI_CLASS] != ELFCLASS) {
  3901. errorBelch("%s: unsupported ELF format", oc->fileName);
  3902. return 0;
  3903. }
  3904. if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {
  3905. IF_DEBUG(linker,debugBelch( "Is little-endian\n" ));
  3906. } else
  3907. if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
  3908. IF_DEBUG(linker,debugBelch( "Is big-endian\n" ));
  3909. } else {
  3910. errorBelch("%s: unknown endiannness", oc->fileName);
  3911. return 0;
  3912. }
  3913. if (ehdr->e_type != ET_REL) {
  3914. errorBelch("%s: not a relocatable object (.o) file", oc->fileName);
  3915. return 0;
  3916. }
  3917. IF_DEBUG(linker, debugBelch( "Is a relocatable object (.o) file\n" ));
  3918. IF_DEBUG(linker,debugBelch( "Architecture is " ));
  3919. switch (ehdr->e_machine) {
  3920. #ifdef EM_ARM
  3921. case EM_ARM: IF_DEBUG(linker,debugBelch( "arm" )); break;
  3922. #endif
  3923. case EM_386: IF_DEBUG(linker,debugBelch( "x86" )); break;
  3924. #ifdef EM_SPARC32PLUS
  3925. case EM_SPARC32PLUS:
  3926. #endif
  3927. case EM_SPARC: IF_DEBUG(linker,debugBelch( "sparc" )); break;
  3928. #ifdef EM_IA_64
  3929. case EM_IA_64: IF_DEBUG(linker,debugBelch( "ia64" )); break;
  3930. #endif
  3931. case EM_PPC: IF_DEBUG(linker,debugBelch( "powerpc32" )); break;
  3932. #ifdef EM_X86_64
  3933. case EM_X86_64: IF_DEBUG(linker,debugBelch( "x86_64" )); break;
  3934. #elif defined(EM_AMD64)
  3935. case EM_AMD64: IF_DEBUG(linker,debugBelch( "amd64" )); break;
  3936. #endif
  3937. default: IF_DEBUG(linker,debugBelch( "unknown" ));
  3938. errorBelch("%s: unknown architecture (e_machine == %d)"
  3939. , oc->fileName, ehdr->e_machine);
  3940. return 0;
  3941. }
  3942. IF_DEBUG(linker,debugBelch(
  3943. "\nSection header table: start %ld, n_entries %d, ent_size %d\n",
  3944. (long)ehdr->e_shoff, ehdr->e_shnum, ehdr->e_shentsize ));
  3945. ASSERT (ehdr->e_shentsize == sizeof(Elf_Shdr));
  3946. shdr = (Elf_Shdr*) (ehdrC + ehdr->e_shoff);
  3947. if (ehdr->e_shstrndx == SHN_UNDEF) {
  3948. errorBelch("%s: no section header string table", oc->fileName);
  3949. return 0;
  3950. } else {
  3951. IF_DEBUG(linker,debugBelch( "Section header string table is section %d\n",
  3952. ehdr->e_shstrndx));
  3953. sh_strtab = ehdrC + shdr[ehdr->e_shstrndx].sh_offset;
  3954. }
  3955. for (i = 0; i < ehdr->e_shnum; i++) {
  3956. IF_DEBUG(linker,debugBelch("%2d: ", i ));
  3957. IF_DEBUG(linker,debugBelch("type=%2d ", (int)shdr[i].sh_type ));
  3958. IF_DEBUG(linker,debugBelch("size=%4d ", (int)shdr[i].sh_size ));
  3959. IF_DEBUG(linker,debugBelch("offs=%4d ", (int)shdr[i].sh_offset ));
  3960. IF_DEBUG(linker,debugBelch(" (%p .. %p) ",
  3961. ehdrC + shdr[i].sh_offset,
  3962. ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1));
  3963. #define SECTION_INDEX_VALID(ndx) (ndx > SHN_UNDEF && ndx < ehdr->e_shnum)
  3964. switch (shdr[i].sh_type) {
  3965. case SHT_REL:
  3966. case SHT_RELA:
  3967. IF_DEBUG(linker,debugBelch( shdr[i].sh_type == SHT_REL ? "Rel " : "RelA "));
  3968. if (!SECTION_INDEX_VALID(shdr[i].sh_link)) {
  3969. if (shdr[i].sh_link == SHN_UNDEF)
  3970. errorBelch("\n%s: relocation section #%d has no symbol table\n"
  3971. "This object file has probably been fully striped. "
  3972. "Such files cannot be linked.\n",
  3973. oc->archiveMemberName ? oc->archiveMemberName : oc->fileName, i);
  3974. else
  3975. errorBelch("\n%s: relocation section #%d has an invalid link field (%d)\n",
  3976. oc->archiveMemberName ? oc->archiveMemberName : oc->fileName,
  3977. i, shdr[i].sh_link);
  3978. return 0;
  3979. }
  3980. if (shdr[shdr[i].sh_link].sh_type != SHT_SYMTAB) {
  3981. errorBelch("\n%s: relocation section #%d does not link to a symbol table\n",
  3982. oc->archiveMemberName ? oc->archiveMemberName : oc->fileName, i);
  3983. return 0;
  3984. }
  3985. if (!SECTION_INDEX_VALID(shdr[i].sh_info)) {
  3986. errorBelch("\n%s: relocation section #%d has an invalid info field (%d)\n",
  3987. oc->archiveMemberName ? oc->archiveMemberName : oc->fileName,
  3988. i, shdr[i].sh_info);
  3989. return 0;
  3990. }
  3991. break;
  3992. case SHT_SYMTAB:
  3993. IF_DEBUG(linker,debugBelch("Sym "));
  3994. if (!SECTION_INDEX_VALID(shdr[i].sh_link)) {
  3995. errorBelch("\n%s: symbol table section #%d has an invalid link field (%d)\n",
  3996. oc->archiveMemberName ? oc->archiveMemberName : oc->fileName,
  3997. i, shdr[i].sh_link);
  3998. return 0;
  3999. }
  4000. if (shdr[shdr[i].sh_link].sh_type != SHT_STRTAB) {
  4001. errorBelch("\n%s: symbol table section #%d does not link to a string table\n",
  4002. oc->archiveMemberName ? oc->archiveMemberName : oc->fileName, i);
  4003. return 0;
  4004. }
  4005. break;
  4006. case SHT_STRTAB: IF_DEBUG(linker,debugBelch("Str ")); break;
  4007. default: IF_DEBUG(linker,debugBelch(" ")); break;
  4008. }
  4009. if (sh_strtab) {
  4010. IF_DEBUG(linker,debugBelch("sname=%s\n", sh_strtab + shdr[i].sh_name ));
  4011. }
  4012. }
  4013. IF_DEBUG(linker,debugBelch( "\nString tables\n" ));
  4014. nstrtab = 0;
  4015. for (i = 0; i < ehdr->e_shnum; i++) {
  4016. if (shdr[i].sh_type == SHT_STRTAB
  4017. /* Ignore the section header's string table. */
  4018. && i != ehdr->e_shstrndx
  4019. /* Ignore string tables named .stabstr, as they contain
  4020. debugging info. */
  4021. && 0 != memcmp(".stabstr", sh_strtab + shdr[i].sh_name, 8)
  4022. ) {
  4023. IF_DEBUG(linker,debugBelch(" section %d is a normal string table\n", i ));
  4024. nstrtab++;
  4025. }
  4026. }
  4027. if (nstrtab == 0) {
  4028. IF_DEBUG(linker,debugBelch(" no normal string tables (potentially, but not necessarily a problem)\n"));
  4029. }
  4030. nsymtabs = 0;
  4031. IF_DEBUG(linker,debugBelch( "Symbol tables\n" ));
  4032. for (i = 0; i < ehdr->e_shnum; i++) {
  4033. if (shdr[i].sh_type != SHT_SYMTAB) continue;
  4034. IF_DEBUG(linker,debugBelch( "section %d is a symbol table\n", i ));
  4035. nsymtabs++;
  4036. stab = (Elf_Sym*) (ehdrC + shdr[i].sh_offset);
  4037. nent = shdr[i].sh_size / sizeof(Elf_Sym);
  4038. IF_DEBUG(linker,debugBelch( " number of entries is apparently %d (%ld rem)\n",
  4039. nent,
  4040. (long)shdr[i].sh_size % sizeof(Elf_Sym)
  4041. ));
  4042. if (0 != shdr[i].sh_size % sizeof(Elf_Sym)) {
  4043. errorBelch("%s: non-integral number of symbol table entries", oc->fileName);
  4044. return 0;
  4045. }
  4046. for (j = 0; j < nent; j++) {
  4047. IF_DEBUG(linker,debugBelch(" %2d ", j ));
  4048. IF_DEBUG(linker,debugBelch(" sec=%-5d size=%-3d val=%5p ",
  4049. (int)stab[j].st_shndx,
  4050. (int)stab[j].st_size,
  4051. (char*)stab[j].st_value ));
  4052. IF_DEBUG(linker,debugBelch("type=" ));
  4053. switch (ELF_ST_TYPE(stab[j].st_info)) {
  4054. case STT_NOTYPE: IF_DEBUG(linker,debugBelch("notype " )); break;
  4055. case STT_OBJECT: IF_DEBUG(linker,debugBelch("object " )); break;
  4056. case STT_FUNC : IF_DEBUG(linker,debugBelch("func " )); break;
  4057. case STT_SECTION: IF_DEBUG(linker,debugBelch("section" )); break;
  4058. case STT_FILE: IF_DEBUG(linker,debugBelch("file " )); break;
  4059. default: IF_DEBUG(linker,debugBelch("? " )); break;
  4060. }
  4061. IF_DEBUG(linker,debugBelch(" " ));
  4062. IF_DEBUG(linker,debugBelch("bind=" ));
  4063. switch (ELF_ST_BIND(stab[j].st_info)) {
  4064. case STB_LOCAL : IF_DEBUG(linker,debugBelch("local " )); break;
  4065. case STB_GLOBAL: IF_DEBUG(linker,debugBelch("global" )); break;
  4066. case STB_WEAK : IF_DEBUG(linker,debugBelch("weak " )); break;
  4067. default: IF_DEBUG(linker,debugBelch("? " )); break;
  4068. }
  4069. IF_DEBUG(linker,debugBelch(" " ));
  4070. IF_DEBUG(linker,debugBelch("name=%s\n",
  4071. ehdrC + shdr[shdr[i].sh_link].sh_offset
  4072. + stab[j].st_name ));
  4073. }
  4074. }
  4075. if (nsymtabs == 0) {
  4076. // Not having a symbol table is not in principle a problem.
  4077. // When an object file has no symbols then the 'strip' program
  4078. // typically will remove the symbol table entirely.
  4079. IF_DEBUG(linker,debugBelch(" no symbol tables (potentially, but not necessarily a problem)\n"));
  4080. }
  4081. return 1;
  4082. }
  4083. static int getSectionKind_ELF( Elf_Shdr *hdr, int *is_bss )
  4084. {
  4085. *is_bss = FALSE;
  4086. if (hdr->sh_type == SHT_PROGBITS
  4087. && (hdr->sh_flags & SHF_ALLOC) && (hdr->sh_flags & SHF_EXECINSTR)) {
  4088. /* .text-style section */
  4089. return SECTIONKIND_CODE_OR_RODATA;
  4090. }
  4091. if (hdr->sh_type == SHT_PROGBITS
  4092. && (hdr->sh_flags & SHF_ALLOC) && (hdr->sh_flags & SHF_WRITE)) {
  4093. /* .data-style section */
  4094. return SECTIONKIND_RWDATA;
  4095. }
  4096. if (hdr->sh_type == SHT_PROGBITS
  4097. && (hdr->sh_flags & SHF_ALLOC) && !(hdr->sh_flags & SHF_WRITE)) {
  4098. /* .rodata-style section */
  4099. return SECTIONKIND_CODE_OR_RODATA;
  4100. }
  4101. if (hdr->sh_type == SHT_NOBITS
  4102. && (hdr->sh_flags & SHF_ALLOC) && (hdr->sh_flags & SHF_WRITE)) {
  4103. /* .bss-style section */
  4104. *is_bss = TRUE;
  4105. return SECTIONKIND_RWDATA;
  4106. }
  4107. return SECTIONKIND_OTHER;
  4108. }
  4109. static int
  4110. ocGetNames_ELF ( ObjectCode* oc )
  4111. {
  4112. int i, j, nent;
  4113. Elf_Sym* stab;
  4114. char* ehdrC = (char*)(oc->image);
  4115. Elf_Ehdr* ehdr = (Elf_Ehdr*)ehdrC;
  4116. char* strtab;
  4117. Elf_Shdr* shdr = (Elf_Shdr*) (ehdrC + ehdr->e_shoff);
  4118. ASSERT(symhash != NULL);
  4119. for (i = 0; i < ehdr->e_shnum; i++) {
  4120. /* Figure out what kind of section it is. Logic derived from
  4121. Figure 1.14 ("Special Sections") of the ELF document
  4122. ("Portable Formats Specification, Version 1.1"). */
  4123. int is_bss = FALSE;
  4124. SectionKind kind = getSectionKind_ELF(&shdr[i], &is_bss);
  4125. if (is_bss && shdr[i].sh_size > 0) {
  4126. /* This is a non-empty .bss section. Allocate zeroed space for
  4127. it, and set its .sh_offset field such that
  4128. ehdrC + .sh_offset == addr_of_zeroed_space. */
  4129. char* zspace = stgCallocBytes(1, shdr[i].sh_size,
  4130. "ocGetNames_ELF(BSS)");
  4131. shdr[i].sh_offset = ((char*)zspace) - ((char*)ehdrC);
  4132. /*
  4133. debugBelch("BSS section at 0x%x, size %d\n",
  4134. zspace, shdr[i].sh_size);
  4135. */
  4136. }
  4137. /* fill in the section info */
  4138. if (kind != SECTIONKIND_OTHER && shdr[i].sh_size > 0) {
  4139. addProddableBlock(oc, ehdrC + shdr[i].sh_offset, shdr[i].sh_size);
  4140. addSection(oc, kind, ehdrC + shdr[i].sh_offset,
  4141. ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1);
  4142. }
  4143. if (shdr[i].sh_type != SHT_SYMTAB) continue;
  4144. /* copy stuff into this module's object symbol table */
  4145. stab = (Elf_Sym*) (ehdrC + shdr[i].sh_offset);
  4146. strtab = ehdrC + shdr[shdr[i].sh_link].sh_offset;
  4147. nent = shdr[i].sh_size / sizeof(Elf_Sym);
  4148. oc->n_symbols = nent;
  4149. oc->symbols = stgMallocBytes(oc->n_symbols * sizeof(char*),
  4150. "ocGetNames_ELF(oc->symbols)");
  4151. //TODO: we ignore local symbols anyway right? So we can use the
  4152. // shdr[i].sh_info to get the index of the first non-local symbol
  4153. // ie we should use j = shdr[i].sh_info
  4154. for (j = 0; j < nent; j++) {
  4155. char isLocal = FALSE; /* avoids uninit-var warning */
  4156. char* ad = NULL;
  4157. char* nm = strtab + stab[j].st_name;
  4158. int secno = stab[j].st_shndx;
  4159. /* Figure out if we want to add it; if so, set ad to its
  4160. address. Otherwise leave ad == NULL. */
  4161. if (secno == SHN_COMMON) {
  4162. isLocal = FALSE;
  4163. ad = stgCallocBytes(1, stab[j].st_size, "ocGetNames_ELF(COMMON)");
  4164. /*
  4165. debugBelch("COMMON symbol, size %d name %s\n",
  4166. stab[j].st_size, nm);
  4167. */
  4168. /* Pointless to do addProddableBlock() for this area,
  4169. since the linker should never poke around in it. */
  4170. }
  4171. else
  4172. if ( ( ELF_ST_BIND(stab[j].st_info)==STB_GLOBAL
  4173. || ELF_ST_BIND(stab[j].st_info)==STB_LOCAL
  4174. )
  4175. /* and not an undefined symbol */
  4176. && stab[j].st_shndx != SHN_UNDEF
  4177. /* and not in a "special section" */
  4178. && stab[j].st_shndx < SHN_LORESERVE
  4179. &&
  4180. /* and it's a not a section or string table or anything silly */
  4181. ( ELF_ST_TYPE(stab[j].st_info)==STT_FUNC ||
  4182. ELF_ST_TYPE(stab[j].st_info)==STT_OBJECT ||
  4183. ELF_ST_TYPE(stab[j].st_info)==STT_NOTYPE
  4184. )
  4185. ) {
  4186. /* Section 0 is the undefined section, hence > and not >=. */
  4187. ASSERT(secno > 0 && secno < ehdr->e_shnum);
  4188. /*
  4189. if (shdr[secno].sh_type == SHT_NOBITS) {
  4190. debugBelch(" BSS symbol, size %d off %d name %s\n",
  4191. stab[j].st_size, stab[j].st_value, nm);
  4192. }
  4193. */
  4194. ad = ehdrC + shdr[ secno ].sh_offset + stab[j].st_value;
  4195. if (ELF_ST_BIND(stab[j].st_info)==STB_LOCAL) {
  4196. isLocal = TRUE;
  4197. } else {
  4198. #ifdef ELF_FUNCTION_DESC
  4199. /* dlsym() and the initialisation table both give us function
  4200. * descriptors, so to be consistent we store function descriptors
  4201. * in the symbol table */
  4202. if (ELF_ST_TYPE(stab[j].st_info) == STT_FUNC)
  4203. ad = (char *)allocateFunctionDesc((Elf_Addr)ad);
  4204. #endif
  4205. IF_DEBUG(linker,debugBelch( "addOTabName(GLOB): %10p %s %s\n",
  4206. ad, oc->fileName, nm ));
  4207. isLocal = FALSE;
  4208. }
  4209. }
  4210. /* And the decision is ... */
  4211. if (ad != NULL) {
  4212. ASSERT(nm != NULL);
  4213. oc->symbols[j] = nm;
  4214. /* Acquire! */
  4215. if (isLocal) {
  4216. /* Ignore entirely. */
  4217. } else {
  4218. ghciInsertStrHashTable(oc->fileName, symhash, nm, ad);
  4219. }
  4220. } else {
  4221. /* Skip. */
  4222. IF_DEBUG(linker,debugBelch( "skipping `%s'\n",
  4223. strtab + stab[j].st_name ));
  4224. /*
  4225. debugBelch(
  4226. "skipping bind = %d, type = %d, shndx = %d `%s'\n",
  4227. (int)ELF_ST_BIND(stab[j].st_info),
  4228. (int)ELF_ST_TYPE(stab[j].st_info),
  4229. (int)stab[j].st_shndx,
  4230. strtab + stab[j].st_name
  4231. );
  4232. */
  4233. oc->symbols[j] = NULL;
  4234. }
  4235. }
  4236. }
  4237. return 1;
  4238. }
  4239. /* Do ELF relocations which lack an explicit addend. All x86-linux
  4240. and arm-linux relocations appear to be of this form. */
  4241. static int
  4242. do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
  4243. Elf_Shdr* shdr, int shnum )
  4244. {
  4245. int j;
  4246. char *symbol;
  4247. Elf_Word* targ;
  4248. Elf_Rel* rtab = (Elf_Rel*) (ehdrC + shdr[shnum].sh_offset);
  4249. Elf_Sym* stab;
  4250. char* strtab;
  4251. int nent = shdr[shnum].sh_size / sizeof(Elf_Rel);
  4252. int target_shndx = shdr[shnum].sh_info;
  4253. int symtab_shndx = shdr[shnum].sh_link;
  4254. int strtab_shndx = shdr[symtab_shndx].sh_link;
  4255. stab = (Elf_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
  4256. strtab= (char*) (ehdrC + shdr[ strtab_shndx ].sh_offset);
  4257. targ = (Elf_Word*)(ehdrC + shdr[ target_shndx ].sh_offset);
  4258. IF_DEBUG(linker,debugBelch( "relocations for section %d using symtab %d and strtab %d\n",
  4259. target_shndx, symtab_shndx, strtab_shndx ));
  4260. /* Skip sections that we're not interested in. */
  4261. {
  4262. int is_bss;
  4263. SectionKind kind = getSectionKind_ELF(&shdr[target_shndx], &is_bss);
  4264. if (kind == SECTIONKIND_OTHER) {
  4265. IF_DEBUG(linker,debugBelch( "skipping (target section not loaded)"));
  4266. return 1;
  4267. }
  4268. }
  4269. for (j = 0; j < nent; j++) {
  4270. Elf_Addr offset = rtab[j].r_offset;
  4271. Elf_Addr info = rtab[j].r_info;
  4272. Elf_Addr P = ((Elf_Addr)targ) + offset;
  4273. Elf_Word* pP = (Elf_Word*)P;
  4274. #if defined(i386_HOST_ARCH) || defined(DEBUG)
  4275. Elf_Addr A = *pP;
  4276. #endif
  4277. Elf_Addr S;
  4278. void* S_tmp;
  4279. #ifdef i386_HOST_ARCH
  4280. Elf_Addr value;
  4281. #endif
  4282. StgStablePtr stablePtr;
  4283. StgPtr stableVal;
  4284. #ifdef arm_HOST_ARCH
  4285. int is_target_thm=0, T=0;
  4286. #endif
  4287. IF_DEBUG(linker,debugBelch( "Rel entry %3d is raw(%6p %6p)",
  4288. j, (void*)offset, (void*)info ));
  4289. if (!info) {
  4290. IF_DEBUG(linker,debugBelch( " ZERO" ));
  4291. S = 0;
  4292. } else {
  4293. Elf_Sym sym = stab[ELF_R_SYM(info)];
  4294. /* First see if it is a local symbol. */
  4295. if (ELF_ST_BIND(sym.st_info) == STB_LOCAL) {
  4296. /* Yes, so we can get the address directly from the ELF symbol
  4297. table. */
  4298. symbol = sym.st_name==0 ? "(noname)" : strtab+sym.st_name;
  4299. S = (Elf_Addr)
  4300. (ehdrC + shdr[ sym.st_shndx ].sh_offset
  4301. + stab[ELF_R_SYM(info)].st_value);
  4302. } else {
  4303. symbol = strtab + sym.st_name;
  4304. stablePtr = (StgStablePtr)lookupHashTable(stablehash, (StgWord)symbol);
  4305. if (NULL == stablePtr) {
  4306. /* No, so look up the name in our global table. */
  4307. S_tmp = lookupSymbol( symbol );
  4308. S = (Elf_Addr)S_tmp;
  4309. } else {
  4310. stableVal = deRefStablePtr( stablePtr );
  4311. S_tmp = stableVal;
  4312. S = (Elf_Addr)S_tmp;
  4313. }
  4314. }
  4315. if (!S) {
  4316. errorBelch("%s: unknown symbol `%s'", oc->fileName, symbol);
  4317. return 0;
  4318. }
  4319. IF_DEBUG(linker,debugBelch( "`%s' resolves to %p\n", symbol, (void*)S ));
  4320. #ifdef arm_HOST_ARCH
  4321. // Thumb instructions have bit 0 of symbol's st_value set
  4322. is_target_thm = S & 0x1;
  4323. T = sym.st_info & STT_FUNC && is_target_thm;
  4324. // Make sure we clear bit 0. Strictly speaking we should have done
  4325. // this to st_value above but I believe alignment requirements should
  4326. // ensure that no instructions start on an odd address
  4327. S &= ~1;
  4328. #endif
  4329. }
  4330. IF_DEBUG(linker,debugBelch( "Reloc: P = %p S = %p A = %p\n",
  4331. (void*)P, (void*)S, (void*)A ));
  4332. checkProddableBlock ( oc, pP, sizeof(Elf_Word) );
  4333. #ifdef i386_HOST_ARCH
  4334. value = S + A;
  4335. #endif
  4336. switch (ELF_R_TYPE(info)) {
  4337. # ifdef i386_HOST_ARCH
  4338. case R_386_32: *pP = value; break;
  4339. case R_386_PC32: *pP = value - P; break;
  4340. # endif
  4341. # ifdef arm_HOST_ARCH
  4342. case R_ARM_ABS32:
  4343. case R_ARM_TARGET1: // Specified by Linux ARM ABI to be equivalent to ABS32
  4344. *(Elf32_Word *)P += S;
  4345. *(Elf32_Word *)P |= T;
  4346. break;
  4347. case R_ARM_REL32:
  4348. *(Elf32_Word *)P += S;
  4349. *(Elf32_Word *)P |= T;
  4350. *(Elf32_Word *)P -= P;
  4351. break;
  4352. case R_ARM_CALL:
  4353. case R_ARM_JUMP24:
  4354. {
  4355. StgWord32 *word = (StgWord32 *)P;
  4356. StgInt32 imm = (*word & 0x00ffffff) << 2;
  4357. StgInt32 offset;
  4358. int overflow;
  4359. // Sign extend 24 to 32 bits
  4360. if (imm & 0x02000000)
  4361. imm -= 0x04000000;
  4362. offset = ((S + imm) | T) - P;
  4363. overflow = offset <= (StgInt32)0xfe000000 || offset >= (StgInt32)0x02000000;
  4364. if ((is_target_thm && ELF_R_TYPE(info) == R_ARM_JUMP24) || overflow) {
  4365. // Generate veneer
  4366. // The +8 below is to undo the PC-bias compensation done by the object producer
  4367. SymbolExtra *extra = makeArmSymbolExtra(oc, ELF_R_SYM(info), S+imm+8, 0, is_target_thm);
  4368. // The -8 below is to compensate for PC bias
  4369. offset = (StgWord32) &extra->jumpIsland - P - 8;
  4370. offset &= ~1; // Clear thumb indicator bit
  4371. } else if (is_target_thm && ELF_R_TYPE(info) == R_ARM_CALL) {
  4372. StgWord32 cond = (*word & 0xf0000000) >> 28;
  4373. if (cond == 0xe) {
  4374. // Change instruction to BLX
  4375. *word |= 0xf0000000; // Set first nibble
  4376. *word = (*word & ~0x01ffffff)
  4377. | ((offset >> 2) & 0x00ffffff) // imm24
  4378. | ((offset & 0x2) << 23); // H
  4379. break;
  4380. } else {
  4381. errorBelch("%s: Can't transition from ARM to Thumb when cond != 0xe\n",
  4382. oc->fileName);
  4383. return 0;
  4384. }
  4385. }
  4386. offset >>= 2;
  4387. *word = (*word & ~0x00ffffff)
  4388. | (offset & 0x00ffffff);
  4389. break;
  4390. }
  4391. case R_ARM_MOVT_ABS:
  4392. case R_ARM_MOVW_ABS_NC:
  4393. {
  4394. StgWord32 *word = (StgWord32 *)P;
  4395. StgInt32 offset = ((*word & 0xf0000) >> 4)
  4396. | (*word & 0xfff);
  4397. // Sign extend from 16 to 32 bits
  4398. offset = (offset ^ 0x8000) - 0x8000;
  4399. offset += S;
  4400. if (ELF_R_TYPE(info) == R_ARM_MOVT_ABS)
  4401. offset >>= 16;
  4402. else
  4403. offset |= T;
  4404. *word = (*word & 0xfff0f000)
  4405. | ((offset & 0xf000) << 4)
  4406. | (offset & 0x0fff);
  4407. break;
  4408. }
  4409. case R_ARM_THM_CALL:
  4410. case R_ARM_THM_JUMP24:
  4411. {
  4412. StgWord16 *upper = (StgWord16 *)P;
  4413. StgWord16 *lower = (StgWord16 *)(P + 2);
  4414. int overflow;
  4415. int to_thm = (*lower >> 12) & 1;
  4416. int sign = (*upper >> 10) & 1;
  4417. int j1, j2, i1, i2;
  4418. // Decode immediate value
  4419. j1 = (*lower >> 13) & 1; i1 = ~(j1 ^ sign) & 1;
  4420. j2 = (*lower >> 11) & 1; i2 = ~(j2 ^ sign) & 1;
  4421. StgInt32 imm = (sign << 24)
  4422. | (i1 << 23)
  4423. | (i2 << 22)
  4424. | ((*upper & 0x03ff) << 12)
  4425. | ((*lower & 0x07ff) << 1);
  4426. // Sign extend 25 to 32 bits
  4427. if (imm & 0x01000000)
  4428. imm -= 0x02000000;
  4429. offset = ((imm + S) | T) - P;
  4430. overflow = offset <= (StgWord32)0xff000000 || offset >= (StgWord32)0x01000000;
  4431. if ((!is_target_thm && ELF_R_TYPE(info) == R_ARM_THM_JUMP24) || overflow) {
  4432. // Generate veneer
  4433. SymbolExtra *extra = makeArmSymbolExtra(oc, ELF_R_SYM(info), S+imm+4, 1, is_target_thm);
  4434. offset = (StgWord32) &extra->jumpIsland - P - 4;
  4435. to_thm = 1;
  4436. } else if (!is_target_thm && ELF_R_TYPE(info) == R_ARM_THM_CALL) {
  4437. offset &= ~0x3;
  4438. to_thm = 0;
  4439. }
  4440. // Reencode instruction
  4441. i1 = ~(offset >> 23) & 1; j1 = sign ^ i1;
  4442. i2 = ~(offset >> 22) & 1; j2 = sign ^ i2;
  4443. *upper = ( (*upper & 0xf800)
  4444. | (sign << 10)
  4445. | ((offset >> 12) & 0x03ff) );
  4446. *lower = ( (*lower & 0xd000)
  4447. | (j1 << 13)
  4448. | (to_thm << 12)
  4449. | (j2 << 11)
  4450. | ((offset >> 1) & 0x07ff) );
  4451. break;
  4452. }
  4453. case R_ARM_THM_MOVT_ABS:
  4454. case R_ARM_THM_MOVW_ABS_NC:
  4455. {
  4456. StgWord16 *upper = (StgWord16 *)P;
  4457. StgWord16 *lower = (StgWord16 *)(P + 2);
  4458. StgInt32 offset = ((*upper & 0x000f) << 12)
  4459. | ((*upper & 0x0400) << 1)
  4460. | ((*lower & 0x7000) >> 4)
  4461. | (*lower & 0x00ff);
  4462. offset = (offset ^ 0x8000) - 0x8000; // Sign extend
  4463. offset += S;
  4464. if (ELF_R_TYPE(info) == R_ARM_THM_MOVW_ABS_NC)
  4465. offset |= T;
  4466. else if (ELF_R_TYPE(info) == R_ARM_THM_MOVT_ABS)
  4467. offset >>= 16;
  4468. *upper = ( (*upper & 0xfbf0)
  4469. | ((offset & 0xf000) >> 12)
  4470. | ((offset & 0x0800) >> 1) );
  4471. *lower = ( (*lower & 0x8f00)
  4472. | ((offset & 0x0700) << 4)
  4473. | (offset & 0x00ff) );
  4474. break;
  4475. }
  4476. case R_ARM_THM_JUMP8:
  4477. {
  4478. StgWord16 *word = (StgWord16 *)P;
  4479. StgWord offset = *word & 0x01fe;
  4480. offset += S - P;
  4481. if (!is_target_thm) {
  4482. errorBelch("%s: Thumb to ARM transition with JUMP8 relocation not supported\n",
  4483. oc->fileName);
  4484. return 0;
  4485. }
  4486. *word = (*word & ~0x01fe)
  4487. | (offset & 0x01fe);
  4488. break;
  4489. }
  4490. case R_ARM_THM_JUMP11:
  4491. {
  4492. StgWord16 *word = (StgWord16 *)P;
  4493. StgWord offset = *word & 0x0ffe;
  4494. offset += S - P;
  4495. if (!is_target_thm) {
  4496. errorBelch("%s: Thumb to ARM transition with JUMP11 relocation not supported\n",
  4497. oc->fileName);
  4498. return 0;
  4499. }
  4500. *word = (*word & ~0x0ffe)
  4501. | (offset & 0x0ffe);
  4502. break;
  4503. }
  4504. # endif // arm_HOST_ARCH
  4505. default:
  4506. errorBelch("%s: unhandled ELF relocation(Rel) type %" FMT_Word "\n",
  4507. oc->fileName, (W_)ELF_R_TYPE(info));
  4508. return 0;
  4509. }
  4510. }
  4511. return 1;
  4512. }
  4513. /* Do ELF relocations for which explicit addends are supplied.
  4514. sparc-solaris relocations appear to be of this form. */
  4515. static int
  4516. do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC,
  4517. Elf_Shdr* shdr, int shnum )
  4518. {
  4519. int j;
  4520. char *symbol = NULL;
  4521. Elf_Rela* rtab = (Elf_Rela*) (ehdrC + shdr[shnum].sh_offset);
  4522. Elf_Sym* stab;
  4523. char* strtab;
  4524. int nent = shdr[shnum].sh_size / sizeof(Elf_Rela);
  4525. int symtab_shndx = shdr[shnum].sh_link;
  4526. int strtab_shndx = shdr[symtab_shndx].sh_link;
  4527. #if defined(DEBUG) || defined(sparc_HOST_ARCH) || defined(ia64_HOST_ARCH) || defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
  4528. /* This #ifdef only serves to avoid unused-var warnings. */
  4529. Elf_Addr targ;
  4530. int target_shndx = shdr[shnum].sh_info;
  4531. #endif
  4532. stab = (Elf_Sym*) (ehdrC + shdr[ symtab_shndx ].sh_offset);
  4533. strtab= (char*) (ehdrC + shdr[ strtab_shndx ].sh_offset);
  4534. #if defined(DEBUG) || defined(sparc_HOST_ARCH) || defined(ia64_HOST_ARCH) || defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
  4535. /* This #ifdef only serves to avoid set-but-not-used warnings */
  4536. targ = (Elf_Addr) (ehdrC + shdr[ target_shndx ].sh_offset);
  4537. #endif
  4538. IF_DEBUG(linker,debugBelch( "relocations for section %d using symtab %d\n",
  4539. target_shndx, symtab_shndx ));
  4540. for (j = 0; j < nent; j++) {
  4541. #if defined(DEBUG) || defined(sparc_HOST_ARCH) || defined(ia64_HOST_ARCH) || defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
  4542. /* This #ifdef only serves to avoid unused-var warnings. */
  4543. Elf_Addr offset = rtab[j].r_offset;
  4544. Elf_Addr P = targ + offset;
  4545. Elf_Addr A = rtab[j].r_addend;
  4546. #endif
  4547. #if defined(sparc_HOST_ARCH) || defined(ia64_HOST_ARCH) || defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
  4548. Elf_Addr value;
  4549. #endif
  4550. Elf_Addr info = rtab[j].r_info;
  4551. Elf_Addr S;
  4552. void* S_tmp;
  4553. # if defined(sparc_HOST_ARCH)
  4554. Elf_Word* pP = (Elf_Word*)P;
  4555. Elf_Word w1, w2;
  4556. # elif defined(powerpc_HOST_ARCH)
  4557. Elf_Sword delta;
  4558. # endif
  4559. IF_DEBUG(linker,debugBelch( "Rel entry %3d is raw(%6p %6p %6p) ",
  4560. j, (void*)offset, (void*)info,
  4561. (void*)A ));
  4562. if (!info) {
  4563. IF_DEBUG(linker,debugBelch( " ZERO" ));
  4564. S = 0;
  4565. } else {
  4566. Elf_Sym sym = stab[ELF_R_SYM(info)];
  4567. /* First see if it is a local symbol. */
  4568. if (ELF_ST_BIND(sym.st_info) == STB_LOCAL) {
  4569. /* Yes, so we can get the address directly from the ELF symbol
  4570. table. */
  4571. symbol = sym.st_name==0 ? "(noname)" : strtab+sym.st_name;
  4572. S = (Elf_Addr)
  4573. (ehdrC + shdr[ sym.st_shndx ].sh_offset
  4574. + stab[ELF_R_SYM(info)].st_value);
  4575. #ifdef ELF_FUNCTION_DESC
  4576. /* Make a function descriptor for this function */
  4577. if (S && ELF_ST_TYPE(sym.st_info) == STT_FUNC) {
  4578. S = allocateFunctionDesc(S + A);
  4579. A = 0;
  4580. }
  4581. #endif
  4582. } else {
  4583. /* No, so look up the name in our global table. */
  4584. symbol = strtab + sym.st_name;
  4585. S_tmp = lookupSymbol( symbol );
  4586. S = (Elf_Addr)S_tmp;
  4587. #ifdef ELF_FUNCTION_DESC
  4588. /* If a function, already a function descriptor - we would
  4589. have to copy it to add an offset. */
  4590. if (S && (ELF_ST_TYPE(sym.st_info) == STT_FUNC) && (A != 0))
  4591. errorBelch("%s: function %s with addend %p", oc->fileName, symbol, (void *)A);
  4592. #endif
  4593. }
  4594. if (!S) {
  4595. errorBelch("%s: unknown symbol `%s'", oc->fileName, symbol);
  4596. return 0;
  4597. }
  4598. IF_DEBUG(linker,debugBelch( "`%s' resolves to %p", symbol, (void*)S ));
  4599. }
  4600. IF_DEBUG(linker,debugBelch("Reloc: P = %p S = %p A = %p\n",
  4601. (void*)P, (void*)S, (void*)A ));
  4602. /* checkProddableBlock ( oc, (void*)P ); */
  4603. #if defined(sparc_HOST_ARCH) || defined(ia64_HOST_ARCH) || defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
  4604. value = S + A;
  4605. #endif
  4606. switch (ELF_R_TYPE(info)) {
  4607. # if defined(sparc_HOST_ARCH)
  4608. case R_SPARC_WDISP30:
  4609. w1 = *pP & 0xC0000000;
  4610. w2 = (Elf_Word)((value - P) >> 2);
  4611. ASSERT((w2 & 0xC0000000) == 0);
  4612. w1 |= w2;
  4613. *pP = w1;
  4614. break;
  4615. case R_SPARC_HI22:
  4616. w1 = *pP & 0xFFC00000;
  4617. w2 = (Elf_Word)(value >> 10);
  4618. ASSERT((w2 & 0xFFC00000) == 0);
  4619. w1 |= w2;
  4620. *pP = w1;
  4621. break;
  4622. case R_SPARC_LO10:
  4623. w1 = *pP & ~0x3FF;
  4624. w2 = (Elf_Word)(value & 0x3FF);
  4625. ASSERT((w2 & ~0x3FF) == 0);
  4626. w1 |= w2;
  4627. *pP = w1;
  4628. break;
  4629. /* According to the Sun documentation:
  4630. R_SPARC_UA32
  4631. This relocation type resembles R_SPARC_32, except it refers to an
  4632. unaligned word. That is, the word to be relocated must be treated
  4633. as four separate bytes with arbitrary alignment, not as a word
  4634. aligned according to the architecture requirements.
  4635. */
  4636. case R_SPARC_UA32:
  4637. w2 = (Elf_Word)value;
  4638. // SPARC doesn't do misaligned writes of 32 bit words,
  4639. // so we have to do this one byte-at-a-time.
  4640. char *pPc = (char*)pP;
  4641. pPc[0] = (char) ((Elf_Word)(w2 & 0xff000000) >> 24);
  4642. pPc[1] = (char) ((Elf_Word)(w2 & 0x00ff0000) >> 16);
  4643. pPc[2] = (char) ((Elf_Word)(w2 & 0x0000ff00) >> 8);
  4644. pPc[3] = (char) ((Elf_Word)(w2 & 0x000000ff));
  4645. break;
  4646. case R_SPARC_32:
  4647. w2 = (Elf_Word)value;
  4648. *pP = w2;
  4649. break;
  4650. # elif defined(powerpc_HOST_ARCH)
  4651. case R_PPC_ADDR16_LO:
  4652. *(Elf32_Half*) P = value;
  4653. break;
  4654. case R_PPC_ADDR16_HI:
  4655. *(Elf32_Half*) P = value >> 16;
  4656. break;
  4657. case R_PPC_ADDR16_HA:
  4658. *(Elf32_Half*) P = (value + 0x8000) >> 16;
  4659. break;
  4660. case R_PPC_ADDR32:
  4661. *(Elf32_Word *) P = value;
  4662. break;
  4663. case R_PPC_REL32:
  4664. *(Elf32_Word *) P = value - P;
  4665. break;
  4666. case R_PPC_REL24:
  4667. delta = value - P;
  4668. if( delta << 6 >> 6 != delta )
  4669. {
  4670. value = (Elf_Addr) (&makeSymbolExtra( oc, ELF_R_SYM(info), value )
  4671. ->jumpIsland);
  4672. delta = value - P;
  4673. if( value == 0 || delta << 6 >> 6 != delta )
  4674. {
  4675. barf( "Unable to make SymbolExtra for #%d",
  4676. ELF_R_SYM(info) );
  4677. return 0;
  4678. }
  4679. }
  4680. *(Elf_Word *) P = (*(Elf_Word *) P & 0xfc000003)
  4681. | (delta & 0x3fffffc);
  4682. break;
  4683. # endif
  4684. #if x86_64_HOST_ARCH
  4685. case R_X86_64_64:
  4686. *(Elf64_Xword *)P = value;
  4687. break;
  4688. case R_X86_64_PC32:
  4689. {
  4690. #if defined(ALWAYS_PIC)
  4691. barf("R_X86_64_PC32 relocation, but ALWAYS_PIC.");
  4692. #else
  4693. StgInt64 off = value - P;
  4694. if (off >= 0x7fffffffL || off < -0x80000000L) {
  4695. #if X86_64_ELF_NONPIC_HACK
  4696. StgInt64 pltAddress = (StgInt64) &makeSymbolExtra(oc, ELF_R_SYM(info), S)
  4697. -> jumpIsland;
  4698. off = pltAddress + A - P;
  4699. #else
  4700. barf("R_X86_64_PC32 relocation out of range: %s = %p\nRecompile %s with -fPIC.",
  4701. symbol, off, oc->fileName );
  4702. #endif
  4703. }
  4704. *(Elf64_Word *)P = (Elf64_Word)off;
  4705. #endif
  4706. break;
  4707. }
  4708. case R_X86_64_PC64:
  4709. {
  4710. StgInt64 off = value - P;
  4711. *(Elf64_Word *)P = (Elf64_Word)off;
  4712. break;
  4713. }
  4714. case R_X86_64_32:
  4715. #if defined(ALWAYS_PIC)
  4716. barf("R_X86_64_32 relocation, but ALWAYS_PIC.");
  4717. #else
  4718. if (value >= 0x7fffffffL) {
  4719. #if X86_64_ELF_NONPIC_HACK
  4720. StgInt64 pltAddress = (StgInt64) &makeSymbolExtra(oc, ELF_R_SYM(info), S)
  4721. -> jumpIsland;
  4722. value = pltAddress + A;
  4723. #else
  4724. barf("R_X86_64_32 relocation out of range: %s = %p\nRecompile %s with -fPIC.",
  4725. symbol, value, oc->fileName );
  4726. #endif
  4727. }
  4728. *(Elf64_Word *)P = (Elf64_Word)value;
  4729. #endif
  4730. break;
  4731. case R_X86_64_32S:
  4732. #if defined(ALWAYS_PIC)
  4733. barf("R_X86_64_32S relocation, but ALWAYS_PIC.");
  4734. #else
  4735. if ((StgInt64)value > 0x7fffffffL || (StgInt64)value < -0x80000000L) {
  4736. #if X86_64_ELF_NONPIC_HACK
  4737. StgInt64 pltAddress = (StgInt64) &makeSymbolExtra(oc, ELF_R_SYM(info), S)
  4738. -> jumpIsland;
  4739. value = pltAddress + A;
  4740. #else
  4741. barf("R_X86_64_32S relocation out of range: %s = %p\nRecompile %s with -fPIC.",
  4742. symbol, value, oc->fileName );
  4743. #endif
  4744. }
  4745. *(Elf64_Sword *)P = (Elf64_Sword)value;
  4746. #endif
  4747. break;
  4748. case R_X86_64_GOTPCREL:
  4749. {
  4750. StgInt64 gotAddress = (StgInt64) &makeSymbolExtra(oc, ELF_R_SYM(info), S)->addr;
  4751. StgInt64 off = gotAddress + A - P;
  4752. *(Elf64_Word *)P = (Elf64_Word)off;
  4753. break;
  4754. }
  4755. #if defined(dragonfly_HOST_OS)
  4756. case R_X86_64_GOTTPOFF:
  4757. {
  4758. #if defined(ALWAYS_PIC)
  4759. barf("R_X86_64_GOTTPOFF relocation, but ALWAYS_PIC.");
  4760. #else
  4761. /* determine the offset of S to the current thread's tls
  4762. area
  4763. XXX: Move this to the beginning of function */
  4764. struct tls_info ti;
  4765. get_tls_area(0, &ti, sizeof(ti));
  4766. /* make entry in GOT that contains said offset */
  4767. StgInt64 gotEntry = (StgInt64) &makeSymbolExtra(oc, ELF_R_SYM(info),
  4768. (S - (Elf64_Addr)(ti.base)))->addr;
  4769. *(Elf64_Word *)P = gotEntry + A - P;
  4770. #endif
  4771. break;
  4772. }
  4773. #endif
  4774. case R_X86_64_PLT32:
  4775. {
  4776. #if defined(ALWAYS_PIC)
  4777. barf("R_X86_64_PLT32 relocation, but ALWAYS_PIC.");
  4778. #else
  4779. StgInt64 off = value - P;
  4780. if (off >= 0x7fffffffL || off < -0x80000000L) {
  4781. StgInt64 pltAddress = (StgInt64) &makeSymbolExtra(oc, ELF_R_SYM(info), S)
  4782. -> jumpIsland;
  4783. off = pltAddress + A - P;
  4784. }
  4785. *(Elf64_Word *)P = (Elf64_Word)off;
  4786. #endif
  4787. break;
  4788. }
  4789. #endif
  4790. default:
  4791. errorBelch("%s: unhandled ELF relocation(RelA) type %" FMT_Word "\n",
  4792. oc->fileName, (W_)ELF_R_TYPE(info));
  4793. return 0;
  4794. }
  4795. }
  4796. return 1;
  4797. }
  4798. static int
  4799. ocResolve_ELF ( ObjectCode* oc )
  4800. {
  4801. int shnum, ok;
  4802. char* ehdrC = (char*)(oc->image);
  4803. Elf_Ehdr* ehdr = (Elf_Ehdr*) ehdrC;
  4804. Elf_Shdr* shdr = (Elf_Shdr*) (ehdrC + ehdr->e_shoff);
  4805. /* Process the relocation sections. */
  4806. for (shnum = 0; shnum < ehdr->e_shnum; shnum++) {
  4807. if (shdr[shnum].sh_type == SHT_REL) {
  4808. ok = do_Elf_Rel_relocations ( oc, ehdrC, shdr, shnum );
  4809. if (!ok) return ok;
  4810. }
  4811. else
  4812. if (shdr[shnum].sh_type == SHT_RELA) {
  4813. ok = do_Elf_Rela_relocations ( oc, ehdrC, shdr, shnum );
  4814. if (!ok) return ok;
  4815. }
  4816. }
  4817. #if defined(powerpc_HOST_ARCH) || defined(arm_HOST_ARCH)
  4818. ocFlushInstructionCache( oc );
  4819. #endif
  4820. return 1;
  4821. }
  4822. /*
  4823. * PowerPC & X86_64 ELF specifics
  4824. */
  4825. #if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH) || defined(arm_HOST_ARCH)
  4826. static int ocAllocateSymbolExtras_ELF( ObjectCode *oc )
  4827. {
  4828. Elf_Ehdr *ehdr;
  4829. Elf_Shdr* shdr;
  4830. int i;
  4831. ehdr = (Elf_Ehdr *) oc->image;
  4832. shdr = (Elf_Shdr *) ( ((char *)oc->image) + ehdr->e_shoff );
  4833. for( i = 0; i < ehdr->e_shnum; i++ )
  4834. if( shdr[i].sh_type == SHT_SYMTAB )
  4835. break;
  4836. if( i == ehdr->e_shnum )
  4837. {
  4838. // Not having a symbol table is not in principle a problem.
  4839. // When an object file has no symbols then the 'strip' program
  4840. // typically will remove the symbol table entirely.
  4841. IF_DEBUG(linker, debugBelch( "The ELF file %s contains no symtab\n",
  4842. oc->archiveMemberName ? oc->archiveMemberName : oc->fileName ));
  4843. return 1;
  4844. }
  4845. if( shdr[i].sh_entsize != sizeof( Elf_Sym ) )
  4846. {
  4847. errorBelch( "The entry size (%d) of the symtab isn't %d\n",
  4848. (int) shdr[i].sh_entsize, (int) sizeof( Elf_Sym ) );
  4849. return 0;
  4850. }
  4851. return ocAllocateSymbolExtras( oc, shdr[i].sh_size / sizeof( Elf_Sym ), 0 );
  4852. }
  4853. #endif /* powerpc */
  4854. #endif /* ELF */
  4855. /* --------------------------------------------------------------------------
  4856. * Mach-O specifics
  4857. * ------------------------------------------------------------------------*/
  4858. #if defined(OBJFORMAT_MACHO)
  4859. /*
  4860. Support for MachO linking on Darwin/MacOS X
  4861. by Wolfgang Thaller (wolfgang.thaller@gmx.net)
  4862. I hereby formally apologize for the hackish nature of this code.
  4863. Things that need to be done:
  4864. *) implement ocVerifyImage_MachO
  4865. *) add still more sanity checks.
  4866. */
  4867. #if x86_64_HOST_ARCH || powerpc64_HOST_ARCH
  4868. #define mach_header mach_header_64
  4869. #define segment_command segment_command_64
  4870. #define section section_64
  4871. #define nlist nlist_64
  4872. #endif
  4873. #ifdef powerpc_HOST_ARCH
  4874. static int
  4875. ocAllocateSymbolExtras_MachO(ObjectCode* oc)
  4876. {
  4877. struct mach_header *header = (struct mach_header *) oc->image;
  4878. struct load_command *lc = (struct load_command *) (header + 1);
  4879. unsigned i;
  4880. IF_DEBUG(linker, debugBelch("ocAllocateSymbolExtras_MachO: start\n"));
  4881. for (i = 0; i < header->ncmds; i++) {
  4882. if (lc->cmd == LC_SYMTAB) {
  4883. // Find out the first and last undefined external
  4884. // symbol, so we don't have to allocate too many
  4885. // jump islands/GOT entries.
  4886. struct symtab_command *symLC = (struct symtab_command *) lc;
  4887. unsigned min = symLC->nsyms, max = 0;
  4888. struct nlist *nlist =
  4889. symLC ? (struct nlist*) ((char*) oc->image + symLC->symoff)
  4890. : NULL;
  4891. for (i = 0; i < symLC->nsyms; i++) {
  4892. if (nlist[i].n_type & N_STAB) {
  4893. ;
  4894. } else if (nlist[i].n_type & N_EXT) {
  4895. if((nlist[i].n_type & N_TYPE) == N_UNDF
  4896. && (nlist[i].n_value == 0)) {
  4897. if (i < min) {
  4898. min = i;
  4899. }
  4900. if (i > max) {
  4901. max = i;
  4902. }
  4903. }
  4904. }
  4905. }
  4906. if (max >= min) {
  4907. return ocAllocateSymbolExtras(oc, max - min + 1, min);
  4908. }
  4909. break;
  4910. }
  4911. lc = (struct load_command *) ( ((char *)lc) + lc->cmdsize );
  4912. }
  4913. return ocAllocateSymbolExtras(oc,0,0);
  4914. }
  4915. #endif
  4916. #ifdef x86_64_HOST_ARCH
  4917. static int
  4918. ocAllocateSymbolExtras_MachO(ObjectCode* oc)
  4919. {
  4920. struct mach_header *header = (struct mach_header *) oc->image;
  4921. struct load_command *lc = (struct load_command *) (header + 1);
  4922. unsigned i;
  4923. IF_DEBUG(linker, debugBelch("ocAllocateSymbolExtras_MachO: start\n"));
  4924. for (i = 0; i < header->ncmds; i++) {
  4925. if (lc->cmd == LC_SYMTAB) {
  4926. // Just allocate one entry for every symbol
  4927. struct symtab_command *symLC = (struct symtab_command *) lc;
  4928. IF_DEBUG(linker, debugBelch("ocAllocateSymbolExtras_MachO: allocate %d symbols\n", symLC->nsyms));
  4929. IF_DEBUG(linker, debugBelch("ocAllocateSymbolExtras_MachO: done\n"));
  4930. return ocAllocateSymbolExtras(oc, symLC->nsyms, 0);
  4931. }
  4932. lc = (struct load_command *) ( ((char *)lc) + lc->cmdsize );
  4933. }
  4934. IF_DEBUG(linker, debugBelch("ocAllocateSymbolExtras_MachO: allocated no symbols\n"));
  4935. IF_DEBUG(linker, debugBelch("ocAllocateSymbolExtras_MachO: done\n"));
  4936. return ocAllocateSymbolExtras(oc,0,0);
  4937. }
  4938. #endif
  4939. static int
  4940. ocVerifyImage_MachO(ObjectCode * oc)
  4941. {
  4942. char *image = (char*) oc->image;
  4943. struct mach_header *header = (struct mach_header*) image;
  4944. IF_DEBUG(linker, debugBelch("ocVerifyImage_MachO: start\n"));
  4945. #if x86_64_HOST_ARCH || powerpc64_HOST_ARCH
  4946. if(header->magic != MH_MAGIC_64) {
  4947. errorBelch("Could not load image %s: bad magic!\n"
  4948. " Expected %08x (64bit), got %08x%s\n",
  4949. oc->fileName, MH_MAGIC_64, header->magic,
  4950. header->magic == MH_MAGIC ? " (32bit)." : ".");
  4951. return 0;
  4952. }
  4953. #else
  4954. if(header->magic != MH_MAGIC) {
  4955. errorBelch("Could not load image %s: bad magic!\n"
  4956. " Expected %08x (32bit), got %08x%s\n",
  4957. oc->fileName, MH_MAGIC, header->magic,
  4958. header->magic == MH_MAGIC_64 ? " (64bit)." : ".");
  4959. return 0;
  4960. }
  4961. #endif
  4962. // FIXME: do some more verifying here
  4963. IF_DEBUG(linker, debugBelch("ocVerifyImage_MachO: done\n"));
  4964. return 1;
  4965. }
  4966. static int
  4967. resolveImports(
  4968. ObjectCode* oc,
  4969. char *image,
  4970. struct symtab_command *symLC,
  4971. struct section *sect, // ptr to lazy or non-lazy symbol pointer section
  4972. unsigned long *indirectSyms,
  4973. struct nlist *nlist)
  4974. {
  4975. unsigned i;
  4976. size_t itemSize = 4;
  4977. IF_DEBUG(linker, debugBelch("resolveImports: start\n"));
  4978. #if i386_HOST_ARCH
  4979. int isJumpTable = 0;
  4980. if (strcmp(sect->sectname,"__jump_table") == 0) {
  4981. isJumpTable = 1;
  4982. itemSize = 5;
  4983. ASSERT(sect->reserved2 == itemSize);
  4984. }
  4985. #endif
  4986. for(i = 0; i * itemSize < sect->size; i++)
  4987. {
  4988. // according to otool, reserved1 contains the first index into the indirect symbol table
  4989. struct nlist *symbol = &nlist[indirectSyms[sect->reserved1+i]];
  4990. char *nm = image + symLC->stroff + symbol->n_un.n_strx;
  4991. void *addr = NULL;
  4992. IF_DEBUG(linker, debugBelch("resolveImports: resolving %s\n", nm));
  4993. if ((symbol->n_type & N_TYPE) == N_UNDF
  4994. && (symbol->n_type & N_EXT) && (symbol->n_value != 0)) {
  4995. addr = (void*) (symbol->n_value);
  4996. IF_DEBUG(linker, debugBelch("resolveImports: undefined external %s has value %p\n", nm, addr));
  4997. } else {
  4998. addr = lookupSymbol(nm);
  4999. IF_DEBUG(linker, debugBelch("resolveImports: looking up %s, %p\n", nm, addr));
  5000. }
  5001. if (addr == NULL)
  5002. {
  5003. errorBelch("\nlookupSymbol failed in resolveImports\n"
  5004. "%s: unknown symbol `%s'", oc->fileName, nm);
  5005. return 0;
  5006. }
  5007. ASSERT(addr);
  5008. #if i386_HOST_ARCH
  5009. if (isJumpTable) {
  5010. checkProddableBlock(oc,image + sect->offset + i*itemSize, 5);
  5011. *(image + sect->offset + i * itemSize) = 0xe9; // jmp opcode
  5012. *(unsigned*)(image + sect->offset + i*itemSize + 1)
  5013. = (char*)addr - (image + sect->offset + i*itemSize + 5);
  5014. }
  5015. else
  5016. #endif
  5017. {
  5018. checkProddableBlock(oc,
  5019. ((void**)(image + sect->offset)) + i,
  5020. sizeof(void *));
  5021. ((void**)(image + sect->offset))[i] = addr;
  5022. }
  5023. }
  5024. IF_DEBUG(linker, debugBelch("resolveImports: done\n"));
  5025. return 1;
  5026. }
  5027. static unsigned long
  5028. relocateAddress(
  5029. ObjectCode* oc,
  5030. int nSections,
  5031. struct section* sections,
  5032. unsigned long address)
  5033. {
  5034. int i;
  5035. IF_DEBUG(linker, debugBelch("relocateAddress: start\n"));
  5036. for (i = 0; i < nSections; i++)
  5037. {
  5038. IF_DEBUG(linker, debugBelch(" relocating address in section %d\n", i));
  5039. if (sections[i].addr <= address
  5040. && address < sections[i].addr + sections[i].size)
  5041. {
  5042. return (unsigned long)oc->image
  5043. + sections[i].offset + address - sections[i].addr;
  5044. }
  5045. }
  5046. barf("Invalid Mach-O file:"
  5047. "Address out of bounds while relocating object file");
  5048. return 0;
  5049. }
  5050. static int
  5051. relocateSection(
  5052. ObjectCode* oc,
  5053. char *image,
  5054. struct symtab_command *symLC, struct nlist *nlist,
  5055. int nSections, struct section* sections, struct section *sect)
  5056. {
  5057. struct relocation_info *relocs;
  5058. int i, n;
  5059. IF_DEBUG(linker, debugBelch("relocateSection: start\n"));
  5060. if(!strcmp(sect->sectname,"__la_symbol_ptr"))
  5061. return 1;
  5062. else if(!strcmp(sect->sectname,"__nl_symbol_ptr"))
  5063. return 1;
  5064. else if(!strcmp(sect->sectname,"__la_sym_ptr2"))
  5065. return 1;
  5066. else if(!strcmp(sect->sectname,"__la_sym_ptr3"))
  5067. return 1;
  5068. n = sect->nreloc;
  5069. IF_DEBUG(linker, debugBelch("relocateSection: number of relocations: %d\n", n));
  5070. relocs = (struct relocation_info*) (image + sect->reloff);
  5071. for(i = 0; i < n; i++)
  5072. {
  5073. #ifdef x86_64_HOST_ARCH
  5074. struct relocation_info *reloc = &relocs[i];
  5075. char *thingPtr = image + sect->offset + reloc->r_address;
  5076. uint64_t thing;
  5077. /* We shouldn't need to initialise this, but gcc on OS X 64 bit
  5078. complains that it may be used uninitialized if we don't */
  5079. uint64_t value = 0;
  5080. uint64_t baseValue;
  5081. int type = reloc->r_type;
  5082. IF_DEBUG(linker, debugBelch("relocateSection: relocation %d\n", i));
  5083. IF_DEBUG(linker, debugBelch(" : type = %d\n", reloc->r_type));
  5084. IF_DEBUG(linker, debugBelch(" : address = %d\n", reloc->r_address));
  5085. IF_DEBUG(linker, debugBelch(" : symbolnum = %u\n", reloc->r_symbolnum));
  5086. IF_DEBUG(linker, debugBelch(" : pcrel = %d\n", reloc->r_pcrel));
  5087. IF_DEBUG(linker, debugBelch(" : length = %d\n", reloc->r_length));
  5088. IF_DEBUG(linker, debugBelch(" : extern = %d\n", reloc->r_extern));
  5089. IF_DEBUG(linker, debugBelch(" : type = %d\n", reloc->r_type));
  5090. switch(reloc->r_length)
  5091. {
  5092. case 0:
  5093. checkProddableBlock(oc,thingPtr,1);
  5094. thing = *(uint8_t*)thingPtr;
  5095. baseValue = (uint64_t)thingPtr + 1;
  5096. break;
  5097. case 1:
  5098. checkProddableBlock(oc,thingPtr,2);
  5099. thing = *(uint16_t*)thingPtr;
  5100. baseValue = (uint64_t)thingPtr + 2;
  5101. break;
  5102. case 2:
  5103. checkProddableBlock(oc,thingPtr,4);
  5104. thing = *(uint32_t*)thingPtr;
  5105. baseValue = (uint64_t)thingPtr + 4;
  5106. break;
  5107. case 3:
  5108. checkProddableBlock(oc,thingPtr,8);
  5109. thing = *(uint64_t*)thingPtr;
  5110. baseValue = (uint64_t)thingPtr + 8;
  5111. break;
  5112. default:
  5113. barf("Unknown size.");
  5114. }
  5115. IF_DEBUG(linker,
  5116. debugBelch("relocateSection: length = %d, thing = %" PRId64 ", baseValue = %p\n",
  5117. reloc->r_length, thing, (char *)baseValue));
  5118. if (type == X86_64_RELOC_GOT
  5119. || type == X86_64_RELOC_GOT_LOAD)
  5120. {
  5121. struct nlist *symbol = &nlist[reloc->r_symbolnum];
  5122. char *nm = image + symLC->stroff + symbol->n_un.n_strx;
  5123. void *addr = NULL;
  5124. IF_DEBUG(linker, debugBelch("relocateSection: making jump island for %s, extern = %d, X86_64_RELOC_GOT\n", nm, reloc->r_extern));
  5125. ASSERT(reloc->r_extern);
  5126. if (reloc->r_extern == 0) {
  5127. errorBelch("\nrelocateSection: global offset table relocation for symbol with r_extern == 0\n");
  5128. }
  5129. if (symbol->n_type & N_EXT) {
  5130. // The external bit is set, meaning the symbol is exported,
  5131. // and therefore can be looked up in this object module's
  5132. // symtab, or it is undefined, meaning dlsym must be used
  5133. // to resolve it.
  5134. addr = lookupSymbol(nm);
  5135. IF_DEBUG(linker, debugBelch("relocateSection: looked up %s, "
  5136. "external X86_64_RELOC_GOT or X86_64_RELOC_GOT_LOAD\n", nm));
  5137. IF_DEBUG(linker, debugBelch(" : addr = %p\n", addr));
  5138. if (addr == NULL) {
  5139. errorBelch("\nlookupSymbol failed in relocateSection (RELOC_GOT)\n"
  5140. "%s: unknown symbol `%s'", oc->fileName, nm);
  5141. return 0;
  5142. }
  5143. } else {
  5144. IF_DEBUG(linker, debugBelch("relocateSection: %s is not an exported symbol\n", nm));
  5145. // The symbol is not exported, or defined in another
  5146. // module, so it must be in the current object module,
  5147. // at the location given by the section index and
  5148. // symbol address (symbol->n_value)
  5149. if ((symbol->n_type & N_TYPE) == N_SECT) {
  5150. addr = (void *)relocateAddress(oc, nSections, sections, symbol->n_value);
  5151. IF_DEBUG(linker, debugBelch("relocateSection: calculated relocation %p of "
  5152. "non-external X86_64_RELOC_GOT or X86_64_RELOC_GOT_LOAD\n",
  5153. (void *)symbol->n_value));
  5154. IF_DEBUG(linker, debugBelch(" : addr = %p\n", addr));
  5155. } else {
  5156. errorBelch("\nrelocateSection: %s is not exported,"
  5157. " and should be defined in a section, but isn't!\n", nm);
  5158. }
  5159. }
  5160. value = (uint64_t) &makeSymbolExtra(oc, reloc->r_symbolnum, (unsigned long)addr)->addr;
  5161. type = X86_64_RELOC_SIGNED;
  5162. }
  5163. else if (reloc->r_extern)
  5164. {
  5165. struct nlist *symbol = &nlist[reloc->r_symbolnum];
  5166. char *nm = image + symLC->stroff + symbol->n_un.n_strx;
  5167. void *addr = NULL;
  5168. IF_DEBUG(linker, debugBelch("relocateSection: looking up external symbol %s\n", nm));
  5169. IF_DEBUG(linker, debugBelch(" : type = %d\n", symbol->n_type));
  5170. IF_DEBUG(linker, debugBelch(" : sect = %d\n", symbol->n_sect));
  5171. IF_DEBUG(linker, debugBelch(" : desc = %d\n", symbol->n_desc));
  5172. IF_DEBUG(linker, debugBelch(" : value = %p\n", (void *)symbol->n_value));
  5173. if ((symbol->n_type & N_TYPE) == N_SECT) {
  5174. value = relocateAddress(oc, nSections, sections,
  5175. symbol->n_value);
  5176. IF_DEBUG(linker, debugBelch("relocateSection, defined external symbol %s, relocated address %p\n", nm, (void *)value));
  5177. }
  5178. else {
  5179. addr = lookupSymbol(nm);
  5180. if (addr == NULL)
  5181. {
  5182. errorBelch("\nlookupSymbol failed in relocateSection (relocate external)\n"
  5183. "%s: unknown symbol `%s'", oc->fileName, nm);
  5184. return 0;
  5185. }
  5186. value = (uint64_t) addr;
  5187. IF_DEBUG(linker, debugBelch("relocateSection: external symbol %s, address %p\n", nm, (void *)value));
  5188. }
  5189. }
  5190. else
  5191. {
  5192. // If the relocation is not through the global offset table
  5193. // or external, then set the value to the baseValue. This
  5194. // will leave displacements into the __const section
  5195. // unchanged (as they ought to be).
  5196. value = baseValue;
  5197. }
  5198. IF_DEBUG(linker, debugBelch("relocateSection: value = %p\n", (void *)value));
  5199. if (type == X86_64_RELOC_BRANCH)
  5200. {
  5201. if((int32_t)(value - baseValue) != (int64_t)(value - baseValue))
  5202. {
  5203. ASSERT(reloc->r_extern);
  5204. value = (uint64_t) &makeSymbolExtra(oc, reloc->r_symbolnum, value)
  5205. -> jumpIsland;
  5206. }
  5207. ASSERT((int32_t)(value - baseValue) == (int64_t)(value - baseValue));
  5208. type = X86_64_RELOC_SIGNED;
  5209. }
  5210. switch(type)
  5211. {
  5212. case X86_64_RELOC_UNSIGNED:
  5213. ASSERT(!reloc->r_pcrel);
  5214. thing += value;
  5215. break;
  5216. case X86_64_RELOC_SIGNED:
  5217. case X86_64_RELOC_SIGNED_1:
  5218. case X86_64_RELOC_SIGNED_2:
  5219. case X86_64_RELOC_SIGNED_4:
  5220. ASSERT(reloc->r_pcrel);
  5221. thing += value - baseValue;
  5222. break;
  5223. case X86_64_RELOC_SUBTRACTOR:
  5224. ASSERT(!reloc->r_pcrel);
  5225. thing -= value;
  5226. break;
  5227. default:
  5228. barf("unkown relocation");
  5229. }
  5230. switch(reloc->r_length)
  5231. {
  5232. case 0:
  5233. *(uint8_t*)thingPtr = thing;
  5234. break;
  5235. case 1:
  5236. *(uint16_t*)thingPtr = thing;
  5237. break;
  5238. case 2:
  5239. *(uint32_t*)thingPtr = thing;
  5240. break;
  5241. case 3:
  5242. *(uint64_t*)thingPtr = thing;
  5243. break;
  5244. }
  5245. #else
  5246. if(relocs[i].r_address & R_SCATTERED)
  5247. {
  5248. struct scattered_relocation_info *scat =
  5249. (struct scattered_relocation_info*) &relocs[i];
  5250. if(!scat->r_pcrel)
  5251. {
  5252. if(scat->r_length == 2)
  5253. {
  5254. unsigned long word = 0;
  5255. unsigned long* wordPtr = (unsigned long*) (image + sect->offset + scat->r_address);
  5256. /* In this check we assume that sizeof(unsigned long) = 2 * sizeof(unsigned short)
  5257. on powerpc_HOST_ARCH */
  5258. checkProddableBlock(oc,wordPtr,sizeof(unsigned long));
  5259. // Note on relocation types:
  5260. // i386 uses the GENERIC_RELOC_* types,
  5261. // while ppc uses special PPC_RELOC_* types.
  5262. // *_RELOC_VANILLA and *_RELOC_PAIR have the same value
  5263. // in both cases, all others are different.
  5264. // Therefore, we use GENERIC_RELOC_VANILLA
  5265. // and GENERIC_RELOC_PAIR instead of the PPC variants,
  5266. // and use #ifdefs for the other types.
  5267. // Step 1: Figure out what the relocated value should be
  5268. if (scat->r_type == GENERIC_RELOC_VANILLA) {
  5269. word = *wordPtr
  5270. + (unsigned long) relocateAddress(oc,
  5271. nSections,
  5272. sections,
  5273. scat->r_value)
  5274. - scat->r_value;
  5275. }
  5276. #ifdef powerpc_HOST_ARCH
  5277. else if(scat->r_type == PPC_RELOC_SECTDIFF
  5278. || scat->r_type == PPC_RELOC_LO16_SECTDIFF
  5279. || scat->r_type == PPC_RELOC_HI16_SECTDIFF
  5280. || scat->r_type == PPC_RELOC_HA16_SECTDIFF
  5281. || scat->r_type == PPC_RELOC_LOCAL_SECTDIFF)
  5282. #else
  5283. else if(scat->r_type == GENERIC_RELOC_SECTDIFF
  5284. || scat->r_type == GENERIC_RELOC_LOCAL_SECTDIFF)
  5285. #endif
  5286. {
  5287. struct scattered_relocation_info *pair =
  5288. (struct scattered_relocation_info*) &relocs[i+1];
  5289. if (!pair->r_scattered || pair->r_type != GENERIC_RELOC_PAIR) {
  5290. barf("Invalid Mach-O file: "
  5291. "RELOC_*_SECTDIFF not followed by RELOC_PAIR");
  5292. }
  5293. word = (unsigned long)
  5294. (relocateAddress(oc, nSections, sections, scat->r_value)
  5295. - relocateAddress(oc, nSections, sections, pair->r_value));
  5296. i++;
  5297. }
  5298. #ifdef powerpc_HOST_ARCH
  5299. else if(scat->r_type == PPC_RELOC_HI16
  5300. || scat->r_type == PPC_RELOC_LO16
  5301. || scat->r_type == PPC_RELOC_HA16
  5302. || scat->r_type == PPC_RELOC_LO14)
  5303. { // these are generated by label+offset things
  5304. struct relocation_info *pair = &relocs[i+1];
  5305. if ((pair->r_address & R_SCATTERED) || pair->r_type != PPC_RELOC_PAIR) {
  5306. barf("Invalid Mach-O file: "
  5307. "PPC_RELOC_* not followed by PPC_RELOC_PAIR");
  5308. }
  5309. if(scat->r_type == PPC_RELOC_LO16)
  5310. {
  5311. word = ((unsigned short*) wordPtr)[1];
  5312. word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF) << 16;
  5313. }
  5314. else if(scat->r_type == PPC_RELOC_LO14)
  5315. {
  5316. barf("Unsupported Relocation: PPC_RELOC_LO14");
  5317. word = ((unsigned short*) wordPtr)[1] & 0xFFFC;
  5318. word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF) << 16;
  5319. }
  5320. else if(scat->r_type == PPC_RELOC_HI16)
  5321. {
  5322. word = ((unsigned short*) wordPtr)[1] << 16;
  5323. word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF);
  5324. }
  5325. else if(scat->r_type == PPC_RELOC_HA16)
  5326. {
  5327. word = ((unsigned short*) wordPtr)[1] << 16;
  5328. word += ((short)relocs[i+1].r_address & (short)0xFFFF);
  5329. }
  5330. word += (unsigned long) relocateAddress(oc, nSections, sections, scat->r_value)
  5331. - scat->r_value;
  5332. i++;
  5333. }
  5334. #endif
  5335. else {
  5336. barf ("Don't know how to handle this Mach-O "
  5337. "scattered relocation entry: "
  5338. "object file %s; entry type %ld; "
  5339. "address %#lx\n",
  5340. OC_INFORMATIVE_FILENAME(oc),
  5341. scat->r_type,
  5342. scat->r_address);
  5343. return 0;
  5344. }
  5345. #ifdef powerpc_HOST_ARCH
  5346. if(scat->r_type == GENERIC_RELOC_VANILLA
  5347. || scat->r_type == PPC_RELOC_SECTDIFF)
  5348. #else
  5349. if(scat->r_type == GENERIC_RELOC_VANILLA
  5350. || scat->r_type == GENERIC_RELOC_SECTDIFF
  5351. || scat->r_type == GENERIC_RELOC_LOCAL_SECTDIFF)
  5352. #endif
  5353. {
  5354. *wordPtr = word;
  5355. }
  5356. #ifdef powerpc_HOST_ARCH
  5357. else if (scat->r_type == PPC_RELOC_LO16_SECTDIFF
  5358. || scat->r_type == PPC_RELOC_LO16)
  5359. {
  5360. ((unsigned short*) wordPtr)[1] = word & 0xFFFF;
  5361. }
  5362. else if (scat->r_type == PPC_RELOC_HI16_SECTDIFF
  5363. || scat->r_type == PPC_RELOC_HI16)
  5364. {
  5365. ((unsigned short*) wordPtr)[1] = (word >> 16) & 0xFFFF;
  5366. }
  5367. else if (scat->r_type == PPC_RELOC_HA16_SECTDIFF
  5368. || scat->r_type == PPC_RELOC_HA16)
  5369. {
  5370. ((unsigned short*) wordPtr)[1] = ((word >> 16) & 0xFFFF)
  5371. + ((word & (1<<15)) ? 1 : 0);
  5372. }
  5373. #endif
  5374. }
  5375. else
  5376. {
  5377. barf("Can't handle Mach-O scattered relocation entry "
  5378. "with this r_length tag: "
  5379. "object file %s; entry type %ld; "
  5380. "r_length tag %ld; address %#lx\n",
  5381. OC_INFORMATIVE_FILENAME(oc),
  5382. scat->r_type,
  5383. scat->r_length,
  5384. scat->r_address);
  5385. return 0;
  5386. }
  5387. }
  5388. else /* scat->r_pcrel */
  5389. {
  5390. barf("Don't know how to handle *PC-relative* Mach-O "
  5391. "scattered relocation entry: "
  5392. "object file %s; entry type %ld; address %#lx\n",
  5393. OC_INFORMATIVE_FILENAME(oc),
  5394. scat->r_type,
  5395. scat->r_address);
  5396. return 0;
  5397. }
  5398. }
  5399. else /* !(relocs[i].r_address & R_SCATTERED) */
  5400. {
  5401. struct relocation_info *reloc = &relocs[i];
  5402. if (reloc->r_pcrel && !reloc->r_extern) {
  5403. IF_DEBUG(linker, debugBelch("relocateSection: pc relative but not external, skipping\n"));
  5404. continue;
  5405. }
  5406. if (reloc->r_length == 2) {
  5407. unsigned long word = 0;
  5408. #ifdef powerpc_HOST_ARCH
  5409. unsigned long jumpIsland = 0;
  5410. long offsetToJumpIsland = 0xBADBAD42; // initialise to bad value
  5411. // to avoid warning and to catch
  5412. // bugs.
  5413. #endif
  5414. unsigned long* wordPtr = (unsigned long*) (image + sect->offset + reloc->r_address);
  5415. /* In this check we assume that sizeof(unsigned long) = 2 * sizeof(unsigned short)
  5416. on powerpc_HOST_ARCH */
  5417. checkProddableBlock(oc,wordPtr, sizeof(unsigned long));
  5418. if (reloc->r_type == GENERIC_RELOC_VANILLA) {
  5419. word = *wordPtr;
  5420. }
  5421. #ifdef powerpc_HOST_ARCH
  5422. else if (reloc->r_type == PPC_RELOC_LO16) {
  5423. word = ((unsigned short*) wordPtr)[1];
  5424. word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF) << 16;
  5425. }
  5426. else if (reloc->r_type == PPC_RELOC_HI16) {
  5427. word = ((unsigned short*) wordPtr)[1] << 16;
  5428. word |= ((unsigned long) relocs[i+1].r_address & 0xFFFF);
  5429. }
  5430. else if (reloc->r_type == PPC_RELOC_HA16) {
  5431. word = ((unsigned short*) wordPtr)[1] << 16;
  5432. word += ((short)relocs[i+1].r_address & (short)0xFFFF);
  5433. }
  5434. else if (reloc->r_type == PPC_RELOC_BR24) {
  5435. word = *wordPtr;
  5436. word = (word & 0x03FFFFFC) | ((word & 0x02000000) ? 0xFC000000 : 0);
  5437. }
  5438. #endif
  5439. else {
  5440. barf("Can't handle this Mach-O relocation entry "
  5441. "(not scattered): "
  5442. "object file %s; entry type %ld; address %#lx\n",
  5443. OC_INFORMATIVE_FILENAME(oc),
  5444. reloc->r_type,
  5445. reloc->r_address);
  5446. return 0;
  5447. }
  5448. if (!reloc->r_extern) {
  5449. long delta = sections[reloc->r_symbolnum-1].offset
  5450. - sections[reloc->r_symbolnum-1].addr
  5451. + ((long) image);
  5452. word += delta;
  5453. }
  5454. else {
  5455. struct nlist *symbol = &nlist[reloc->r_symbolnum];
  5456. char *nm = image + symLC->stroff + symbol->n_un.n_strx;
  5457. void *symbolAddress = lookupSymbol(nm);
  5458. if (!symbolAddress) {
  5459. errorBelch("\nunknown symbol `%s'", nm);
  5460. return 0;
  5461. }
  5462. if (reloc->r_pcrel) {
  5463. #ifdef powerpc_HOST_ARCH
  5464. // In the .o file, this should be a relative jump to NULL
  5465. // and we'll change it to a relative jump to the symbol
  5466. ASSERT(word + reloc->r_address == 0);
  5467. jumpIsland = (unsigned long)
  5468. &makeSymbolExtra(oc,
  5469. reloc->r_symbolnum,
  5470. (unsigned long) symbolAddress)
  5471. -> jumpIsland;
  5472. if (jumpIsland != 0) {
  5473. offsetToJumpIsland = word + jumpIsland
  5474. - (((long)image) + sect->offset - sect->addr);
  5475. }
  5476. #endif
  5477. word += (unsigned long) symbolAddress
  5478. - (((long)image) + sect->offset - sect->addr);
  5479. }
  5480. else {
  5481. word += (unsigned long) symbolAddress;
  5482. }
  5483. }
  5484. if (reloc->r_type == GENERIC_RELOC_VANILLA) {
  5485. *wordPtr = word;
  5486. continue;
  5487. }
  5488. #ifdef powerpc_HOST_ARCH
  5489. else if(reloc->r_type == PPC_RELOC_LO16)
  5490. {
  5491. ((unsigned short*) wordPtr)[1] = word & 0xFFFF;
  5492. i++;
  5493. continue;
  5494. }
  5495. else if(reloc->r_type == PPC_RELOC_HI16)
  5496. {
  5497. ((unsigned short*) wordPtr)[1] = (word >> 16) & 0xFFFF;
  5498. i++;
  5499. continue;
  5500. }
  5501. else if(reloc->r_type == PPC_RELOC_HA16)
  5502. {
  5503. ((unsigned short*) wordPtr)[1] = ((word >> 16) & 0xFFFF)
  5504. + ((word & (1<<15)) ? 1 : 0);
  5505. i++;
  5506. continue;
  5507. }
  5508. else if(reloc->r_type == PPC_RELOC_BR24)
  5509. {
  5510. if ((word & 0x03) != 0) {
  5511. barf("%s: unconditional relative branch with a displacement "
  5512. "which isn't a multiple of 4 bytes: %#lx",
  5513. OC_INFORMATIVE_FILENAME(oc),
  5514. word);
  5515. }
  5516. if((word & 0xFE000000) != 0xFE000000 &&
  5517. (word & 0xFE000000) != 0x00000000) {
  5518. // The branch offset is too large.
  5519. // Therefore, we try to use a jump island.
  5520. if (jumpIsland == 0) {
  5521. barf("%s: unconditional relative branch out of range: "
  5522. "no jump island available: %#lx",
  5523. OC_INFORMATIVE_FILENAME(oc),
  5524. word);
  5525. }
  5526. word = offsetToJumpIsland;
  5527. if((word & 0xFE000000) != 0xFE000000 &&
  5528. (word & 0xFE000000) != 0x00000000) {
  5529. barf("%s: unconditional relative branch out of range: "
  5530. "jump island out of range: %#lx",
  5531. OC_INFORMATIVE_FILENAME(oc),
  5532. word);
  5533. }
  5534. }
  5535. *wordPtr = (*wordPtr & 0xFC000003) | (word & 0x03FFFFFC);
  5536. continue;
  5537. }
  5538. #endif
  5539. }
  5540. else
  5541. {
  5542. barf("Can't handle Mach-O relocation entry (not scattered) "
  5543. "with this r_length tag: "
  5544. "object file %s; entry type %ld; "
  5545. "r_length tag %ld; address %#lx\n",
  5546. OC_INFORMATIVE_FILENAME(oc),
  5547. reloc->r_type,
  5548. reloc->r_length,
  5549. reloc->r_address);
  5550. return 0;
  5551. }
  5552. }
  5553. #endif
  5554. }
  5555. IF_DEBUG(linker, debugBelch("relocateSection: done\n"));
  5556. return 1;
  5557. }
  5558. static int
  5559. ocGetNames_MachO(ObjectCode* oc)
  5560. {
  5561. char *image = (char*) oc->image;
  5562. struct mach_header *header = (struct mach_header*) image;
  5563. struct load_command *lc = (struct load_command*) (image + sizeof(struct mach_header));
  5564. unsigned i,curSymbol = 0;
  5565. struct segment_command *segLC = NULL;
  5566. struct section *sections;
  5567. struct symtab_command *symLC = NULL;
  5568. struct nlist *nlist;
  5569. unsigned long commonSize = 0;
  5570. char *commonStorage = NULL;
  5571. unsigned long commonCounter;
  5572. IF_DEBUG(linker,debugBelch("ocGetNames_MachO: start\n"));
  5573. for(i=0;i<header->ncmds;i++)
  5574. {
  5575. if (lc->cmd == LC_SEGMENT || lc->cmd == LC_SEGMENT_64) {
  5576. segLC = (struct segment_command*) lc;
  5577. }
  5578. else if (lc->cmd == LC_SYMTAB) {
  5579. symLC = (struct symtab_command*) lc;
  5580. }
  5581. lc = (struct load_command *) ( ((char*)lc) + lc->cmdsize );
  5582. }
  5583. sections = (struct section*) (segLC+1);
  5584. nlist = symLC ? (struct nlist*) (image + symLC->symoff)
  5585. : NULL;
  5586. if (!segLC) {
  5587. barf("ocGetNames_MachO: no segment load command");
  5588. }
  5589. IF_DEBUG(linker, debugBelch("ocGetNames_MachO: will load %d sections\n", segLC->nsects));
  5590. for(i=0;i<segLC->nsects;i++)
  5591. {
  5592. IF_DEBUG(linker, debugBelch("ocGetNames_MachO: section %d\n", i));
  5593. if (sections[i].size == 0) {
  5594. IF_DEBUG(linker, debugBelch("ocGetNames_MachO: found a zero length section, skipping\n"));
  5595. continue;
  5596. }
  5597. if((sections[i].flags & SECTION_TYPE) == S_ZEROFILL)
  5598. {
  5599. #ifdef USE_MMAP
  5600. char * zeroFillArea = mmapForLinker(sections[i].size, MAP_ANONYMOUS, -1);
  5601. memset(zeroFillArea, 0, sections[i].size);
  5602. #else
  5603. char * zeroFillArea = stgCallocBytes(1,sections[i].size,
  5604. "ocGetNames_MachO(common symbols)");
  5605. #endif
  5606. sections[i].offset = zeroFillArea - image;
  5607. }
  5608. if (!strcmp(sections[i].sectname,"__text")) {
  5609. IF_DEBUG(linker, debugBelch("ocGetNames_MachO: adding __text section\n"));
  5610. addSection(oc, SECTIONKIND_CODE_OR_RODATA,
  5611. (void*) (image + sections[i].offset),
  5612. (void*) (image + sections[i].offset + sections[i].size));
  5613. }
  5614. else if (!strcmp(sections[i].sectname,"__const")) {
  5615. IF_DEBUG(linker, debugBelch("ocGetNames_MachO: adding __const section\n"));
  5616. addSection(oc, SECTIONKIND_RWDATA,
  5617. (void*) (image + sections[i].offset),
  5618. (void*) (image + sections[i].offset + sections[i].size));
  5619. }
  5620. else if (!strcmp(sections[i].sectname,"__data")) {
  5621. IF_DEBUG(linker, debugBelch("ocGetNames_MachO: adding __data section\n"));
  5622. addSection(oc, SECTIONKIND_RWDATA,
  5623. (void*) (image + sections[i].offset),
  5624. (void*) (image + sections[i].offset + sections[i].size));
  5625. }
  5626. else if(!strcmp(sections[i].sectname,"__bss")
  5627. || !strcmp(sections[i].sectname,"__common")) {
  5628. IF_DEBUG(linker, debugBelch("ocGetNames_MachO: adding __bss section\n"));
  5629. addSection(oc, SECTIONKIND_RWDATA,
  5630. (void*) (image + sections[i].offset),
  5631. (void*) (image + sections[i].offset + sections[i].size));
  5632. }
  5633. addProddableBlock(oc,
  5634. (void *) (image + sections[i].offset),
  5635. sections[i].size);
  5636. }
  5637. // count external symbols defined here
  5638. oc->n_symbols = 0;
  5639. if (symLC) {
  5640. for (i = 0; i < symLC->nsyms; i++) {
  5641. if (nlist[i].n_type & N_STAB) {
  5642. ;
  5643. }
  5644. else if(nlist[i].n_type & N_EXT)
  5645. {
  5646. if((nlist[i].n_type & N_TYPE) == N_UNDF
  5647. && (nlist[i].n_value != 0))
  5648. {
  5649. commonSize += nlist[i].n_value;
  5650. oc->n_symbols++;
  5651. }
  5652. else if((nlist[i].n_type & N_TYPE) == N_SECT)
  5653. oc->n_symbols++;
  5654. }
  5655. }
  5656. }
  5657. IF_DEBUG(linker, debugBelch("ocGetNames_MachO: %d external symbols\n", oc->n_symbols));
  5658. oc->symbols = stgMallocBytes(oc->n_symbols * sizeof(char*),
  5659. "ocGetNames_MachO(oc->symbols)");
  5660. if(symLC)
  5661. {
  5662. for(i=0;i<symLC->nsyms;i++)
  5663. {
  5664. if(nlist[i].n_type & N_STAB)
  5665. ;
  5666. else if((nlist[i].n_type & N_TYPE) == N_SECT)
  5667. {
  5668. if(nlist[i].n_type & N_EXT)
  5669. {
  5670. char *nm = image + symLC->stroff + nlist[i].n_un.n_strx;
  5671. if ((nlist[i].n_desc & N_WEAK_DEF) && lookupSymbol(nm)) {
  5672. // weak definition, and we already have a definition
  5673. IF_DEBUG(linker, debugBelch(" weak: %s\n", nm));
  5674. }
  5675. else
  5676. {
  5677. IF_DEBUG(linker, debugBelch("ocGetNames_MachO: inserting %s\n", nm));
  5678. ghciInsertStrHashTable(oc->fileName, symhash, nm,
  5679. image
  5680. + sections[nlist[i].n_sect-1].offset
  5681. - sections[nlist[i].n_sect-1].addr
  5682. + nlist[i].n_value);
  5683. oc->symbols[curSymbol++] = nm;
  5684. }
  5685. }
  5686. else
  5687. {
  5688. IF_DEBUG(linker, debugBelch("ocGetNames_MachO: \t...not external, skipping\n"));
  5689. }
  5690. }
  5691. else
  5692. {
  5693. IF_DEBUG(linker, debugBelch("ocGetNames_MachO: \t...not defined in this section, skipping\n"));
  5694. }
  5695. }
  5696. }
  5697. commonStorage = stgCallocBytes(1,commonSize,"ocGetNames_MachO(common symbols)");
  5698. commonCounter = (unsigned long)commonStorage;
  5699. if (symLC) {
  5700. for (i = 0; i < symLC->nsyms; i++) {
  5701. if((nlist[i].n_type & N_TYPE) == N_UNDF
  5702. && (nlist[i].n_type & N_EXT)
  5703. && (nlist[i].n_value != 0)) {
  5704. char *nm = image + symLC->stroff + nlist[i].n_un.n_strx;
  5705. unsigned long sz = nlist[i].n_value;
  5706. nlist[i].n_value = commonCounter;
  5707. IF_DEBUG(linker, debugBelch("ocGetNames_MachO: inserting common symbol: %s\n", nm));
  5708. ghciInsertStrHashTable(oc->fileName, symhash, nm,
  5709. (void*)commonCounter);
  5710. oc->symbols[curSymbol++] = nm;
  5711. commonCounter += sz;
  5712. }
  5713. }
  5714. }
  5715. IF_DEBUG(linker, debugBelch("ocGetNames_MachO: done\n"));
  5716. return 1;
  5717. }
  5718. static int
  5719. ocResolve_MachO(ObjectCode* oc)
  5720. {
  5721. char *image = (char*) oc->image;
  5722. struct mach_header *header = (struct mach_header*) image;
  5723. struct load_command *lc = (struct load_command*) (image + sizeof(struct mach_header));
  5724. unsigned i;
  5725. struct segment_command *segLC = NULL;
  5726. struct section *sections;
  5727. struct symtab_command *symLC = NULL;
  5728. struct dysymtab_command *dsymLC = NULL;
  5729. struct nlist *nlist;
  5730. IF_DEBUG(linker, debugBelch("ocResolve_MachO: start\n"));
  5731. for (i = 0; i < header->ncmds; i++)
  5732. {
  5733. if (lc->cmd == LC_SEGMENT || lc->cmd == LC_SEGMENT_64) {
  5734. segLC = (struct segment_command*) lc;
  5735. IF_DEBUG(linker, debugBelch("ocResolve_MachO: found a 32 or 64 bit segment load command\n"));
  5736. }
  5737. else if (lc->cmd == LC_SYMTAB) {
  5738. symLC = (struct symtab_command*) lc;
  5739. IF_DEBUG(linker, debugBelch("ocResolve_MachO: found a symbol table load command\n"));
  5740. }
  5741. else if (lc->cmd == LC_DYSYMTAB) {
  5742. dsymLC = (struct dysymtab_command*) lc;
  5743. IF_DEBUG(linker, debugBelch("ocResolve_MachO: found a dynamic symbol table load command\n"));
  5744. }
  5745. lc = (struct load_command *) ( ((char*)lc) + lc->cmdsize );
  5746. }
  5747. sections = (struct section*) (segLC+1);
  5748. nlist = symLC ? (struct nlist*) (image + symLC->symoff)
  5749. : NULL;
  5750. if(dsymLC)
  5751. {
  5752. unsigned long *indirectSyms
  5753. = (unsigned long*) (image + dsymLC->indirectsymoff);
  5754. IF_DEBUG(linker, debugBelch("ocResolve_MachO: resolving dsymLC\n"));
  5755. for (i = 0; i < segLC->nsects; i++)
  5756. {
  5757. if( !strcmp(sections[i].sectname,"__la_symbol_ptr")
  5758. || !strcmp(sections[i].sectname,"__la_sym_ptr2")
  5759. || !strcmp(sections[i].sectname,"__la_sym_ptr3"))
  5760. {
  5761. if(!resolveImports(oc,image,symLC,&sections[i],indirectSyms,nlist))
  5762. return 0;
  5763. }
  5764. else if(!strcmp(sections[i].sectname,"__nl_symbol_ptr")
  5765. || !strcmp(sections[i].sectname,"__pointers"))
  5766. {
  5767. if(!resolveImports(oc,image,symLC,&sections[i],indirectSyms,nlist))
  5768. return 0;
  5769. }
  5770. else if(!strcmp(sections[i].sectname,"__jump_table"))
  5771. {
  5772. if(!resolveImports(oc,image,symLC,&sections[i],indirectSyms,nlist))
  5773. return 0;
  5774. }
  5775. else
  5776. {
  5777. IF_DEBUG(linker, debugBelch("ocResolve_MachO: unknown section\n"));
  5778. }
  5779. }
  5780. }
  5781. for(i=0;i<segLC->nsects;i++)
  5782. {
  5783. IF_DEBUG(linker, debugBelch("ocResolve_MachO: relocating section %d\n", i));
  5784. if (!relocateSection(oc,image,symLC,nlist,segLC->nsects,sections,&sections[i]))
  5785. return 0;
  5786. }
  5787. #if defined (powerpc_HOST_ARCH)
  5788. ocFlushInstructionCache( oc );
  5789. #endif
  5790. return 1;
  5791. }
  5792. #ifdef powerpc_HOST_ARCH
  5793. /*
  5794. * The Mach-O object format uses leading underscores. But not everywhere.
  5795. * There is a small number of runtime support functions defined in
  5796. * libcc_dynamic.a whose name does not have a leading underscore.
  5797. * As a consequence, we can't get their address from C code.
  5798. * We have to use inline assembler just to take the address of a function.
  5799. * Yuck.
  5800. */
  5801. extern void* symbolsWithoutUnderscore[];
  5802. static void
  5803. machoInitSymbolsWithoutUnderscore(void)
  5804. {
  5805. void **p = symbolsWithoutUnderscore;
  5806. __asm__ volatile(".globl _symbolsWithoutUnderscore\n.data\n_symbolsWithoutUnderscore:");
  5807. #undef SymI_NeedsProto
  5808. #define SymI_NeedsProto(x) \
  5809. __asm__ volatile(".long " # x);
  5810. RTS_MACHO_NOUNDERLINE_SYMBOLS
  5811. __asm__ volatile(".text");
  5812. #undef SymI_NeedsProto
  5813. #define SymI_NeedsProto(x) \
  5814. ghciInsertStrHashTable("(GHCi built-in symbols)", symhash, #x, *p++);
  5815. RTS_MACHO_NOUNDERLINE_SYMBOLS
  5816. #undef SymI_NeedsProto
  5817. }
  5818. #endif
  5819. #ifndef USE_MMAP
  5820. /*
  5821. * Figure out by how much to shift the entire Mach-O file in memory
  5822. * when loading so that its single segment ends up 16-byte-aligned
  5823. */
  5824. static int
  5825. machoGetMisalignment( FILE * f )
  5826. {
  5827. struct mach_header header;
  5828. int misalignment;
  5829. {
  5830. int n = fread(&header, sizeof(header), 1, f);
  5831. if (n != 1) {
  5832. barf("machoGetMisalignment: can't read the Mach-O header");
  5833. }
  5834. }
  5835. fseek(f, -sizeof(header), SEEK_CUR);
  5836. #if x86_64_HOST_ARCH || powerpc64_HOST_ARCH
  5837. if(header.magic != MH_MAGIC_64) {
  5838. barf("Bad magic. Expected: %08x, got: %08x.",
  5839. MH_MAGIC_64, header.magic);
  5840. }
  5841. #else
  5842. if(header.magic != MH_MAGIC) {
  5843. barf("Bad magic. Expected: %08x, got: %08x.",
  5844. MH_MAGIC, header.magic);
  5845. }
  5846. #endif
  5847. misalignment = (header.sizeofcmds + sizeof(header))
  5848. & 0xF;
  5849. return misalignment ? (16 - misalignment) : 0;
  5850. }
  5851. #endif
  5852. #endif