Skip to content

Commit

Permalink
x86-symbolic: Use SysV-compatible stack setup in test suite
Browse files Browse the repository at this point in the history
Fix a logic bug (bytes, not bits!) along the way
  • Loading branch information
langston-barrett committed Sep 11, 2024
1 parent b37e907 commit edc9635
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 6 deletions.
12 changes: 9 additions & 3 deletions symbolic/src/Data/Macaw/Symbolic/Testing.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ module Data.Macaw.Symbolic.Testing (
MemModelPreset(..),
describeMemModelPreset,
toAddrSymMap,
freshRegs,
InitialMem(..),
initialMem,
lazyInitialMem,
simDiscoveredFunction,
summarizeExecution,
-- * Execution features
SomeBackend(..),
defaultExecFeatures,
Expand Down Expand Up @@ -337,7 +343,7 @@ defaultRegs ::
bak ->
MS.ArchVals arch ->
CLM.MemImpl sym ->
IO (CS.RegEntry sym (MS.ArchRegStruct arch) , CLM.MemImpl sym)
IO (CS.RegEntry sym (MS.ArchRegStruct arch), CLM.MemImpl sym)
defaultRegs bak archVals mem = do
let sym = CB.backendGetSym bak

Expand Down Expand Up @@ -583,8 +589,8 @@ lazyInitialMem binfo bak archInfo archVals = do

data InitialMem p sym arch
= InitialMem
{ _initMemMem :: CLM.MemImpl sym
, _initMemMmConf :: MS.MemModelConfig p sym arch CLM.Mem
{ initMemMem :: CLM.MemImpl sym
, initMemMmConf :: MS.MemModelConfig p sym arch CLM.Mem
}

-- | Set up the symbolic execution engine with initial states and execute
Expand Down
1 change: 1 addition & 0 deletions x86_symbolic/macaw-x86-symbolic.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ test-suite macaw-x86-symbolic-tests
hs-source-dirs: tests
build-depends:
base >= 4,
bv-sized,
bytestring,
containers,
crucible,
Expand Down
2 changes: 1 addition & 1 deletion x86_symbolic/src/Data/Macaw/X86/Symbolic/ABI/SysV.hs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ writeRetAddr bak mem sp retAddr = do
let ?ptrWidth = MM.ptrWidth (getRetAddr retAddr)
ptrSzBv <- WI.bvLit sym ?ptrWidth (BVS.mkBV ?ptrWidth ptrBytes)
top <- MM.ptrSub sym ?ptrWidth (getStackPointer sp) ptrSzBv
let i64 = MM.bitvectorType (Bytes.toBytes (64 :: Int))
let i64 = MM.bitvectorType (Bytes.toBytes (8 :: Int))
let val = MM.ptrToPtrVal (getRetAddr retAddr)
mem' <- MM.storeRaw bak mem top i64 CLD.noAlignment val
pure (StackPointer top, mem')
Expand Down
61 changes: 59 additions & 2 deletions x86_symbolic/tests/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
module Main (main) where

import Control.Lens ( (^.) )
import qualified Data.BitVector.Sized as BVS
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as BS8
import qualified Data.ElfEdit as Elf
Expand All @@ -18,6 +20,7 @@ import qualified Data.Parameterized.Classes as PC
import qualified Data.Parameterized.Nonce as PN
import Data.Parameterized.Some ( Some(..) )
import Data.Proxy ( Proxy(..) )
import qualified Data.Sequence as Seq
import qualified Prettyprinter as PP
import System.FilePath ( (</>), (<.>) )
import qualified System.FilePath.Glob as SFG
Expand All @@ -34,19 +37,24 @@ import qualified Data.Macaw.Symbolic.Testing as MST
import qualified Data.Macaw.X86 as MX
import Data.Macaw.X86.Symbolic ()
import qualified Data.Macaw.X86.Symbolic as MXS
import qualified Data.Macaw.X86.Symbolic.ABI.SysV as SysV
import qualified What4.Config as WC
import qualified What4.Interface as WI
import qualified What4.ProblemFeatures as WPF
import qualified What4.Solver as WS

import qualified Lang.Crucible.Backend as CB
import qualified Lang.Crucible.Backend.Online as CBO
import qualified Lang.Crucible.FunctionHandle as CFH
import qualified Lang.Crucible.Simulator as CS
import qualified Lang.Crucible.Types as CT
import qualified Lang.Crucible.LLVM.MemModel as LLVM

import qualified What4.FloatMode as W4
import qualified What4.Expr.Builder as W4
import qualified Data.Parameterized.Context as Ctx
import qualified What4.Protocol.Online as WPO
import qualified Lang.Crucible.CFG.Extension as CCE

-- | A Tasty option to tell us to save SMT queries and responses to /tmp for debugging purposes
data SaveSMT = SaveSMT Bool
Expand Down Expand Up @@ -140,6 +148,46 @@ x86ResultExtractor archVals = MST.ResultExtractor $ \regs _mem k -> do

data MacawX86SymbolicTest t = MacawX86SymbolicTest

setupRegsAndMem ::
( ext ~ MS.MacawExt MX.X86_64
, CCE.IsSyntaxExtension ext
, CB.IsSymBackend sym bak
, LLVM.HasLLVMAnn sym
, sym ~ W4.ExprBuilder scope st fs
, bak ~ CBO.OnlineBackend solver scope st fs
, WPO.OnlineSolver solver
, ?memOpts :: LLVM.MemOptions
, MS.HasMacawLazySimulatorState p sym 64
) =>
bak ->
MS.GenArchVals MS.LLVMMemory MX.X86_64 ->
MST.MemModelPreset ->
MST.BinariesInfo MX.X86_64 ->
IO ( CS.RegEntry sym (MS.ArchRegStruct MX.X86_64)
, MST.InitialMem p sym MX.X86_64
)
setupRegsAndMem bak archVals mmPreset binariesInfo = do
let sym = CB.backendGetSym bak
MST.InitialMem initMem mmConf <-
case mmPreset of
MST.DefaultMemModel -> MST.initialMem binariesInfo bak MX.x86_64_linux_info archVals
MST.LazyMemModel -> MST.lazyInitialMem binariesInfo bak MX.x86_64_linux_info archVals

let symArchFns = MS.archFunctions archVals
initRegs <- MST.freshRegs symArchFns sym
let kib = 1024
let mib = 1024 * kib
stackSize <- WI.bvLit sym CT.knownNat (BVS.mkBV CT.knownNat mib)
(regs, mem) <- SysV.allocStack bak initMem initRegs stackSize
retAddr <- SysV.freshRetAddr sym
let spilled = SysV.SpilledArgs Seq.Empty
(regs', mem') <- SysV.pushStackFrame bak mem regs spilled retAddr
let crucRegTypes = MS.crucArchRegTypes symArchFns
let regsEntry = CS.RegEntry (CT.StructRepr crucRegTypes) regs'
let iMem = MST.InitialMem mem' mmConf
pure (regsEntry, iMem)


mkSymExTest :: MST.SimulationResult -> MST.MemModelPreset -> FilePath -> TT.TestTree
mkSymExTest expected mmPreset exePath = TT.askOption $ \saveSMT@(SaveSMT _) -> TT.askOption $ \saveMacaw@(SaveMacaw _) -> TTH.testCaseSteps exePath $ \step -> do
bytes <- BS.readFile exePath
Expand Down Expand Up @@ -171,8 +219,17 @@ mkSymExTest expected mmPreset exePath = TT.askOption $ \saveSMT@(SaveSMT _) -> T
let extract = x86ResultExtractor archVals
logger <- makeGoalLogger saveSMT solver name exePath
let ?memOpts = LLVM.defaultMemOptions
simRes <- MST.simulateAndVerify solver logger bak execFeatures MX.x86_64_linux_info archVals binariesInfo mmPreset extract dfi
TTH.assertEqual "AssertionResult" expected simRes

MS.withArchConstraints archVals $ do
halloc <- CFH.newHandleAllocator
let ?recordLLVMAnnotation = \_ _ _ -> return ()

(regs, iMem) <- setupRegsAndMem bak archVals mmPreset binariesInfo
(memVar, execResult) <-
MST.simDiscoveredFunction bak execFeatures archVals halloc iMem regs binariesInfo dfi

simRes <- MST.summarizeExecution solver logger bak memVar extract execResult
TTH.assertEqual "AssertionResult" expected simRes

writeMacawIR :: (MC.ArchConstraints arch) => SaveMacaw -> String -> M.DiscoveryFunInfo arch ids -> IO ()
writeMacawIR (SaveMacaw sm) name dfi
Expand Down

0 comments on commit edc9635

Please sign in to comment.