diff --git a/compiler/GHC/Linker/Deps.hs b/compiler/GHC/Linker/Deps.hs
index e23b68d7c7a985be4a86b67adb9d28c05c92c0ec..a6736c8bc16bf61386b6d7c2e700e00eb4a635c2 100644
--- a/compiler/GHC/Linker/Deps.hs
+++ b/compiler/GHC/Linker/Deps.hs
@@ -60,6 +60,7 @@ import System.Directory
 
 data LinkDepsOpts = LinkDepsOpts
   { ldObjSuffix   :: !String                        -- ^ Suffix of .o files
+  , ldForceDyn    :: !Bool                          -- ^ Always use .dyn_o?
   , ldOneShotMode :: !Bool                          -- ^ Is the driver in one-shot mode?
   , ldModuleGraph :: !ModuleGraph                   -- ^ Module graph
   , ldUnitEnv     :: !UnitEnv                       -- ^ Unit environment
@@ -349,6 +350,16 @@ throwProgramError opts doc = throwGhcExceptionIO (ProgramError (renderWithContex
 
 checkNonStdWay :: LinkDepsOpts -> Interp -> SrcSpan -> IO (Maybe FilePath)
 checkNonStdWay _opts interp _srcspan
+  -- On some targets (e.g. wasm) the RTS linker only supports loading
+  -- dynamic code, in which case we need to ensure the .dyn_o object
+  -- is picked (instead of .o which is also present because of
+  -- -dynamic-too)
+  | ldForceDyn _opts = do
+      let target_ways = fullWays $ ldWays _opts
+      pure $ if target_ways `hasWay` WayDyn
+        then Nothing
+        else Just $ waysTag (WayDyn `addWay` target_ways) ++ "_o"
+
   | ExternalInterp {} <- interpInstance interp = return Nothing
     -- with -fexternal-interpreter we load the .o files, whatever way
     -- they were built.  If they were built for a non-std way, then
diff --git a/compiler/GHC/Linker/Loader.hs b/compiler/GHC/Linker/Loader.hs
index bcf4ba9cc591e67e0ac40bd03b5f267d7d2ba6e8..adc729f31edd48e2167bfbb66e295098f69360c4 100644
--- a/compiler/GHC/Linker/Loader.hs
+++ b/compiler/GHC/Linker/Loader.hs
@@ -637,6 +637,7 @@ initLinkDepsOpts hsc_env = opts
   where
     opts = LinkDepsOpts
             { ldObjSuffix   = objectSuf dflags
+            , ldForceDyn    = sTargetRTSLinkerOnlySupportsSharedLibs $ settings dflags
             , ldOneShotMode = isOneShot (ghcMode dflags)
             , ldModuleGraph = hsc_mod_graph hsc_env
             , ldUnitEnv     = hsc_unit_env hsc_env