Skip to content

Commit 9d096dc

Browse files
authored
Merge pull request #859 from GaloisInc/saw-aes
Small updates to x86 verification
2 parents 9a9274c + beafc24 commit 9d096dc

File tree

9 files changed

+109
-7
lines changed

9 files changed

+109
-7
lines changed

deps/flexdis86

intTests/test_llvm_x86_06/test.S

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
section .bss
2+
section .text
3+
foo:
4+
ret
5+
global discoverytest
6+
discoverytest:
7+
lea rax, [rsp]
8+
call foo
9+
lea rsp, [rax]
10+
ret
11+
global _start
12+
_start:
13+
mov rax, 60
14+
syscall

intTests/test_llvm_x86_06/test.c

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <stdint.h>
2+
#include <stdio.h>
3+
4+
extern void discoverytest();
5+
6+
void test() {
7+
discoverytest();
8+
};

intTests/test_llvm_x86_06/test.saw

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
enable_experimental;
2+
3+
m <- llvm_load_module "test.bc";
4+
5+
let discoverytest_setup = do {
6+
crucible_execute_func [];
7+
};
8+
9+
fails (crucible_llvm_verify_x86 m "./test" "discoverytest" [] false discoverytest_setup w4);
10+
11+
add_x86_preserved_reg "rax";
12+
crucible_llvm_verify_x86 m "./test" "discoverytest" [] false discoverytest_setup w4;
13+
default_x86_preserved_reg;

intTests/test_llvm_x86_06/test.sh

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/sh
2+
set -e
3+
4+
yasm -felf64 test.S
5+
ld test.o -o test
6+
clang -c -emit-llvm test.c
7+
$SAW test.saw

src/SAWScript/Crucible/LLVM/X86.hs

+43-5
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ import Data.Foldable (foldlM)
3939
import qualified Data.List.NonEmpty as NE
4040
import qualified Data.Vector as Vector
4141
import qualified Data.Text as Text
42+
import Data.Text (Text)
4243
import Data.Text.Encoding (decodeUtf8, encodeUtf8)
4344
import qualified Data.Set as Set
45+
import Data.Set (Set)
4446
import qualified Data.Map as Map
4547
import Data.Map (Map)
4648
import Data.Maybe
@@ -170,6 +172,27 @@ getReg reg regs = case Macaw.lookupX86Reg reg regs of
170172
Just (C.RV val) -> pure val
171173
Nothing -> throwX86 $ mconcat ["Invalid register: ", show reg]
172174

175+
-- TODO: extend to more than general purpose registers
176+
stringToReg :: Text -> Maybe (Some Macaw.X86Reg)
177+
stringToReg s = case s of
178+
"rax" -> Just $ Some Macaw.RAX
179+
"rbx" -> Just $ Some Macaw.RBX
180+
"rcx" -> Just $ Some Macaw.RCX
181+
"rdx" -> Just $ Some Macaw.RDX
182+
"rsp" -> Just $ Some Macaw.RSP
183+
"rbp" -> Just $ Some Macaw.RBP
184+
"rsi" -> Just $ Some Macaw.RSI
185+
"rdi" -> Just $ Some Macaw.RDI
186+
"r8" -> Just $ Some Macaw.R8
187+
"r9" -> Just $ Some Macaw.R9
188+
"r10" -> Just $ Some Macaw.R10
189+
"r11" -> Just $ Some Macaw.R11
190+
"r12" -> Just $ Some Macaw.R12
191+
"r13" -> Just $ Some Macaw.R13
192+
"r14" -> Just $ Some Macaw.R14
193+
"r15" -> Just $ Some Macaw.R15
194+
_ -> Nothing
195+
173196
cryptolUninterpreted ::
174197
(MonadIO m, MonadThrow m) =>
175198
CryptolEnv ->
@@ -217,11 +240,17 @@ crucible_llvm_verify_x86 bic opts (Some (llvmModule :: LLVMModule x)) path nm gl
217240
halloc <- getHandleAlloc
218241
let mvar = C.LLVM.llvmMemVar . view C.LLVM.transContext $ modTrans llvmModule
219242
sfs <- liftIO $ Macaw.newSymFuns sym
220-
cenv <- rwCryptol <$> getTopLevelRW
243+
rw <- getTopLevelRW
244+
let cenv = rwCryptol rw
221245
liftIO $ C.sawRegisterSymFunInterp sym (Macaw.fnAesEnc sfs) $ cryptolUninterpreted cenv "aesenc"
222246
liftIO $ C.sawRegisterSymFunInterp sym (Macaw.fnAesEncLast sfs) $ cryptolUninterpreted cenv "aesenclast"
247+
liftIO $ C.sawRegisterSymFunInterp sym (Macaw.fnAesDec sfs) $ cryptolUninterpreted cenv "aesdec"
248+
liftIO $ C.sawRegisterSymFunInterp sym (Macaw.fnAesDecLast sfs) $ cryptolUninterpreted cenv "aesdeclast"
249+
liftIO $ C.sawRegisterSymFunInterp sym (Macaw.fnAesKeyGenAssist sfs) $ cryptolUninterpreted cenv "aeskeygenassist"
250+
liftIO $ C.sawRegisterSymFunInterp sym (Macaw.fnClMul sfs) $ cryptolUninterpreted cenv "clmul"
223251

