Magnus pushed to branch wip/mangoiv/ghc-9.12-bp at Glasgow Haskell Compiler / GHC
Commits:
-
11ce0b56
by doyougnu at 2026-05-25T14:42:22+02:00
20 changed files:
- docs/users_guide/runtime_control.rst
- libraries/ghc-internal/src/GHC/Internal/RTS/Flags.hsc
- rts/Linker.c
- rts/RtsFlags.c
- rts/include/rts/Flags.h
- rts/linker/elf_got.c
- + testsuite/tests/ghci/linking/T25240/Makefile
- + testsuite/tests/ghci/linking/T25240/T25240.hs
- + testsuite/tests/ghci/linking/T25240/T25240.stderr
- + testsuite/tests/ghci/linking/T25240/T25240a.hs
- + testsuite/tests/ghci/linking/T25240/all.T
- testsuite/tests/ghci/should_run/T18064.stderr
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/rts/linker/T11223/T11223_link_order_a_b_2_fail.stderr
- testsuite/tests/rts/linker/T11223/T11223_link_order_a_b_2_fail.stderr-ws-64-mingw32
- testsuite/tests/rts/linker/T11223/T11223_simple_duplicate_lib.stderr
- testsuite/tests/rts/linker/T11223/T11223_simple_duplicate_lib.stderr-ws-64-mingw32
Changes:
| ... | ... | @@ -397,6 +397,11 @@ Miscellaneous RTS options |
| 397 | 397 | heap larger than 1T. ``-xr`` is a no-op if GHC is configured with
|
| 398 | 398 | ``--disable-large-address-space`` or if the platform is 32-bit.
|
| 399 | 399 | |
| 400 | +.. rts-flag:: --optimistic-linking
|
|
| 401 | + |
|
| 402 | + If given, instruct the runtime linker to try to continue linking in the
|
|
| 403 | + presence of an unresolved symbol.
|
|
| 404 | + |
|
| 400 | 405 | .. _rts-options-gc:
|
| 401 | 406 | |
| 402 | 407 | RTS options to control the garbage collector
|
| ... | ... | @@ -162,6 +162,7 @@ data MiscFlags = MiscFlags |
| 162 | 162 | , disableDelayedOsMemoryReturn :: Bool
|
| 163 | 163 | , internalCounters :: Bool
|
| 164 | 164 | , linkerAlwaysPic :: Bool
|
| 165 | + , linkerOptimistic :: Bool
|
|
| 165 | 166 | , linkerMemBase :: Word
|
| 166 | 167 | -- ^ address to ask the OS for memory for the linker, 0 ==> off
|
| 167 | 168 | , ioManager :: IoManagerFlag
|
| ... | ... | @@ -536,6 +537,8 @@ getMiscFlags = do |
| 536 | 537 | (#{peek MISC_FLAGS, internalCounters} ptr :: IO CBool))
|
| 537 | 538 | <*> (toBool <$>
|
| 538 | 539 | (#{peek MISC_FLAGS, linkerAlwaysPic} ptr :: IO CBool))
|
| 540 | + <*> (toBool <$>
|
|
| 541 | + (#{peek MISC_FLAGS, linkerOptimistic} ptr :: IO CBool))
|
|
| 539 | 542 | <*> #{peek MISC_FLAGS, linkerMemBase} ptr
|
| 540 | 543 | <*> (toEnum . fromIntegral
|
| 541 | 544 | <$> (#{peek MISC_FLAGS, ioManager} ptr :: IO Word32))
|
| ... | ... | @@ -980,10 +980,20 @@ SymbolAddr* lookupSymbol( SymbolName* lbl ) |
| 980 | 980 | // lookupDependentSymbol directly.
|
| 981 | 981 | SymbolAddr* r = lookupDependentSymbol(lbl, NULL, NULL);
|
| 982 | 982 | if (!r) {
|
| 983 | - errorBelch("^^ Could not load '%s', dependency unresolved. "
|
|
| 984 | - "See top entry above.\n", lbl);
|
|
| 985 | - IF_DEBUG(linker, printLoadedObjects());
|
|
| 986 | - fflush(stderr);
|
|
| 983 | + if (!RtsFlags.MiscFlags.linkerOptimistic) {
|
|
| 984 | + errorBelch("^^ Could not load '%s', dependency unresolved. "
|
|
| 985 | + "See top entry above. You might consider using --optimistic-linking\n",
|
|
| 986 | + lbl);
|
|
| 987 | + IF_DEBUG(linker, printLoadedObjects());
|
|
| 988 | + fflush(stderr);
|
|
| 989 | + } else {
|
|
| 990 | + // if --optimistic-linking is passed into the RTS we allow the linker
|
|
| 991 | + // to optimistically continue
|
|
| 992 | + errorBelch("^^ Could not load '%s', dependency unresolved, "
|
|
| 993 | + "optimistically continuing\n",
|
|
| 994 | + lbl);
|
|
| 995 | + r = (void*) 0xDEADBEEF;
|
|
| 996 | + }
|
|
| 987 | 997 | }
|
| 988 | 998 | |
| 989 | 999 | if (!runPendingInitializers()) {
|
| ... | ... | @@ -269,6 +269,7 @@ void initRtsFlagsDefaults(void) |
| 269 | 269 | RtsFlags.MiscFlags.disableDelayedOsMemoryReturn = false;
|
| 270 | 270 | RtsFlags.MiscFlags.internalCounters = false;
|
| 271 | 271 | RtsFlags.MiscFlags.linkerAlwaysPic = DEFAULT_LINKER_ALWAYS_PIC;
|
| 272 | + RtsFlags.MiscFlags.linkerOptimistic = false;
|
|
| 272 | 273 | RtsFlags.MiscFlags.linkerMemBase = 0;
|
| 273 | 274 | RtsFlags.MiscFlags.ioManager = IO_MNGR_FLAG_AUTO;
|
| 274 | 275 | #if defined(THREADED_RTS) && defined(mingw32_HOST_OS)
|
| ... | ... | @@ -998,6 +999,11 @@ error = true; |
| 998 | 999 | OPTION_UNSAFE;
|
| 999 | 1000 | RtsFlags.MiscFlags.generate_dump_file = true;
|
| 1000 | 1001 | }
|
| 1002 | + else if (strequal("optimistic-linking",
|
|
| 1003 | + &rts_argv[arg][2])) {
|
|
| 1004 | + OPTION_UNSAFE;
|
|
| 1005 | + RtsFlags.MiscFlags.linkerOptimistic = true;
|
|
| 1006 | + }
|
|
| 1001 | 1007 | else if (strequal("null-eventlog-writer",
|
| 1002 | 1008 | &rts_argv[arg][2])) {
|
| 1003 | 1009 | OPTION_UNSAFE;
|
| ... | ... | @@ -267,6 +267,7 @@ typedef struct _MISC_FLAGS { |
| 267 | 267 | there as well. */
|
| 268 | 268 | bool internalCounters; /* See Note [Internal Counters Stats] */
|
| 269 | 269 | bool linkerAlwaysPic; /* Assume the object code is always PIC */
|
| 270 | + bool linkerOptimistic; /* Should the runtime linker optimistically continue */
|
|
| 270 | 271 | StgWord linkerMemBase; /* address to ask the OS for memory
|
| 271 | 272 | * for the linker, NULL ==> off */
|
| 272 | 273 | IO_MANAGER_FLAG ioManager; /* The I/O manager to use. */
|
| ... | ... | @@ -97,9 +97,22 @@ fillGot(ObjectCode * oc) { |
| 97 | 97 | if(0 == strncmp(symbol->name,"_GLOBAL_OFFSET_TABLE_",21)) {
|
| 98 | 98 | symbol->addr = oc->info->got_start;
|
| 99 | 99 | } else {
|
| 100 | - errorBelch("Failed to lookup symbol: %s\n",
|
|
| 100 | + errorBelch("Failed to lookup symbol: %s,"
|
|
| 101 | + " you might consider using --optimistic-linking\n",
|
|
| 101 | 102 | symbol->name);
|
| 102 | - return EXIT_FAILURE;
|
|
| 103 | + |
|
| 104 | + // if --optimistic-linking is passed into the
|
|
| 105 | + // RTS we allow the linker to optimistically
|
|
| 106 | + // continue
|
|
| 107 | + if (RtsFlags.MiscFlags.linkerOptimistic) {
|
|
| 108 | + errorBelch("Failed to lookup symbol: %s,"
|
|
| 109 | + " optimistically continuing.\n",
|
|
| 110 | + symbol->name);
|
|
| 111 | + symbol->addr = (void*) 0xDEADBEEF;
|
|
| 112 | + } else {
|
|
| 113 | + return EXIT_FAILURE;
|
|
| 114 | + }
|
|
| 115 | + |
|
| 103 | 116 | }
|
| 104 | 117 | }
|
| 105 | 118 | } else {
|
| 1 | +TOP=../../../..
|
|
| 2 | +include $(TOP)/mk/boilerplate.mk
|
|
| 3 | +include $(TOP)/mk/test.mk
|
|
| 4 | + |
|
| 5 | +.PHONY: T25240
|
|
| 6 | +T25240:
|
|
| 7 | + "$(TEST_HC)" $(TEST_HC_OPTS_INTERACTIVE) T25240a.hs T25240.hs +RTS --optimistic-linking -RTS |
| 1 | +{-# LANGUAGE TemplateHaskell #-}
|
|
| 2 | + |
|
| 3 | +{-
|
|
| 4 | + |
|
| 5 | +When the RTS linker loads the T25240a module to run the pure foo splice, it
|
|
| 6 | +tries to resolve the func symbol even if this function isn't required to run the
|
|
| 7 | +splice code, i.e., its dead code. This test checks that by passing the
|
|
| 8 | +--optimistic-linking flag the RTS linker continues to link even in the presence
|
|
| 9 | +of unknown symbols.
|
|
| 10 | + |
|
| 11 | +-}
|
|
| 12 | + |
|
| 13 | +module T25240 where
|
|
| 14 | + |
|
| 15 | +import T25240a
|
|
| 16 | + |
|
| 17 | +$(pure foo) |
| 1 | +ghc: ^^ Could not load 'func', dependency unresolved, optimistically continuing
|
|
| 2 | + |
| 1 | +{-# LANGUAGE TemplateHaskell #-}
|
|
| 2 | + |
|
| 3 | + |
|
| 4 | +module T25240a
|
|
| 5 | + ( foo, func
|
|
| 6 | + ) where
|
|
| 7 | + |
|
| 8 | + |
|
| 9 | +foo :: [a]
|
|
| 10 | +foo = []
|
|
| 11 | + |
|
| 12 | +foreign import ccall "func"
|
|
| 13 | + func :: Int -> Int |
| 1 | +# skip on darwin because the leading underscores will make the test fail
|
|
| 2 | +test('T25240', [when(leading_underscore(),skip), req_rts_linker, extra_files(['T25240a.hs'])],
|
|
| 3 | + makefile_test, ['T25240']) |
| 1 | -<interactive>: ^^ Could not load 'blah', dependency unresolved. See top entry above.
|
|
| 1 | +<interactive>: ^^ Could not load 'blah', dependency unresolved. See top entry above. You might consider using --optimistic-linking
|
|
| 2 | 2 |
| ... | ... | @@ -9120,7 +9120,7 @@ module GHC.RTS.Flags where |
| 9120 | 9120 | type IoSubSystem :: *
|
| 9121 | 9121 | data IoSubSystem = IoPOSIX | IoNative
|
| 9122 | 9122 | type MiscFlags :: *
|
| 9123 | - data MiscFlags = MiscFlags {tickInterval :: RtsTime, installSignalHandlers :: GHC.Types.Bool, installSEHHandlers :: GHC.Types.Bool, generateCrashDumpFile :: GHC.Types.Bool, generateStackTrace :: GHC.Types.Bool, machineReadable :: GHC.Types.Bool, disableDelayedOsMemoryReturn :: GHC.Types.Bool, internalCounters :: GHC.Types.Bool, linkerAlwaysPic :: GHC.Types.Bool, linkerMemBase :: GHC.Types.Word, ioManager :: IoManagerFlag, numIoWorkerThreads :: GHC.Internal.Word.Word32}
|
|
| 9123 | + data MiscFlags = MiscFlags {tickInterval :: RtsTime, installSignalHandlers :: GHC.Types.Bool, installSEHHandlers :: GHC.Types.Bool, generateCrashDumpFile :: GHC.Types.Bool, generateStackTrace :: GHC.Types.Bool, machineReadable :: GHC.Types.Bool, disableDelayedOsMemoryReturn :: GHC.Types.Bool, internalCounters :: GHC.Types.Bool, linkerAlwaysPic :: GHC.Types.Bool, linkerOptimistic :: GHC.Types.Bool, linkerMemBase :: GHC.Types.Word, ioManager :: IoManagerFlag, numIoWorkerThreads :: GHC.Internal.Word.Word32}
|
|
| 9124 | 9124 | type ParFlags :: *
|
| 9125 | 9125 | data ParFlags = ParFlags {nCapabilities :: GHC.Internal.Word.Word32, migrate :: GHC.Types.Bool, maxLocalSparks :: GHC.Internal.Word.Word32, parGcEnabled :: GHC.Types.Bool, parGcGen :: GHC.Internal.Word.Word32, parGcLoadBalancingEnabled :: GHC.Types.Bool, parGcLoadBalancingGen :: GHC.Internal.Word.Word32, parGcNoSyncWithIdle :: GHC.Internal.Word.Word32, parGcThreads :: GHC.Internal.Word.Word32, setAffinity :: GHC.Types.Bool}
|
| 9126 | 9126 | type ProfFlags :: *
|
| ... | ... | @@ -12162,7 +12162,7 @@ module GHC.RTS.Flags where |
| 12162 | 12162 | type IoSubSystem :: *
|
| 12163 | 12163 | data IoSubSystem = IoPOSIX | IoNative
|
| 12164 | 12164 | type MiscFlags :: *
|
| 12165 | - data MiscFlags = MiscFlags {tickInterval :: RtsTime, installSignalHandlers :: GHC.Types.Bool, installSEHHandlers :: GHC.Types.Bool, generateCrashDumpFile :: GHC.Types.Bool, generateStackTrace :: GHC.Types.Bool, machineReadable :: GHC.Types.Bool, disableDelayedOsMemoryReturn :: GHC.Types.Bool, internalCounters :: GHC.Types.Bool, linkerAlwaysPic :: GHC.Types.Bool, linkerMemBase :: GHC.Types.Word, ioManager :: IoManagerFlag, numIoWorkerThreads :: GHC.Internal.Word.Word32}
|
|
| 12165 | + data MiscFlags = MiscFlags {tickInterval :: RtsTime, installSignalHandlers :: GHC.Types.Bool, installSEHHandlers :: GHC.Types.Bool, generateCrashDumpFile :: GHC.Types.Bool, generateStackTrace :: GHC.Types.Bool, machineReadable :: GHC.Types.Bool, disableDelayedOsMemoryReturn :: GHC.Types.Bool, internalCounters :: GHC.Types.Bool, linkerAlwaysPic :: GHC.Types.Bool, linkerOptimistic :: GHC.Types.Bool, linkerMemBase :: GHC.Types.Word, ioManager :: IoManagerFlag, numIoWorkerThreads :: GHC.Internal.Word.Word32}
|
|
| 12166 | 12166 | type ParFlags :: *
|
| 12167 | 12167 | data ParFlags = ParFlags {nCapabilities :: GHC.Internal.Word.Word32, migrate :: GHC.Types.Bool, maxLocalSparks :: GHC.Internal.Word.Word32, parGcEnabled :: GHC.Types.Bool, parGcGen :: GHC.Internal.Word.Word32, parGcLoadBalancingEnabled :: GHC.Types.Bool, parGcLoadBalancingGen :: GHC.Internal.Word.Word32, parGcNoSyncWithIdle :: GHC.Internal.Word.Word32, parGcThreads :: GHC.Internal.Word.Word32, setAffinity :: GHC.Types.Bool}
|
| 12168 | 12168 | type ProfFlags :: *
|
| ... | ... | @@ -9344,7 +9344,7 @@ module GHC.RTS.Flags where |
| 9344 | 9344 | type IoSubSystem :: *
|
| 9345 | 9345 | data IoSubSystem = IoPOSIX | IoNative
|
| 9346 | 9346 | type MiscFlags :: *
|
| 9347 | - data MiscFlags = MiscFlags {tickInterval :: RtsTime, installSignalHandlers :: GHC.Types.Bool, installSEHHandlers :: GHC.Types.Bool, generateCrashDumpFile :: GHC.Types.Bool, generateStackTrace :: GHC.Types.Bool, machineReadable :: GHC.Types.Bool, disableDelayedOsMemoryReturn :: GHC.Types.Bool, internalCounters :: GHC.Types.Bool, linkerAlwaysPic :: GHC.Types.Bool, linkerMemBase :: GHC.Types.Word, ioManager :: IoManagerFlag, numIoWorkerThreads :: GHC.Internal.Word.Word32}
|
|
| 9347 | + data MiscFlags = MiscFlags {tickInterval :: RtsTime, installSignalHandlers :: GHC.Types.Bool, installSEHHandlers :: GHC.Types.Bool, generateCrashDumpFile :: GHC.Types.Bool, generateStackTrace :: GHC.Types.Bool, machineReadable :: GHC.Types.Bool, disableDelayedOsMemoryReturn :: GHC.Types.Bool, internalCounters :: GHC.Types.Bool, linkerAlwaysPic :: GHC.Types.Bool, linkerOptimistic :: GHC.Types.Bool, linkerMemBase :: GHC.Types.Word, ioManager :: IoManagerFlag, numIoWorkerThreads :: GHC.Internal.Word.Word32}
|
|
| 9348 | 9348 | type ParFlags :: *
|
| 9349 | 9349 | data ParFlags = ParFlags {nCapabilities :: GHC.Internal.Word.Word32, migrate :: GHC.Types.Bool, maxLocalSparks :: GHC.Internal.Word.Word32, parGcEnabled :: GHC.Types.Bool, parGcGen :: GHC.Internal.Word.Word32, parGcLoadBalancingEnabled :: GHC.Types.Bool, parGcLoadBalancingGen :: GHC.Internal.Word.Word32, parGcNoSyncWithIdle :: GHC.Internal.Word.Word32, parGcThreads :: GHC.Internal.Word.Word32, setAffinity :: GHC.Types.Bool}
|
| 9350 | 9350 | type ProfFlags :: *
|
| ... | ... | @@ -9120,7 +9120,7 @@ module GHC.RTS.Flags where |
| 9120 | 9120 | type IoSubSystem :: *
|
| 9121 | 9121 | data IoSubSystem = IoPOSIX | IoNative
|
| 9122 | 9122 | type MiscFlags :: *
|
| 9123 | - data MiscFlags = MiscFlags {tickInterval :: RtsTime, installSignalHandlers :: GHC.Types.Bool, installSEHHandlers :: GHC.Types.Bool, generateCrashDumpFile :: GHC.Types.Bool, generateStackTrace :: GHC.Types.Bool, machineReadable :: GHC.Types.Bool, disableDelayedOsMemoryReturn :: GHC.Types.Bool, internalCounters :: GHC.Types.Bool, linkerAlwaysPic :: GHC.Types.Bool, linkerMemBase :: GHC.Types.Word, ioManager :: IoManagerFlag, numIoWorkerThreads :: GHC.Internal.Word.Word32}
|
|
| 9123 | + data MiscFlags = MiscFlags {tickInterval :: RtsTime, installSignalHandlers :: GHC.Types.Bool, installSEHHandlers :: GHC.Types.Bool, generateCrashDumpFile :: GHC.Types.Bool, generateStackTrace :: GHC.Types.Bool, machineReadable :: GHC.Types.Bool, disableDelayedOsMemoryReturn :: GHC.Types.Bool, internalCounters :: GHC.Types.Bool, linkerAlwaysPic :: GHC.Types.Bool, linkerOptimistic :: GHC.Types.Bool, linkerMemBase :: GHC.Types.Word, ioManager :: IoManagerFlag, numIoWorkerThreads :: GHC.Internal.Word.Word32}
|
|
| 9124 | 9124 | type ParFlags :: *
|
| 9125 | 9125 | data ParFlags = ParFlags {nCapabilities :: GHC.Internal.Word.Word32, migrate :: GHC.Types.Bool, maxLocalSparks :: GHC.Internal.Word.Word32, parGcEnabled :: GHC.Types.Bool, parGcGen :: GHC.Internal.Word.Word32, parGcLoadBalancingEnabled :: GHC.Types.Bool, parGcLoadBalancingGen :: GHC.Internal.Word.Word32, parGcNoSyncWithIdle :: GHC.Internal.Word.Word32, parGcThreads :: GHC.Internal.Word.Word32, setAffinity :: GHC.Types.Bool}
|
| 9126 | 9126 | type ProfFlags :: *
|
| ... | ... | @@ -9,7 +9,7 @@ This could be caused by: |
| 9 | 9 | * Specifying the same object file twice on the GHCi command line
|
| 10 | 10 | * An incorrect `package.conf' entry, causing some object to be
|
| 11 | 11 | loaded twice.
|
| 12 | -ghc-stage2: ^^ Could not load 'c', dependency unresolved. See top entry above.
|
|
| 12 | +ghc-stage2: ^^ Could not load 'c', dependency unresolved. See top entry above. You might consider using --optimistic-linking
|
|
| 13 | 13 | |
| 14 | 14 | |
| 15 | 15 | GHC.ByteCode.Linker: can't find label
|
| ... | ... | @@ -9,7 +9,7 @@ This could be caused by: |
| 9 | 9 | * Specifying the same object file twice on the GHCi command line
|
| 10 | 10 | * An incorrect `package.conf' entry, causing some object to be
|
| 11 | 11 | loaded twice.
|
| 12 | -ghc-stage2.exe: ^^ Could not load 'c', dependency unresolved. See top entry above.
|
|
| 12 | +ghc-stage2.exe: ^^ Could not load 'c', dependency unresolved. See top entry above. You might consider using --optimistic-linking
|
|
| 13 | 13 | |
| 14 | 14 | |
| 15 | 15 | GHC.ByteCode.Linker: can't find label
|
| ... | ... | @@ -9,7 +9,7 @@ This could be caused by: |
| 9 | 9 | * Specifying the same object file twice on the GHCi command line
|
| 10 | 10 | * An incorrect `package.conf' entry, causing some object to be
|
| 11 | 11 | loaded twice.
|
| 12 | -ghc-stage2: ^^ Could not load 'c', dependency unresolved. See top entry above.
|
|
| 12 | +ghc-stage2: ^^ Could not load 'c', dependency unresolved. See top entry above. You might consider using --optimistic-linking
|
|
| 13 | 13 | |
| 14 | 14 | |
| 15 | 15 | GHC.ByteCode.Linker: can't find label
|
| ... | ... | @@ -9,7 +9,7 @@ This could be caused by: |
| 9 | 9 | * Specifying the same object file twice on the GHCi command line
|
| 10 | 10 | * An incorrect `package.conf' entry, causing some object to be
|
| 11 | 11 | loaded twice.
|
| 12 | -ghc-stage2.exe: ^^ Could not load 'c', dependency unresolved. See top entry above.
|
|
| 12 | +ghc-stage2.exe: ^^ Could not load 'c', dependency unresolved. See top entry above. You might consider using --optimistic-linking
|
|
| 13 | 13 | |
| 14 | 14 | |
| 15 | 15 | GHC.ByteCode.Linker: can't find label
|