@@ -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,41 +744,87 @@ 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
755
759
756
760
-- Ensure that all RW regions are disjoint from each other, and
757
761
-- that all RW regions are disjoint from all RO regions.
758
762
sequence_
759
- [ do c <- liftIO $
760
- do W4. setCurrentProgramLoc sym ploc
761
- psz' <- W4. bvLit sym Crucible. PtrWidth $ Crucible. bytesToBV Crucible. PtrWidth psz
762
- W4. setCurrentProgramLoc sym qloc
763
- qsz' <- W4. bvLit sym Crucible. PtrWidth $ Crucible. bytesToBV Crucible. PtrWidth qsz
764
- W4. setCurrentProgramLoc sym loc
765
- Crucible. buildDisjointRegionsAssertion
766
- sym Crucible. PtrWidth
767
- p psz'
768
- q qsz'
769
- let msg =
770
- " Memory regions not disjoint: "
771
- ++ " (base=" ++ show (Crucible. ppPtr p) ++ " , size=" ++ show psz ++ " )"
772
- ++ " and "
773
- ++ " (base=" ++ show (Crucible. ppPtr q) ++ " , size=" ++ show qsz ++ " )"
774
- addAssert c $ Crucible. SimError loc $
775
- Crucible. AssertFailureSimError msg " "
776
-
777
- | (LLVMAllocSpec _mut _pty _align psz ploc, p) : ps <- tails memsRW
778
- , (LLVMAllocSpec _mut _qty _align qsz qloc, q) <- ps ++ memsRO
763
+ [ enforceDisjointAllocSpec sym loc p q
764
+ | p : ps <- tails memsRW
765
+ , q <- ps ++ memsRO
779
766
]
780
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.
781
+ enforceDisjointAllocSpec ::
782
+ (Crucible. HasPtrWidth (Crucible. ArchWidth arch )) =>
783
+ Sym -> W4. ProgramLoc ->
784
+ (LLVMAllocSpec , LLVMPtr (Crucible. ArchWidth arch )) ->
785
+ (LLVMAllocSpec , LLVMPtr (Crucible. ArchWidth arch )) ->
786
+ OverrideMatcher (LLVM arch ) md ()
787
+ enforceDisjointAllocSpec sym loc
788
+ (LLVMAllocSpec _pmut _pty _palign psz ploc, p)
789
+ (LLVMAllocSpec _qmut _qty _qalign qsz qloc, q) =
790
+ do c <- liftIO $
791
+ do W4. setCurrentProgramLoc sym ploc
792
+ psz' <- W4. bvLit sym Crucible. PtrWidth $ Crucible. bytesToBV Crucible. PtrWidth psz
793
+ W4. setCurrentProgramLoc sym qloc
794
+ qsz' <- W4. bvLit sym Crucible. PtrWidth $ Crucible. bytesToBV Crucible. PtrWidth qsz
795
+ W4. setCurrentProgramLoc sym loc
796
+ Crucible. buildDisjointRegionsAssertion
797
+ sym Crucible. PtrWidth
798
+ p psz'
799
+ q qsz'
800
+ let msg =
801
+ " Memory regions not disjoint: "
802
+ ++ " (base=" ++ show (Crucible. ppPtr p) ++ " , size=" ++ show psz ++ " )"
803
+ ++ " and "
804
+ ++ " (base=" ++ show (Crucible. ppPtr q) ++ " , size=" ++ show qsz ++ " )"
805
+ addAssert c $ Crucible. SimError loc $
806
+ Crucible. AssertFailureSimError msg " "
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
+
781
828
------------------------------------------------------------------------
782
829
783
830
-- | For each points-to statement read the memory value through the
0 commit comments