224-
(C.SomeCFG cfg, elf, relf, addr, cfgs) <- liftIO $ buildCFG opts halloc path nm
252+
let preserved = Set.fromList . catMaybes $ stringToReg . Text.toLower . Text.pack <$> rwPreservedRegs rw
253+
(C.SomeCFG cfg, elf, relf, addr, cfgs) <- liftIO $ buildCFG opts halloc preserved path nm
225254
addrInt <- if Macaw.segmentBase (Macaw.segoffSegment addr) == 0
226255
then pure . toInteger $ Macaw.segmentOffset (Macaw.segoffSegment addr) + Macaw.segoffOffset addr
227256
else fail $ mconcat ["Address of \"", nm, "\" is not an absolute address"]
@@ -334,6 +363,7 @@ crucible_llvm_verify_x86 bic opts (Some (llvmModule :: LLVMModule x)) path nm gl
334363
buildCFG ::
335364
Options ->
336365
C.HandleAllocator ->
366+
Set (Some Macaw.X86Reg) {- ^ Registers to treat as callee-saved -} ->
337367
String {- ^ Path to ELF file -} ->
338368
String {- ^ Function's symbol in ELF file -} ->
339369
IO ( C.SomeCFG
@@ -350,7 +380,7 @@ buildCFG ::
350380
(EmptyCtx ::> Macaw.ArchRegStruct Macaw.X86_64)
351381
(Macaw.ArchRegStruct Macaw.X86_64))
352382
)
353-
buildCFG opts halloc path nm = do
383+
buildCFG opts halloc preserved path nm = do
354384
printOutLn opts Info $ mconcat ["Finding symbol for \"", nm, "\""]
355385
elf <- getElf path
356386
relf <- getRelevant elf
@@ -360,10 +390,17 @@ buildCFG opts halloc path nm = do
360390
_ -> fail $ mconcat ["Could not find symbol \"", nm, "\""]
361391
printOutLn opts Info $ mconcat ["Found symbol at address ", show addr, ", building CFG"]
362392
let
393+
preservedRegs = Set.union preserved Macaw.x86CalleeSavedRegs
394+
preserveFn :: forall t. Macaw.X86Reg t -> Bool
395+
preserveFn r = Set.member (Some r) preservedRegs
396+
macawCallParams = Macaw.x86_64CallParams { Macaw.preserveReg = preserveFn }
397+
macawArchInfo = (Macaw.x86_64_info preserveFn)
398+
{ Macaw.archCallParams = macawCallParams
399+
}
363400
initialDiscoveryState =
364-
Macaw.emptyDiscoveryState (memory relf) (funSymMap relf) Macaw.x86_64_linux_info
401+
Macaw.emptyDiscoveryState (memory relf) (funSymMap relf) macawArchInfo
402+
-- "inline" any function addresses that we happen to jump to
365403
& Macaw.trustedFunctionEntryPoints .~ Set.empty
366-
let
367404
finalState = Macaw.cfgFromAddrsAndState initialDiscoveryState [addr] []
368405
finfos = finalState ^. Macaw.funInfo
369406
cfgs <- forM finfos $ \(Some finfo) ->
@@ -790,6 +827,7 @@ assertPointsTo env tyenv nameEnv (LLVMPointsTo _ cond tptr tptexpected) = do
790827
ptr <- resolvePtrSetupValue env tyenv tptr
791828
memTy <- liftIO $ typeOfSetupValue cc tyenv nameEnv texpected
792829
storTy <- liftIO $ C.LLVM.toStorableType memTy
830+
793831
actual <- liftIO $ C.LLVM.assertSafe sym =<< C.LLVM.loadRaw sym mem ptr storTy C.LLVM.noAlignment
794832
pure $ LO.matchArg opts sc cc ms MS.PostState actual memTy texpected
795833

src/SAWScript/Interpreter.hs

+21
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ buildTopLevelEnv proxy opts =
434434
, rwProfilingFile = Nothing
435435
, rwLaxArith = False
436436
, rwWhat4HashConsing = False
437+
, rwPreservedRegs = []
437438
}
438439
return (bic, ro0, rw0)
439440

@@ -508,6 +509,16 @@ disable_what4_hash_consing = do
508509
rw <- getTopLevelRW
509510
putTopLevelRW rw { rwWhat4HashConsing = False }
510511

512+
add_x86_preserved_reg :: String -> TopLevel ()
513+
add_x86_preserved_reg r = do
514+
rw <- getTopLevelRW
515+
putTopLevelRW rw { rwPreservedRegs = r:rwPreservedRegs rw }
516+
517+
default_x86_preserved_reg :: TopLevel ()
518+
default_x86_preserved_reg = do
519+
rw <- getTopLevelRW
520+
putTopLevelRW rw { rwPreservedRegs = [] }
521+
511522
include_value :: FilePath -> TopLevel ()
512523
include_value file = do
513524
oldpath <- io $ getCurrentDirectory
@@ -2203,6 +2214,16 @@ primitives = Map.fromList
22032214
, "that can be used as an override when verifying other LLVM functions."
22042215
]
22052216

2217+
, prim "add_x86_preserved_reg" "String -> TopLevel ()"
2218+
(pureVal add_x86_preserved_reg)
2219+
Current
2220+
[ "Treat the given register as callee-saved during x86 verification." ]
2221+
2222+
, prim "default_x86_preserved_reg" "TopLevel ()"
2223+
(pureVal default_x86_preserved_reg)
2224+
Current
2225+
[ "Use the default set of callee-saved registers during x86 verification.." ]
2226+
22062227
, prim "crucible_array"
22072228
"[SetupValue] -> SetupValue"
22082229
(pureVal CIR.anySetupArray)

src/SAWScript/Value.hs

+1
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ data TopLevelRW =
409409
, rwProfilingFile :: Maybe FilePath
410410
, rwLaxArith :: Bool
411411
, rwWhat4HashConsing :: Bool
412+
, rwPreservedRegs :: [String]
412413
}
413414

414415
newtype TopLevel a =

0 commit comments

Comments
 (0)