diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,15 @@
+# 0.12 -- 2026-01-29
+
+# 0.11 -- 2025-11-09
+
+* Sync the version number with `crux-mir-0.11` as part of the overall Crux 0.10
+  release.
+
+# 0.10 -- 2025-03-24
+
+* Sync the version number with `crux-mir-0.10` as part of the overall Crux 0.10
+  release.
+
 # 0.9.1 -- 2025-03-21
 
 * Add support for the Bitwuzla SMT solver in the test suite.
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,12 +1,16 @@
-# Overview
+# Crux-LLVM
 
+<img src="../doc/crux.svg" alt="Crux logo" width="25%" />
+
+## Overview
+
 The `crux-llvm` tool (and corresponding C library) are intended for
 verifying C programs containing inline specifications (in the form of
 function calls to create non-deterministic values and assert
 properties). For more information about Crux itself, refer to the
 [official website](https://crux.galois.com).
 
-# Licensing and bundled tools
+## Licensing and bundled tools
 
 `crux-llvm` is licensed under the 3-Clause BSD license. For more details, refer
 to the `LICENSE` file. Some binary distributions of `crux-llvm` come bundled
@@ -21,7 +25,7 @@
 `crux-llvm` does not link against any of these tools directly. As a result,
 `crux-llvm` adheres to the GPLv3 licensing terms in Yices.
 
-# Prerequisites
+## Prerequisites
 
 Before running `crux-llvm`, you'll need to install the following
 software:
@@ -46,11 +50,11 @@
 and `cabal` version 3.10. We recommend Yices 2.6.x, and Z3
 4.8.x. Technically, only one of Yices or Z3 is required, and CVC4 is
 also supported. However, in practice, having both tends to be
-convenient. Finally, LLVM versions from 3.6 through 16 are likely to
+convenient. Finally, LLVM versions from 3.6 through 21 are likely to
 work well, and any failures with versions in that range should be
 [reported as bugs](https://github.com/GaloisInc/crucible/issues).
 
-# Building
+## Building
 
 The `crux-llvm` tool can be built by doing the following:
 
@@ -72,7 +76,7 @@
 You can also use the `--installdir` flag to install binaries in a
 different location.
 
-# Invocation
+## Invocation
 
 In the `crux-llvm` directory (either in the repository or the root of
 the directory extracted from a distribution tarball), to analyze
@@ -157,7 +161,7 @@
 `main`, these arguments will _not_ be passed automatically to the
 counterexample executables.
 
-# API
+## API
 
 The [`crucible.h` header file](c-src/includes/crucible.h) contains
 declarations of several functions that can be used to describe the
@@ -191,7 +195,7 @@
 that the conditions used in assertions are directly available and not
 obscured by a conditional wrapper around an error function.
 
-# Standard C and C++ Libraries
+## Standard C and C++ Libraries
 
 The code supplied to `crux-llvm` should be largely self-contained,
 without calls to external code. However, some standard library functions
@@ -253,7 +257,7 @@
 most C++ code that doesn't use third-party libraries (or that includes
 those libraries linked into a single bitcode file) should work.
 
-# Command-line Flags
+## Command-line Flags
 
 The most important and only required argument to `crux-llvm` is the
 source file or list of source files to analyze. In the case that
@@ -408,7 +412,7 @@
 
 * `--debug`: Start the Crucible debugger.
 
-# Environment Variables
+## Environment Variables
 
 The following environment variables are supported:
 
@@ -423,7 +427,7 @@
 * `LLVM_LINK`: Specify the name of the `llvm-link` command used to
   combine multiple LLVM bitcode files.
 
-# Configuration Files
+## Configuration Files
 
 In addition to command-line flags and environment variables, `crux-llvm`
 can be configured with a key-value input file. The file consists of a
@@ -450,7 +454,7 @@
 `llvm-link`, instructs `crux-llvm` not to create counter-example
 demonstration executables, and provides a list of input files.
 
-# Symbolic I/O [Experimental]
+## Symbolic I/O [Experimental]
 
 Note that Symbolic I/O is currently experimental.  We expect that the API (both
 internal and command line) will change.
@@ -534,7 +538,7 @@
 sequential file descriptors. In contrast, the real program would allocate the
 same file descriptor to both (as only one branch would be taken).
 
-# Test suite
+## Test suite
 
 The `crux-llvm` test suite is implemented in `test/Test.hs`, and the
 accompanying test case data can be found under `test-data`. Each test case
@@ -574,7 +578,7 @@
 read anything past `SKIP_TEST`, so the rest of the file can be used to document
 why the test is skipped on that particular configuration.
 
-# Acknowledgements
+## Acknowledgements
 
 Crux is partly based upon work supported by the Defense Advanced
 Research Projects Agency (DARPA) under Contract No. N66001-18-C-4011.
diff --git a/crux-llvm.cabal b/crux-llvm.cabal
--- a/crux-llvm.cabal
+++ b/crux-llvm.cabal
@@ -1,6 +1,6 @@
 Cabal-version: 2.2
 Name:          crux-llvm
-Version:       0.9.1
+Version:       0.12
 Author:        Galois Inc.
 Maintainer:    rscott@galois.com, kquick@galois.com, langston@galois.com
 Copyright:     (c) Galois, Inc 2014-2022
@@ -55,7 +55,7 @@
                -Wincomplete-uni-patterns
   ghc-prof-options: -O2
   default-language: Haskell2010
-  build-depends:    base >= 4.8 && < 4.20
+  build-depends:    base >= 4.8 && < 4.21
                   , bytestring
                   , containers
                   , crucible
@@ -69,6 +69,97 @@
                   , text
                   , what4
 
+common warns
+  -- Specifying -Wall and -Werror can cause the project to fail to build on
+  -- newer versions of GHC simply due to new warnings being added to -Wall. To
+  -- prevent this from happening we manually list which warnings should be
+  -- considered errors. We also list some warnings that are not in -Wall, though
+  -- try to avoid "opinionated" warnings (though this judgement is clearly
+  -- subjective).
+  --
+  -- Warnings are grouped by the GHC version that introduced them, and then
+  -- alphabetically.
+  --
+  -- A list of warnings and the GHC version in which they were introduced is
+  -- available here:
+  -- https://ghc.gitlab.haskell.org/ghc/doc/users_guide/using-warnings.html
+
+  -- Since GHC 9.6 or earlier:
+  ghc-options:
+    -Wall
+    -Werror=ambiguous-fields
+    -Werror=compat-unqualified-imports
+    -Werror=deferred-type-errors
+    -Werror=deprecated-flags
+    -Werror=deprecations
+    -Werror=deriving-defaults
+    -Werror=deriving-typeable
+    -Werror=dodgy-foreign-imports
+    -Werror=duplicate-exports
+    -Werror=empty-enumerations
+    -Werror=gadt-mono-local-binds
+    -Werror=identities
+    -Werror=inaccessible-code
+    -Werror=incomplete-patterns
+    -Werror=incomplete-record-updates
+    -Werror=incomplete-uni-patterns
+    -Werror=inline-rule-shadowing
+    -Werror=misplaced-pragmas
+    -Werror=missed-extra-shared-lib
+    -Werror=missing-exported-signatures
+    -Werror=missing-fields
+    -Werror=missing-home-modules
+    -Werror=missing-methods
+    -Werror=missing-pattern-synonym-signatures
+    -Werror=missing-signatures
+    -Werror=name-shadowing
+    -Werror=noncanonical-monad-instances
+    -Werror=noncanonical-monoid-instances
+    -Werror=operator-whitespace
+    -Werror=operator-whitespace-ext-conflict
+    -Werror=orphans
+    -Werror=overflowed-literals
+    -Werror=overlapping-patterns
+    -Werror=partial-fields
+    -Werror=partial-type-signatures
+    -Werror=redundant-bang-patterns
+    -Werror=redundant-record-wildcards
+    -Werror=redundant-strictness-flags
+    -Werror=simplifiable-class-constraints
+    -Werror=star-binder
+    -Werror=star-is-type
+    -Werror=tabs
+    -Werror=type-defaults
+    -Werror=typed-holes
+    -Werror=type-equality-out-of-scope
+    -Werror=type-equality-requires-operators
+    -Werror=unicode-bidirectional-format-characters
+    -Werror=unrecognised-pragmas
+    -Werror=unrecognised-warning-flags
+    -Werror=unsupported-calling-conventions
+    -Werror=unsupported-llvm-version
+    -Werror=unused-do-bind
+    -Werror=unused-imports
+    -Werror=unused-record-wildcards
+    -Werror=warnings-deprecations
+    -Werror=wrong-do-bind
+
+  if impl(ghc < 9.8)
+    ghc-options:
+      -Werror=forall-identifier
+
+  if impl(ghc >= 9.8)
+    ghc-options:
+      -Werror=incomplete-export-warnings
+      -Werror=inconsistent-flags
+
+  if impl(ghc >= 9.10)
+    ghc-options:
+      -Werror=badly-staged-types
+      -Werror=data-kinds-tc
+      -Werror=deprecated-type-abstractions
+      -Werror=incomplete-record-selectors
+
 common testdefs
   build-depends: tasty            >= 0.10
                , tasty-hunit      >= 0.10
@@ -95,9 +186,10 @@
     aeson,
     bv-sized,
     config-schema >= 1.2.2.0,
+    crucible-debug,
     logict,
     llvm-pretty,
-    llvm-pretty-bc-parser,
+    llvm-pretty-bc-parser >= 0.5,
     mtl,
     parameterized-utils,
     prettyprinter >= 1.7.0
@@ -174,6 +266,7 @@
 
 test-suite crux-llvm-test
   import: bldflags, testdefs
+  import: warns
   type: exitcode-stdio-1.0
   hs-source-dirs: test
 
diff --git a/src/Crux/LLVM/Compile.hs b/src/Crux/LLVM/Compile.hs
--- a/src/Crux/LLVM/Compile.hs
+++ b/src/Crux/LLVM/Compile.hs
@@ -35,7 +35,7 @@
 
 import           Crux
 import qualified Crux.Config.Common as CC
-import           Crux.Model ( toDouble, showBVLiteral, showFloatLiteral
+import           Crux.Model ( toDouble, showBVLiteralSigned, showFloatLiteral
                             , showDoubleLiteral )
 import           Crux.Types
 
@@ -325,7 +325,7 @@
 ppValsC ty (Vals xs) =
   let (cty, cnm, ppRawVal) = case ty of
         BaseBVRepr n ->
-          ("int" ++ show n ++ "_t", "int" ++ show n ++ "_t", showBVLiteral n)
+          ("int" ++ show n ++ "_t", "int" ++ show n ++ "_t", showBVLiteralSigned n)
         BaseFloatRepr (FloatingPointPrecisionRepr eb sb)
           | Just Refl <- testEquality eb (knownNat @8)
           , Just Refl <- testEquality sb (knownNat @24)
diff --git a/src/Crux/LLVM/Simulate.hs b/src/Crux/LLVM/Simulate.hs
--- a/src/Crux/LLVM/Simulate.hs
+++ b/src/Crux/LLVM/Simulate.hs
@@ -1,18 +1,22 @@
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE GADTs #-}
 {-# LANGUAGE ImplicitParams #-}
 {-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE MagicHash #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeApplications #-}
 {-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE TypeSynonymInstances #-}
 
 module Crux.LLVM.Simulate where
 
+import qualified Control.Lens as Lens
 import Control.Monad (unless)
 import Data.String (fromString)
 import qualified Data.Map.Strict as Map
@@ -25,6 +29,7 @@
 import Control.Lens ((&), (%~), (%=), (^.), use, view)
 import Control.Monad.IO.Class (liftIO)
 import Data.Text as Text (Text, pack)
+import Data.Void (Void)
 import GHC.Exts ( proxy# )
 
 import System.IO (stdout)
@@ -58,6 +63,8 @@
 import Lang.Crucible.Simulator.GlobalState ( insertGlobal, lookupGlobal )
 import Lang.Crucible.Simulator.Profiling ( Metric(Metric) )
 
+-- crucible-debug
+import qualified Lang.Crucible.Debug as Debug
 
 -- crucible-llvm
 import Lang.Crucible.LLVM(llvmExtensionImpl, llvmGlobals, registerLazyModule )
@@ -100,6 +107,14 @@
 import qualified Crux.LLVM.Log as Log
 import Crux.LLVM.Overrides
 
+-- | Crux LLVM personality
+newtype CruxLLVM sym
+  = CruxLLVM { getCruxLLVM :: Debug.Context Void sym LLVM UnitType }
+
+instance Debug.HasContext (CruxLLVM sym) Void sym LLVM UnitType where
+  context = Lens.lens getCruxLLVM (const CruxLLVM)
+  {-# INLINE context #-}
+
 -- | Create a simulator context for the given architecture.
 setupSimCtxt ::
   (IsSymBackend sym bak, HasLLVMAnn sym) =>
@@ -107,16 +122,27 @@
   bak ->
   MemOptions ->
   GlobalVar Mem ->
-  SimCtxt Crux sym LLVM
-setupSimCtxt halloc bak mo memVar =
-  initSimContext bak
-                 (MapF.union llvmIntrinsicTypes llvmSymIOIntrinsicTypes)
-                 halloc
-                 stdout
-                 (fnBindingsFromList [])
-                 (llvmExtensionImpl mo)
-                 CruxPersonality
-    & profilingMetrics %~ Map.union (memMetrics memVar)
+  IO (SimCtxt CruxLLVM sym LLVM)
+setupSimCtxt halloc bak mo memVar = do
+  -- TODO(#1576): Use LLVM debugger extensions (crucible-llvm-debug)
+  let cExts = Debug.voidExts
+  inps <- Debug.defaultDebuggerInputs cExts
+  dbgCtx <-
+    Debug.initCtx
+      cExts
+      (Debug.IntrinsicPrinters MapF.empty)
+      inps
+      Debug.defaultDebuggerOutputs
+      UnitRepr
+  pure $
+    initSimContext bak
+                   (MapF.union llvmIntrinsicTypes llvmSymIOIntrinsicTypes)
+                   halloc
+                   stdout
+                   (fnBindingsFromList [])
+                   (llvmExtensionImpl mo)
+                   (CruxLLVM dbgCtx)
+      & profilingMetrics %~ Map.union (memMetrics memVar)
 
 -- | Parse an LLVM bit-code file.
 parseLLVM ::
@@ -140,7 +166,7 @@
   LLVM.Module ->
   ModuleTranslation arch ->
   Maybe (LLVMFileSystem ptrW) ->
-  OverM Crux sym LLVM ()
+  OverM CruxLLVM sym LLVM ()
 registerFunctions llvmOpts llvm_module mtrans fs0 =
   do let llvm_ctx = mtrans ^. transContext
      let ?lc = llvm_ctx ^. llvmTypeCtx
@@ -165,7 +191,7 @@
   -- | Path to the LLVM module
   FilePath ->
   LLVMOptions ->
-  Crux.SimulatorCallbacks msgs Crux.Types.CruxSimulationResult
+  Crux.SimulatorCallbacks msgs st Crux.Types.CruxSimulationResult
 simulateLLVMFile llvm_file llvmOpts =
   Crux.SimulatorCallbacks $
     do bbMapRef <- newIORef (Map.empty :: LLVMAnnMap sym)
@@ -199,8 +225,8 @@
   do let sym = backendGetSym bak
      memVar <- mkMemVar "crux:llvm_memory" halloc
 
-     let simctx = (setupSimCtxt halloc bak (memOpts llvmOpts) memVar)
-                  { printHandle = view outputHandle ?outputConfig }
+     simctx_ <- setupSimCtxt halloc bak (memOpts llvmOpts) memVar
+     let simctx = simctx_ { printHandle = view outputHandle ?outputConfig }
 
      prepped <- prepLLVMModule llvmOpts halloc bak llvm_file memVar
 
@@ -306,7 +332,7 @@
              ,  Just Refl <- testEquality w (knownNat @32)
              -> checkMainWithArguments anyCfg
 
-           _ -> throwCError (BadFun nm isMain)  -- TODO(lb): Suggest uc-crux-llvm?
+           _ -> throwCError (BadFun nm isMain)
 
     Nothing -> throwCError (MissingFun nm)
   where
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -3,7 +3,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
-module Main where
+module Main (main) where
 
 import           Control.Exception ( SomeException, catches, try, Handler(..), IOException )
 import           Control.Lens ( (^?), _Right )
@@ -15,6 +15,7 @@
 import           Data.List.Extra ( isInfixOf )
 import           Data.Maybe ( catMaybes, fromMaybe )
 import qualified Data.Text as T
+import qualified Data.Version as Version
 import           Data.Versions ( Versioning, versioning, prettyV, major )
 import qualified GHC.IO.Exception as GE
 import           Numeric.Natural
@@ -52,6 +53,9 @@
                                                            , "pre-clang14"
                                                            , "pre-clang15"
                                                            , "pre-clang16"
+                                                           , "pre-clang18"
+                                                           , "pre-clang19"
+                                                           , "pre-clang20"
                                                            ])
                                     ]
                  , TS.associatedNames = [ ("config",      "config")
@@ -408,13 +412,18 @@
           Info.arch /= "x86_64" &&
           TS.rootBaseName sweet == "T972-fail"
 
+    -- T816 has different output on GHC 9.10.1, see #1377.
+    let skipGhc910T816 =
+          Info.compilerVersion == Version.makeVersion [9, 10] &&
+          TS.rootBaseName sweet == "T816"
+
     -- If a .good file begins with SKIP_TEST, skip that test entirely. For test
     -- cases that require a minimum Clang version, this technique is used to
     -- prevent running the test on older Clang versions.
 
     skipTest <- ("SKIP_TEST" `BSIO.isPrefixOf`) <$> BSIO.readFile (TS.expectedFile expct)
 
-    if or [ skipTest, skipX86_64Tests, testLevel == "0" && longTests ]
+    if or [ skipTest, skipX86_64Tests, skipGhc910T816, testLevel == "0" && longTests ]
       then do
         when (testLevel == "0" && longTests) $
           putStrLn "*** Longer running test skipped; set CI_TEST_LEVEL=1 env var to enable"
