@@ -592,7 +592,7 @@ methodSpecHandler_prestate opts sc cc args cs =
592
592
593
593
sequence_ [ matchArg opts sc cc cs PreState x y z | (x, y, z) <- xs]
594
594
595
- learnCond opts sc cc cs PreState (cs ^. MS. csPreState)
595
+ learnCond opts sc cc cs PreState (cs ^. MS. csGlobalAllocs) (cs ^. MS. csPreState)
596
596
597
597
598
598
-- | Use a method spec to override the behavior of a function.
@@ -619,14 +619,15 @@ learnCond :: (?lc :: Crucible.TypeContext, Crucible.HasPtrWidth (Crucible.ArchWi
619
619
-> LLVMCrucibleContext arch
620
620
-> MS. CrucibleMethodSpecIR (LLVM arch )
621
621
-> PrePost
622
+ -> [MS. AllocGlobal (LLVM arch )]
622
623
-> MS. StateSpec (LLVM arch )
623
624
-> OverrideMatcher (LLVM arch ) md ()
624
- learnCond opts sc cc cs prepost ss =
625
+ learnCond opts sc cc cs prepost globals ss =
625
626
do let loc = cs ^. MS. csLoc
626
627
matchPointsTos opts sc cc cs prepost (ss ^. MS. csPointsTos)
627
628
traverse_ (learnSetupCondition opts sc cc cs prepost) (ss ^. MS. csConditions)
628
629
enforcePointerValidity cc loc ss
629
- enforceDisjointness loc ss
630
+ enforceDisjointness cc loc globals ss
630
631
enforceCompleteSubstitution loc ss
631
632
632
633
@@ -743,12 +744,15 @@ enforcePointerValidity cc loc ss =
743
744
-- allowed to alias other read-only allocations, however.
744
745
enforceDisjointness ::
745
746
(? lc :: Crucible. TypeContext , Crucible. HasPtrWidth (Crucible. ArchWidth arch )) =>
747
+ LLVMCrucibleContext arch ->
746
748
W4. ProgramLoc ->
749
+ [MS. AllocGlobal (LLVM arch )] ->
747
750
MS. StateSpec (LLVM arch ) ->
748
751
OverrideMatcher (LLVM arch ) md ()
749
- enforceDisjointness loc ss =
752
+ enforceDisjointness cc loc globals ss =
750
753
do sym <- Ov. getSymInterface
751
754
sub <- OM (use setupValueSub)
755
+ mem <- readGlobal $ Crucible. llvmMemVar $ ccLLVMContext cc
752
756
let (allocsRW, allocsRO) = Map. partition (view isMut) (view MS. csAllocs ss)
753
757
memsRW = Map. elems $ Map. intersectionWith (,) allocsRW sub
754
758
memsRO = Map. elems $ Map. intersectionWith (,) allocsRO sub
@@ -761,6 +765,19 @@ enforceDisjointness loc ss =
761
765
, q <- ps ++ memsRO
762
766
]
763
767
768
+ -- Ensure that all RW and RO regions are disjoint from mutable
769
+ -- global regions.
770
+ let resolveAllocGlobal g@ (LLVMAllocGlobal _ nm) =
771
+ do ptr <- liftIO $ Crucible. doResolveGlobal sym mem nm
772
+ pure (g, ptr)
773
+ globals' <- traverse resolveAllocGlobal globals
774
+ sequence_
775
+ [ enforceDisjointAllocGlobal sym loc p q
776
+ | p <- memsRW ++ memsRO
777
+ , q <- globals'
778
+ ]
779
+
780
+ -- | Assert that two LLVM allocations are disjoint from each other.
764
781
enforceDisjointAllocSpec ::
765
782
(Crucible. HasPtrWidth (Crucible. ArchWidth arch )) =>
766
783
Sym -> W4. ProgramLoc ->
@@ -788,6 +805,26 @@ enforceDisjointAllocSpec sym loc
788
805
addAssert c $ Crucible. SimError loc $
789
806
Crucible. AssertFailureSimError msg " "
790
807
808
+ -- | Assert that an LLVM allocation is disjoint from a global region.
809
+ enforceDisjointAllocGlobal ::
810
+ Sym -> W4. ProgramLoc ->
811
+ (LLVMAllocSpec , LLVMPtr (Crucible. ArchWidth arch )) ->
812
+ (LLVMAllocGlobal arch , LLVMPtr (Crucible. ArchWidth arch )) ->
813
+ OverrideMatcher (LLVM arch ) md ()
814
+ enforceDisjointAllocGlobal sym loc
815
+ (LLVMAllocSpec _pmut _pty _palign psz _ploc, p)
816
+ (LLVMAllocGlobal _qloc (L. Symbol qname), q) =
817
+ do let Crucible. LLVMPointer pblk _ = p
818
+ let Crucible. LLVMPointer qblk _ = q
819
+ c <- liftIO $ W4. notPred sym =<< W4. natEq sym pblk qblk
820
+ let msg =
821
+ " Memory regions not disjoint: "
822
+ ++ " (base=" ++ show (Crucible. ppPtr p) ++ " , size=" ++ show psz ++ " )"
823
+ ++ " and "
824
+ ++ " global " ++ show qname ++ " (base=" ++ show (Crucible. ppPtr q) ++ " )"
825
+ addAssert c $ Crucible. SimError loc $
826
+ Crucible. AssertFailureSimError msg " "
827
+
791
828
------------------------------------------------------------------------
792
829
793
830
-- | For each points-to statement read the memory value through the
0 commit comments