diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+# ghc-tags-1.9 (2024-06-07)
+* Add support for GHC 9.10 and drop support for GHC 9.4.
+
 # ghc-tags-1.8 (2024-01-24)
 * Add support for GHC 9.8 and drop support for GHC 9.2.
 
diff --git a/ghc-tags.cabal b/ghc-tags.cabal
--- a/ghc-tags.cabal
+++ b/ghc-tags.cabal
@@ -1,6 +1,6 @@
 cabal-version:       3.0
 name:                ghc-tags
-version:             1.8
+version:             1.9
 synopsis:            Utility for generating ctags and etags with GHC API.
 description:         Utility for generating etags (Emacs) and ctags (Vim and other
                      editors) with GHC API for efficient project navigation.
@@ -14,7 +14,7 @@
                      README.md
 homepage:            https://github.com/arybczak/ghc-tags
 bug-reports:         https://github.com/arybczak/ghc-tags/issues
-tested-with:         GHC == { 9.4.8, 9.6.4, 9.8.1 }
+tested-with:         GHC == { 9.6.5, 9.8.2, 9.10.1 }
 
 source-repository head
   type:     git
@@ -28,12 +28,12 @@
 executable ghc-tags
   ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-A4m
 
-  if !flag(ghc-lib) && impl(ghc == 9.8.*)
+  if !flag(ghc-lib) && impl(ghc == 9.10.*)
      build-depends:    ghc, ghc-boot
   else
-     build-depends:    ghc-lib == 9.8.*
+     build-depends:    ghc-lib == 9.10.*
 
-  build-depends:       base >=4.17 && <4.20
+  build-depends:       base >=4.18 && <4.21
                      , aeson >= 2.0.0.0
                      , async
                      , attoparsec
diff --git a/src/GhcTags/Ghc.hs b/src/GhcTags/Ghc.hs
--- a/src/GhcTags/Ghc.hs
+++ b/src/GhcTags/Ghc.hs
@@ -88,15 +88,15 @@
   where
     go :: IE GhcPs -> Bool
 
-    go (IEVar _ (L _ n)) = ieWrappedName n == unLoc memberName
+    go (IEVar _ (L _ n) _) = ieWrappedName n == unLoc memberName
 
-    go (IEThingAbs _ _)  = False
+    go (IEThingAbs _ _ _)  = False
 
-    go (IEThingAll _ (L _ n)) = ieWrappedName n == unLoc className
+    go (IEThingAll _ (L _ n) _) = ieWrappedName n == unLoc className
 
-    go (IEThingWith _ _ IEWildcard{} _) = True
+    go (IEThingWith _ _ IEWildcard{} _ _) = True
 
-    go (IEThingWith _ (L _ n) NoIEWildcard ns) =
+    go (IEThingWith _ (L _ n) NoIEWildcard ns _) =
             ieWrappedName n == unLoc className
          && isInWrappedNames
       where
@@ -117,11 +117,11 @@
          -> Bool
          -- ^ is term exported
          -> GhcTag
