diff --git a/compiler/GHC/Linker/Deps.hs b/compiler/GHC/Linker/Deps.hs
index e363d12d4d4f89abfee53ff59958a6f6da7f8ae2..a52aabc80f6452711b82b7e3e1034fc7d7e109fc 100644
--- a/compiler/GHC/Linker/Deps.hs
+++ b/compiler/GHC/Linker/Deps.hs
@@ -59,6 +59,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
   , ldUnitEnv     :: !UnitEnv
@@ -351,6 +352,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 c3f9a8de2e1cdb7d3a3b1acc71757c8ed89595bc..d05539c4612f01c29dd43df54c06beff6628667a 100644
--- a/compiler/GHC/Linker/Loader.hs
+++ b/compiler/GHC/Linker/Loader.hs
@@ -639,6 +639,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