David Eichmann pushed to branch wip/27162/rts-explicit-dllimport at Glasgow Haskell Compiler / GHC
Commits:
-
5a6ba22b
by Duncan Coutts at 2026-04-30T11:40:09+01:00
-
6833e03c
by Duncan Coutts at 2026-04-30T11:40:09+01:00
-
793008fb
by David Eichmann at 2026-04-30T11:40:09+01:00
7 changed files:
- hadrian/src/Settings/Packages.hs
- rts/IOManager.h
- rts/Linker.c
- rts/LinkerInternals.h
- rts/RtsSymbols.c
- rts/RtsSymbols.h
- rts/linker/Elf.c
Changes:
| ... | ... | @@ -321,6 +321,7 @@ rtsPackageArgs = package rts ? do |
| 321 | 321 | , Profiling `wayUnit` way ? arg "-DPROFILING"
|
| 322 | 322 | , Threaded `wayUnit` way ? arg "-DTHREADED_RTS"
|
| 323 | 323 | , notM targetSupportsSMP ? arg "-optc-DNOSMP"
|
| 324 | + , isWinHost ? arg "-optl-Wl,--disable-runtime-pseudo-reloc"
|
|
| 324 | 325 | |
| 325 | 326 | -- See Note [AutoApply.cmm for vectors] in genapply/Main.hs
|
| 326 | 327 | --
|
| ... | ... | @@ -21,6 +21,15 @@ |
| 21 | 21 | |
| 22 | 22 | #include "sm/GC.h" // for evac_fn
|
| 23 | 23 | |
| 24 | +#if defined(mingw32_HOST_OS)
|
|
| 25 | +/* Global var (only on Windows) that is exported (hence before BeginPrivate.h)
|
|
| 26 | + * to be shared with the I/O code in the base library to tell us which style
|
|
| 27 | + * of I/O manager we are using: one that uses the Windows native API HANDLEs,
|
|
| 28 | + * or one that uses Posix style fds.
|
|
| 29 | + */
|
|
| 30 | +extern bool rts_IOManagerIsWin32Native;
|
|
| 31 | +#endif
|
|
| 32 | + |
|
| 24 | 33 | #include "BeginPrivate.h"
|
| 25 | 34 | |
| 26 | 35 | /* The ./configure gives us a set of CPP flags, one for each named I/O manager:
|
| ... | ... | @@ -160,14 +169,6 @@ typedef enum { |
| 160 | 169 | /* Global var to tell us which I/O manager impl we are using */
|
| 161 | 170 | extern IOManagerType iomgr_type;
|
| 162 | 171 | |
| 163 | -#if defined(mingw32_HOST_OS)
|
|
| 164 | -/* Global var (only on Windows) that is exported to be shared with the I/O code
|
|
| 165 | - * in the base library to tell us which style of I/O manager we are using: one
|
|
| 166 | - * that uses the Windows native API HANDLEs, or one that uses Posix style fds.
|
|
| 167 | - */
|
|
| 168 | -extern bool rts_IOManagerIsWin32Native;
|
|
| 169 | -#endif
|
|
| 170 | - |
|
| 171 | 172 | |
| 172 | 173 | /* The CapIOManager is the per-capability data structure belonging to the I/O
|
| 173 | 174 | * manager. It is defined in full in IOManagerInternals.h. The opaque forward
|
| ... | ... | @@ -478,16 +478,7 @@ initLinker_ (int retain_cafs) |
| 478 | 478 | symhash = allocStrHashTable();
|
| 479 | 479 | |
| 480 | 480 | /* populate the symbol table with stuff from the RTS */
|
| 481 | - IF_DEBUG(linker, debugBelch("populating linker symbol table with built-in RTS symbols\n"));
|
|
| 482 | - for (const RtsSymbolVal *sym = rtsSyms; sym->lbl != NULL; sym++) {
|
|
| 483 | - IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
|
|
| 484 | - if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"),
|
|
| 485 | - symhash, sym->lbl, sym->addr,
|
|
| 486 | - sym->strength, sym->type, 0, NULL)) {
|
|
| 487 | - barf("ghciInsertSymbolTable failed");
|
|
| 488 | - }
|
|
| 489 | - }
|
|
| 490 | - IF_DEBUG(linker, debugBelch("done with built-in RTS symbols\n"));
|
|
| 481 | + initLinkerRtsSyms(symhash);
|
|
| 491 | 482 | |
| 492 | 483 | /* Add extra symbols. rtsExtraSyms() is a weakly defined symbol in the rts,
|
| 493 | 484 | * that can be overrided by linking in an object with a corresponding
|
| ... | ... | @@ -502,4 +502,6 @@ ObjectCode* mkOc( ObjectType type, pathchar *path, char *image, int imageSize, |
| 502 | 502 | void initSegment(Segment *s, void *start, size_t size, SegmentProt prot, int n_sections);
|
| 503 | 503 | void freeSegments(ObjectCode *oc);
|
| 504 | 504 | |
| 505 | +void initLinkerRtsSyms(StrHashTable *symhash);
|
|
| 506 | + |
|
| 505 | 507 | #include "EndPrivate.h" |
| ... | ... | @@ -9,6 +9,8 @@ |
| 9 | 9 | #include "ghcplatform.h"
|
| 10 | 10 | #include "Rts.h"
|
| 11 | 11 | #include "RtsSymbols.h"
|
| 12 | +#include "LinkerInternals.h"
|
|
| 13 | +#include "PathUtils.h"
|
|
| 12 | 14 | |
| 13 | 15 | #include "TopHandler.h"
|
| 14 | 16 | #include "HsFFI.h"
|
| ... | ... | @@ -51,6 +53,20 @@ extern char **environ; |
| 51 | 53 | |
| 52 | 54 | /* -----------------------------------------------------------------------------
|
| 53 | 55 | * Symbols to be inserted into the RTS symbol table.
|
| 56 | + *
|
|
| 57 | + * Note [Naming Scheme for Symbol Macros]
|
|
| 58 | + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 59 | + *
|
|
| 60 | + * SymI_*: symbol is internal to the RTS. It resides in an object
|
|
| 61 | + * file/library that is linked into the RTS library (as a static
|
|
| 62 | + * archive or dynamic shared library).
|
|
| 63 | + * SymE_*: symbol is external to the RTS library. It might be linked
|
|
| 64 | + * dynamically.
|
|
| 65 | + *
|
|
| 66 | + * Sym*_HasProto : the symbol prototype is imported in an include file
|
|
| 67 | + * or defined explicitly
|
|
| 68 | + * Sym*_NeedsProto: the symbol is undefined and we add a dummy
|
|
| 69 | + * default proto extern void sym(void);
|
|
| 54 | 70 | */
|
| 55 | 71 | |
| 56 | 72 | #define Maybe_Stable_Names SymI_HasProto(stg_mkWeakzh) \
|
| ... | ... | @@ -162,7 +178,7 @@ extern char **environ; |
| 162 | 178 | SymI_HasProto(stg_asyncWritezh) \
|
| 163 | 179 | SymI_HasProto(stg_asyncDoProczh) \
|
| 164 | 180 | SymI_HasProto(rts_InstallConsoleEvent) \
|
| 165 | - SymI_HasProto(rts_IOManagerIsWin32Native) \
|
|
| 181 | + SymI_HasDataProto(rts_IOManagerIsWin32Native) \
|
|
| 166 | 182 | SymI_HasProto(rts_ConsoleHandlerDone) \
|
| 167 | 183 | SymI_NeedsProto(__mingw_module_is_dll) \
|
| 168 | 184 | RTS_WIN64_ONLY(SymI_NeedsProto(___chkstk_ms)) \
|
| ... | ... | @@ -913,7 +929,7 @@ extern char **environ; |
| 913 | 929 | SymI_HasProto(freeExecPage) \
|
| 914 | 930 | SymI_HasProto(getAllocations) \
|
| 915 | 931 | SymI_HasProto(revertCAFs) \
|
| 916 | - SymI_HasProto(RtsFlags) \
|
|
| 932 | + SymI_HasDataProto(RtsFlags) \
|
|
| 917 | 933 | SymI_NeedsDataProto(rts_breakpoint_io_action) \
|
| 918 | 934 | SymI_NeedsDataProto(rts_stop_next_breakpoint) \
|
| 919 | 935 | SymI_NeedsDataProto(rts_stop_on_exception) \
|
| ... | ... | @@ -924,9 +940,9 @@ extern char **environ; |
| 924 | 940 | SymI_NeedsProto(rts_enableStopAfterReturn) \
|
| 925 | 941 | SymI_NeedsProto(rts_disableStopAfterReturn) \
|
| 926 | 942 | SymI_HasProto(stopTimer) \
|
| 927 | - SymI_HasProto(n_capabilities) \
|
|
| 928 | - SymI_HasProto(max_n_capabilities) \
|
|
| 929 | - SymI_HasProto(enabled_capabilities) \
|
|
| 943 | + SymI_HasDataProto(n_capabilities) \
|
|
| 944 | + SymI_HasDataProto(max_n_capabilities) \
|
|
| 945 | + SymI_HasDataProto(enabled_capabilities) \
|
|
| 930 | 946 | SymI_HasDataProto(stg_traceEventzh) \
|
| 931 | 947 | SymI_HasDataProto(stg_traceMarkerzh) \
|
| 932 | 948 | SymI_HasDataProto(stg_traceBinaryEventzh) \
|
| ... | ... | @@ -1144,12 +1160,27 @@ extern char **environ; |
| 1144 | 1160 | SymI_HasProto(hs_word2float64)
|
| 1145 | 1161 | |
| 1146 | 1162 | |
| 1147 | -/* entirely bogus claims about types of these symbols */
|
|
| 1148 | -#define SymI_NeedsProto(vvv) extern void vvv(void);
|
|
| 1149 | -#define SymI_NeedsDataProto(vvv) extern StgWord vvv[];
|
|
| 1150 | -#define SymE_NeedsProto(vvv) SymI_NeedsProto(vvv);
|
|
| 1151 | -#define SymE_NeedsDataProto(vvv) SymI_NeedsDataProto(vvv);
|
|
| 1152 | -#define SymE_HasProto(vvv) SymI_HasProto(vvv);
|
|
| 1163 | +/* Declare prototypes for the symbols that need it, so we can refer
|
|
| 1164 | + * to them in the rtsSyms table below.
|
|
| 1165 | + *
|
|
| 1166 | + * In particular, for the external ones (SymE_*) we use the dllimport attribute
|
|
| 1167 | + * to indicate that (on Windows) they come from external DLLs. This attribute
|
|
| 1168 | + * is ignored on other platforms.
|
|
| 1169 | + *
|
|
| 1170 | + * The claims about the types of these symbols are entirely bogus.
|
|
| 1171 | + */
|
|
| 1172 | +#if defined(mingw32_HOST_OS) && defined(DYNAMIC)
|
|
| 1173 | +#define DLLIMPORT __attribute__((dllimport))
|
|
| 1174 | +#else
|
|
| 1175 | +#define DLLIMPORT /**/
|
|
| 1176 | +#endif
|
|
| 1177 | + |
|
| 1178 | +#define SymI_NeedsProto(vvv) extern void vvv(void);
|
|
| 1179 | +#define SymI_NeedsDataProto(vvv) extern StgWord vvv[];
|
|
| 1180 | +#define SymE_NeedsProto(vvv) extern DLLIMPORT void vvv(void);
|
|
| 1181 | +#define SymE_NeedsDataProto(vvv) extern DLLIMPORT StgWord vvv[];
|
|
| 1182 | + |
|
| 1183 | +#define SymE_HasProto(vvv) /**/
|
|
| 1153 | 1184 | #define SymI_HasProto(vvv) /**/
|
| 1154 | 1185 | #define SymI_HasDataProto(vvv) /**/
|
| 1155 | 1186 | #define SymI_HasProto_redirect(vvv,xxx,strength,ty) /**/
|
| ... | ... | @@ -1178,6 +1209,8 @@ RTS_SYMBOLS_PRIM |
| 1178 | 1209 | #undef SymE_NeedsProto
|
| 1179 | 1210 | #undef SymE_NeedsDataProto
|
| 1180 | 1211 | |
| 1212 | +/* See Note [Naming Scheme for Symbol Macros] */
|
|
| 1213 | + |
|
| 1181 | 1214 | #define SymI_HasProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
|
| 1182 | 1215 | (void*)(&(vvv)), STRENGTH_NORMAL, SYM_TYPE_CODE },
|
| 1183 | 1216 | #define SymI_HasDataProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
|
| ... | ... | @@ -1198,7 +1231,16 @@ RTS_SYMBOLS_PRIM |
| 1198 | 1231 | { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
|
| 1199 | 1232 | (void*)(&(xxx)), strength, ty },
|
| 1200 | 1233 | |
| 1201 | -RtsSymbolVal rtsSyms[] = {
|
|
| 1234 | + |
|
| 1235 | + |
|
| 1236 | +/* Initialize (if not already initialized) and return an array of symbols with stuff from the RTS. */
|
|
| 1237 | +void initLinkerRtsSyms (StrHashTable *symhash) {
|
|
| 1238 | + /* The address of data symbols with the dllimport attribute are not
|
|
| 1239 | + * compile-time constants and so cannot be used in constant initialisers.
|
|
| 1240 | + * For this reason, rtsSyms is a local variable within this function
|
|
| 1241 | + * rather than a global constant (as it was historically).
|
|
| 1242 | + */
|
|
| 1243 | + const RtsSymbolVal rtsSyms[] = {
|
|
| 1202 | 1244 | RTS_SYMBOLS
|
| 1203 | 1245 | RTS_RET_SYMBOLS
|
| 1204 | 1246 | RTS_POSIX_ONLY_SYMBOLS
|
| ... | ... | @@ -1213,7 +1255,20 @@ RtsSymbolVal rtsSyms[] = { |
| 1213 | 1255 | RTS_SYMBOLS_PRIM
|
| 1214 | 1256 | SymI_HasDataProto(nonmoving_write_barrier_enabled)
|
| 1215 | 1257 | { 0, 0, STRENGTH_NORMAL, SYM_TYPE_CODE } /* sentinel */
|
| 1216 | -};
|
|
| 1258 | + };
|
|
| 1259 | + |
|
| 1260 | + IF_DEBUG(linker, debugBelch("populating linker symbol table with built-in RTS symbols\n"));
|
|
| 1261 | + for (const RtsSymbolVal *sym = rtsSyms; sym->lbl != NULL; sym++) {
|
|
| 1262 | + IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
|
|
| 1263 | + if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"),
|
|
| 1264 | + symhash, sym->lbl, sym->addr,
|
|
| 1265 | + sym->strength, sym->type, 0, NULL)) {
|
|
| 1266 | + barf("ghciInsertSymbolTable failed");
|
|
| 1267 | + }
|
|
| 1268 | + }
|
|
| 1269 | + IF_DEBUG(linker, debugBelch("done with built-in RTS symbols\n"));
|
|
| 1270 | +}
|
|
| 1271 | + |
|
| 1217 | 1272 | |
| 1218 | 1273 | |
| 1219 | 1274 | // Note [Extra RTS symbols]
|
| ... | ... | @@ -46,8 +46,6 @@ typedef struct _RtsSymbolVal { |
| 46 | 46 | SymType type;
|
| 47 | 47 | } RtsSymbolVal;
|
| 48 | 48 | |
| 49 | -extern RtsSymbolVal rtsSyms[];
|
|
| 50 | - |
|
| 51 | 49 | extern RtsSymbolVal* __attribute__((weak)) rtsExtraSyms(void);
|
| 52 | 50 | |
| 53 | 51 | /* See Note [_iob_func symbol]. */
|
| ... | ... | @@ -76,18 +76,6 @@ |
| 76 | 76 | *
|
| 77 | 77 | * See bug #781
|
| 78 | 78 | * See thread http://www.haskell.org/pipermail/cvs-ghc/2007-September/038458.html
|
| 79 | - *
|
|
| 80 | - * Naming Scheme for Symbol Macros
|
|
| 81 | - *
|
|
| 82 | - * SymI_*: symbol is internal to the RTS. It resides in an object
|
|
| 83 | - * file/library that is statically.
|
|
| 84 | - * SymE_*: symbol is external to the RTS library. It might be linked
|
|
| 85 | - * dynamically.
|
|
| 86 | - *
|
|
| 87 | - * Sym*_HasProto : the symbol prototype is imported in an include file
|
|
| 88 | - * or defined explicitly
|
|
| 89 | - * Sym*_NeedsProto: the symbol is undefined and we add a dummy
|
|
| 90 | - * default proto extern void sym(void);
|
|
| 91 | 79 | */
|
| 92 | 80 | #define X86_64_ELF_NONPIC_HACK (!RtsFlags.MiscFlags.linkerAlwaysPic)
|
| 93 | 81 |