-mkGhcTag (L SrcSpanAnn { locA = gtSrcSpan } rdrName) gtKind gtIsExported =
+mkGhcTag (L loc rdrName) gtKind gtIsExported =
     case rdrName of
       Unqual occName ->
         GhcTag { gtTag = bytesFS (occNameFS occName)
-               , gtSrcSpan
+               , gtSrcSpan = getHasLoc loc
                , gtKind
                , gtIsExported
                , gtFFI = Nothing
@@ -129,7 +129,7 @@
 
       Qual _ occName ->
         GhcTag { gtTag = bytesFS (occNameFS occName)
-               , gtSrcSpan
+               , gtSrcSpan = getHasLoc loc
                , gtKind
                , gtIsExported
                , gtFFI = Nothing
@@ -138,7 +138,7 @@
       -- Orig is the only one we are interested in
       Orig _ occName ->
         GhcTag { gtTag = bytesFS (occNameFS occName)
-               , gtSrcSpan
+               , gtSrcSpan = getHasLoc loc
                , gtKind
                , gtIsExported
                , gtFFI = Nothing
@@ -146,7 +146,7 @@
 
       Exact eName ->
         GhcTag { gtTag = bytesFS (occNameFS (nameOccName eName))
-               , gtSrcSpan
+               , gtSrcSpan = getHasLoc loc
                , gtKind
                , gtIsExported
                , gtFFI = Nothing
@@ -225,7 +225,7 @@
     -- Main routine which traverse all top level declarations.
     --
     go :: LHsDecl GhcPs -> [GhcTag] -> [GhcTag]
-    go (L SrcSpanAnn { locA = decLoc } hsDecl) tags = case hsDecl of
+    go (L loc hsDecl) tags = let decLoc = getHasLoc loc in case hsDecl of
 
       -- type or class declaration
       TyClD _ tyClDecl ->
@@ -397,7 +397,7 @@
       -> LocatedN RdrName
       -> HsConDeclGADTDetails GhcPs
       -> [GhcTag]
-    mkHsConDeclGADTDetails decLoc tyName (RecConGADT (L _ fields) _) =
+    mkHsConDeclGADTDetails decLoc tyName (RecConGADT _ (L _ fields)) =
         foldr f [] fields
       where
         f :: LConDeclField GhcPs -> [GhcTag] -> [GhcTag]
diff --git a/src/GhcTags/GhcCompat.hs b/src/GhcTags/GhcCompat.hs
--- a/src/GhcTags/GhcCompat.hs
+++ b/src/GhcTags/GhcCompat.hs
@@ -42,27 +42,14 @@
 runGhc m = do
   env <- liftIO $ do
     mySettings <- compatInitSettings libdir
-    dflags <- threadSafeInitDynFlags (defaultDynFlags mySettings)
-    newHscEnv libdir dflags
+    tmpdir <- liftIO getTemporaryDirectory
+    newHscEnv libdir $ (defaultDynFlags mySettings) { tmpDir = TempDir tmpdir }
   ref <- newIORef env
   unGhc (GHC.withCleanupSession m) (Session ref)
 
 ----------------------------------------
 -- Internal
 
--- | Adjusted version of 'GHC.Driver.Session.initDynFlags' that doesn't check
--- for colors as it's not thread safe.
-threadSafeInitDynFlags :: DynFlags -> IO DynFlags
-threadSafeInitDynFlags dflags = do
-  refRtldInfo <- newIORef Nothing
-  refRtccInfo <- newIORef Nothing
-  tmpdir      <- liftIO getTemporaryDirectory
-  pure dflags
-    { rtldInfo = refRtldInfo
-    , rtccInfo = refRtccInfo
-    , tmpDir   = TempDir tmpdir
-    }
-
 -- | Stripped version of 'GHC.Settings.IO.initSettings' that ignores the
 -- @platformConstants@ file as it's irrelevant for parsing.
 compatInitSettings :: FilePath -> IO Settings
@@ -146,16 +133,10 @@
   install_name_tool_path <- getToolSetting "install_name_tool command"
   ranlib_path <- getToolSetting "ranlib command"
 
-  touch_path <- getToolSetting "touch command"
-
-  mkdll_prog <- getToolSetting "dllwrap command"
-  let mkdll_args = []
-
   -- cpp is derived from gcc on all platforms
   -- HACK, see setPgmP below. We keep 'words' here to remember to fix
   -- Config.hs one day.
 
-
   -- Other things being equal, as and ld are simply gcc
   cc_link_args_str <- getSetting "C compiler link flags"
   let   as_prog  = cc_prog
@@ -171,7 +152,6 @@
   -- We just assume on command line
   lc_prog <- getSetting "LLVM llc command"
   lo_prog <- getSetting "LLVM opt command"
-  lcc_prog <- getSetting "LLVM clang command"
 
   let iserv_prog = libexec "ghc-iserv"
 
@@ -202,8 +182,6 @@
       , toolSettings_pgm_a   = (as_prog, as_args)
       , toolSettings_pgm_l   = (ld_prog, ld_args)
       , toolSettings_pgm_lm  = ld_r
-      , toolSettings_pgm_dll = (mkdll_prog,mkdll_args)
-      , toolSettings_pgm_T   = touch_path
       , toolSettings_pgm_windres = windres_path
       , toolSettings_pgm_ar = ar_path
       , toolSettings_pgm_otool = otool_path
@@ -211,7 +189,6 @@
       , toolSettings_pgm_ranlib = ranlib_path
       , toolSettings_pgm_lo  = (lo_prog,[])
       , toolSettings_pgm_lc  = (lc_prog,[])
-      , toolSettings_pgm_lcc = (lcc_prog,[])
       , toolSettings_pgm_i   = iserv_prog
       , toolSettings_opt_L       = []
       , toolSettings_opt_P       = []
@@ -223,7 +200,6 @@
       , toolSettings_opt_l       = []
       , toolSettings_opt_lm      = []
       , toolSettings_opt_windres = []
-      , toolSettings_opt_lcc     = []
       , toolSettings_opt_lo      = []
       , toolSettings_opt_lc      = []
       , toolSettings_opt_i       = []
