@@ -30,6 +30,7 @@ import qualified Data.Set as Set
30
30
import Data.Vector (Vector )
31
31
import qualified Data.Vector as V
32
32
import GHC.Stack (HasCallStack )
33
+ import qualified Data.BitVector.Sized as BV
33
34
34
35
import Lang.Crucible.Backend
35
36
import Lang.Crucible.Simulator.RegValue
@@ -52,6 +53,7 @@ import SAWCentral.Crucible.MIR.TypeShape
52
53
import Mir.Intrinsics
53
54
import qualified Mir.Mir as M
54
55
import Mir.Compositional.State
56
+ import Lang.Crucible.Simulator
55
57
56
58
57
59
-- | Run `f` on each `SymExpr` in `v`.
@@ -306,6 +308,85 @@ exprToTerm sym sc w4VarMapRef val = liftIO $ do
306
308
term <- SAW. scVariable sc ec
307
309
return term
308
310
311
+
312
+ -- | Try to convert a Crucible register value into a SAW core `Term`, using
313
+ -- a `CryTermAdaptor` to validate and convert references to slices.
314
+ -- We check that references to slices match the expected length specified
315
+ -- in the `CryTermAdaptor`, and if so we read out the value stored in
316
+ -- in the slice.
317
+ regToTermWithAdapt :: forall m p sym t fs tp0 rtp args ret .
318
+ ( IsSymInterface sym ,
319
+ sym ~ MirSym t fs ,
320
+ m ~ OverrideSim (p sym ) sym MIR rtp args ret ) =>
321
+ sym ->
322
+ SAW. SharedContext ->
323
+ String ->
324
+ IORef (Map SAW. VarIndex (Some (W4. Expr t ))) ->
325
+ CryTermAdaptor Integer ->
326
+ TypeShape tp0 ->
327
+ RegValue sym tp0 ->
328
+ m SAW. Term
329
+ regToTermWithAdapt sym sc name w4VarMapRef ada0 shp0 rv0 = go ada0 shp0 rv0
330
+ where
331
+ go :: forall tp .
332
+ CryTermAdaptor Integer ->
333
+ TypeShape tp ->
334
+ RegValue sym tp ->
335
+ m SAW. Term
336
+ go ada shp rv =
337
+ case (ada, shp, rv) of
338
+ (NoAdapt , _, _) -> regToTerm sym sc name w4VarMapRef shp rv
339
+ (AdaptTuple as, TupleShape _ elems, ag) -> do
340
+ terms <- accessMirAggregate' sym elems as ag $ \ _off _sz shp' rv' a -> go a shp' rv'
341
+ liftIO $ SAW. scTuple sc terms
342
+ (AdaptArray a, ArrayShape _ _ shp', vec) -> do
343
+ terms <- goVector a shp' vec
344
+ tyTerm <- shapeToTerm' sc a shp'
345
+ liftIO $ SAW. scVector sc tyTerm terms
346
+ (AdaptDerefSlice col n elAda, SliceShape _ty elT M. Immut tpr, Ctx. Empty Ctx. :> RV mirPtr Ctx. :> RV lenExpr) ->
347
+ case BV. asUnsigned <$> W4. asBV lenExpr of
348
+ Nothing ->
349
+ fail " Slice length is not statically known"
350
+
351
+ Just n1
352
+ | n /= n1 ->
353
+ fail (unlines [
354
+ " Slice length mismatch:" ,
355
+ " Expected: " ++ show n,
356
+ " Actual : " ++ show n1
357
+ ])
358
+ | otherwise ->
359
+ do
360
+ let elShp = tyToShapeEq col elT tpr
361
+ vals <-
362
+ forM [ 0 .. n - 1 ] $ \ i ->
363
+ do
364
+ iExpr <- liftIO (W4. bvLit sym knownNat (BV. mkBV knownNat i))
365
+ elemPtr <- mirRef_offsetWrapSim mirPtr iExpr
366
+ r <- readMirRefSim tpr elemPtr
367
+ go elAda elShp r
368
+ elTyTerm <- shapeToTerm' sc elAda elShp
369
+ liftIO (SAW. scVector sc elTyTerm vals)
370
+
371
+
372
+
373
+ _ -> fail $
374
+ " type error: " ++ name ++ " got argument of unsupported type " ++ show (shapeType shp)
375
+
376
+ goVector :: forall tp .
377
+ CryTermAdaptor Integer ->
378
+ TypeShape tp ->
379
+ MirVector sym tp ->
380
+ m [SAW. Term ]
381
+ goVector ada shp (MirVector_Vector v) = mapM (go ada shp) $ toList v
382
+ goVector ada shp (MirVector_PartialVector pv) = do
383
+ forM (toList pv) $ \ rv -> do
384
+ let rv' = readMaybeType sym " field" (shapeType shp) rv
385
+ go ada shp rv'
386
+ goVector _ada _shp (MirVector_Array _) = fail $
387
+ " regToTerm: MirVector_Array not supported"
388
+
389
+
309
390
regToTerm :: forall sym t fs tp0 m .
310
391
(IsSymInterface sym , sym ~ MirSym t fs , MonadIO m , MonadFail m ) =>
311
392
sym ->
0 commit comments