Skip to content

Commit 4f22217

Browse files
author
brianhuffman
authored
Merge pull request #752 from GaloisInc/issue642
Issue642
2 parents cbedbee + dc2108e commit 4f22217

File tree

7 files changed

+123
-25
lines changed

7 files changed

+123
-25
lines changed

intTests/test_issue642/Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
test.bc : test.c
2+
clang -c -emit-llvm -g -o test.bc test.c

intTests/test_issue642/test.bc

2.66 KB
Binary file not shown.

intTests/test_issue642/test.c

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include <stdlib.h>
2+
3+
int glob;
4+
5+
int foo (int *x) {
6+
return (x == &glob);
7+
}
8+
9+
int bar () {
10+
return foo(&glob);
11+
}

intTests/test_issue642/test.saw

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// This test checks whether we can use an override with a pointer
2+
// argument that aliases a global. It is a regression test for
3+
// saw-script issue #642.
4+
// https://github.com/GaloisInc/saw-script/issues/642
5+
6+
bc <- llvm_load_module "test.bc";
7+
8+
let i32 = llvm_int 32;
9+
10+
foo_ov <-
11+
crucible_llvm_verify bc "foo" [] false
12+
do {
13+
crucible_alloc_global "glob";
14+
x <- crucible_alloc i32;
15+
crucible_execute_func [x];
16+
crucible_return (crucible_term {{ 0 : [32] }});
17+
}
18+
z3;
19+
20+
bar_ov1 <-
21+
crucible_llvm_verify bc "bar" [] false
22+
do {
23+
crucible_alloc_global "glob";
24+
crucible_execute_func [];
25+
crucible_return (crucible_term {{ 1 : [32] }});
26+
}
27+
z3;
28+
29+
fails (
30+
crucible_llvm_verify bc "bar" [foo_ov] false
31+
do {
32+
crucible_alloc_global "glob";
33+
crucible_execute_func [];
34+
crucible_return (crucible_term {{ 0 : [32] }});
35+
}
36+
z3
37+
);

intTests/test_issue642/test.sh

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
$SAW test.saw

src/SAWScript/Crucible/LLVM/Builtins.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1131,7 +1131,7 @@ verifyPoststate opts sc cc mspec env0 globals ret =
11311131
io $
11321132
runOverrideMatcher sym globals env0 terms0 initialFree poststateLoc $
11331133
do matchResult
1134-
learnCond opts sc cc mspec PostState (mspec ^. MS.csPostState)
1134+
learnCond opts sc cc mspec PostState (mspec ^. MS.csGlobalAllocs) (mspec ^. MS.csPostState)
11351135

11361136
st <-
11371137
case matchPost of

src/SAWScript/Crucible/LLVM/Override.hs

+71-24
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ methodSpecHandler_prestate opts sc cc args cs =
592592

593593
sequence_ [ matchArg opts sc cc cs PreState x y z | (x, y, z) <- xs]
594594

595-
learnCond opts sc cc cs PreState (cs ^. MS.csPreState)
595+
learnCond opts sc cc cs PreState (cs ^. MS.csGlobalAllocs) (cs ^. MS.csPreState)
596596

597597

598598
-- | Use a method spec to override the behavior of a function.
@@ -619,14 +619,15 @@ learnCond :: (?lc :: Crucible.TypeContext, Crucible.HasPtrWidth (Crucible.ArchWi
619619
-> LLVMCrucibleContext arch
620620
-> MS.CrucibleMethodSpecIR (LLVM arch)
621621
-> PrePost
622+
-> [MS.AllocGlobal (LLVM arch)]
622623
-> MS.StateSpec (LLVM arch)
623624
-> OverrideMatcher (LLVM arch) md ()
624-
learnCond opts sc cc cs prepost ss =
625+
learnCond opts sc cc cs prepost globals ss =
625626
do let loc = cs ^. MS.csLoc
626627
matchPointsTos opts sc cc cs prepost (ss ^. MS.csPointsTos)
627628
traverse_ (learnSetupCondition opts sc cc cs prepost) (ss ^. MS.csConditions)
628629
enforcePointerValidity cc loc ss
629-
enforceDisjointness loc ss
630+
enforceDisjointness cc loc globals ss
630631
enforceCompleteSubstitution loc ss
631632

632633

@@ -743,41 +744,87 @@ enforcePointerValidity cc loc ss =
743744
-- allowed to alias other read-only allocations, however.
744745
enforceDisjointness ::
745746
(?lc :: Crucible.TypeContext, Crucible.HasPtrWidth (Crucible.ArchWidth arch)) =>
747+
LLVMCrucibleContext arch ->
746748
W4.ProgramLoc ->
749+
[MS.AllocGlobal (LLVM arch)] ->
747750
MS.StateSpec (LLVM arch) ->
748751
OverrideMatcher (LLVM arch) md ()
749-
enforceDisjointness loc ss =
752+
enforceDisjointness cc loc globals ss =
750753
do sym <- Ov.getSymInterface
751754
sub <- OM (use setupValueSub)
755+
mem <- readGlobal $ Crucible.llvmMemVar $ ccLLVMContext cc
752756
let (allocsRW, allocsRO) = Map.partition (view isMut) (view MS.csAllocs ss)
753757
memsRW = Map.elems $ Map.intersectionWith (,) allocsRW sub
754758
memsRO = Map.elems $ Map.intersectionWith (,) allocsRO sub
755759

756760
-- Ensure that all RW regions are disjoint from each other, and
757761
-- that all RW regions are disjoint from all RO regions.
758762
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
779766
]
780767

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+
781828
------------------------------------------------------------------------
782829

783830
-- | For each points-to statement read the memory value through the

0 commit comments

Comments
 (0)