@@ -975,6 +975,8 @@ setupMemory globsyms balign = do
975
975
976
976
setArgs env tyenv nameEnv . fmap snd . Map. elems $ ms ^. MS. csArgBindings
977
977
978
+ pushFreshReturnAddress
979
+
978
980
pure env
979
981
980
982
-- | Given an alist of symbol names and sizes (in bytes), allocate space and copy
@@ -1008,8 +1010,7 @@ setupGlobals globsyms = do
1008
1010
mem' <- liftIO $ foldlM writeGlobal mem globs
1009
1011
x86Mem .= mem'
1010
1012
1011
- -- | Allocate memory for the stack, and pushes a fresh pointer as the return
1012
- -- address.
1013
+ -- | Allocate memory for the stack.
1013
1014
allocateStack ::
1014
1015
X86Constraints =>
1015
1016
Integer {- ^ Stack size in bytes -} ->
@@ -1021,16 +1022,31 @@ allocateStack szInt balign = do
1021
1022
mem <- use x86Mem
1022
1023
regs <- use x86Regs
1023
1024
sz <- liftIO $ W4. bvLit sym knownNat $ BV. mkBV knownNat $ szInt + 8
1024
- (base, mem') <- liftIO $ C.LLVM. doMalloc bak C.LLVM. HeapAlloc C.LLVM. Mutable " stack_alloc" mem sz balign
1025
+ (base, finalMem) <- liftIO $ C.LLVM. doMalloc bak C.LLVM. HeapAlloc C.LLVM. Mutable " stack_alloc" mem sz balign
1026
+ ptr <- liftIO $ C.LLVM. doPtrAddOffset bak finalMem base sz
1027
+ x86Mem .= finalMem
1028
+ finalRegs <- setReg Macaw. RSP ptr regs
1029
+ x86Regs .= finalRegs
1030
+
1031
+ -- | Push a fresh pointer as the return address.
1032
+ pushFreshReturnAddress ::
1033
+ X86Constraints =>
1034
+ X86Sim ()
1035
+ pushFreshReturnAddress = do
1036
+ SomeOnlineBackend bak <- use x86Backend
1037
+ sym <- use x86Sym
1038
+ mem <- use x86Mem
1039
+ regs <- use x86Regs
1025
1040
sn <- case W4. userSymbol " stack" of
1026
1041
Left err -> throwX86 $ " Invalid symbol for stack: " <> show err
1027
1042
Right sn -> pure sn
1028
1043
fresh <- liftIO $ C.LLVM. LLVMPointer
1029
1044
<$> W4. natLit sym 0
1030
1045
<*> W4. freshConstant sym sn (W4. BaseBVRepr $ knownNat @ 64 )
1031
- ptr <- liftIO $ C.LLVM. doPtrAddOffset bak mem' base =<< W4. bvLit sym knownNat (BV. mkBV knownNat szInt)
1032
- writeAlign <- integerToAlignment defaultStackBaseAlign
1033
- finalMem <- liftIO $ C.LLVM. doStore bak mem' ptr
1046
+ rsp <- getReg Macaw. RSP regs
1047
+ ptr <- liftIO $ C.LLVM. doPtrAddOffset bak mem rsp =<< W4. bvLit sym knownNat (BV. mkBV knownNat (- 8 ))
1048
+ let writeAlign = C.LLVM. noAlignment
1049
+ finalMem <- liftIO $ C.LLVM. doStore bak mem ptr
1034
1050
(C.LLVM. LLVMPointerRepr $ knownNat @ 64 )
1035
1051
(C.LLVM. bitvectorType 8 ) writeAlign fresh
1036
1052
x86Mem .= finalMem
@@ -1152,36 +1168,57 @@ setArgs ::
1152
1168
Map MS. AllocIndex C.LLVM. Ident {- ^ Associates each AllocIndex with its name -} ->
1153
1169
[MS. SetupValue LLVM ] {- ^ Arguments passed to llvm_execute_func -} ->
1154
1170
X86Sim ()
1155
- setArgs env tyenv nameEnv args
1156
- | length args > length argRegs = throwX86 " More arguments than would fit into general-purpose registers"
1157
- | otherwise = do
1158
- sym <- use x86Sym
1159
- cc <- use x86CrucibleContext
1160
- mem <- use x86Mem
1161
- let
1162
- setRegSetupValue rs (reg, sval) =
1163
- exceptToFail (typeOfSetupValue cc tyenv nameEnv sval) >>= \ case
1164
- ty | C.LLVM. isPointerMemType ty -> do
1165
- val <- C.LLVM. unpackMemValue sym (C.LLVM. LLVMPointerRepr $ knownNat @ 64 )
1166
- =<< resolveSetupVal cc mem env tyenv nameEnv sval
1167
- setReg reg val rs
1168
- C.LLVM. IntType 64 -> do
1171
+ setArgs env tyenv nameEnv args = do
1172
+ SomeOnlineBackend bak <- use x86Backend
1173
+ sym <- use x86Sym
1174
+ cc <- use x86CrucibleContext
1175
+ mem <- use x86Mem
1176
+ let
1177
+ setRegSetupValue rs (reg, sval) =
1178
+ exceptToFail (typeOfSetupValue cc tyenv nameEnv sval) >>= \ case
1179
+ ty | C.LLVM. isPointerMemType ty -> do
1180
+ val <- C.LLVM. unpackMemValue sym (C.LLVM. LLVMPointerRepr $ knownNat @ 64 )
1181
+ =<< resolveSetupVal cc mem env tyenv nameEnv sval
1182
+ setReg reg val rs
1183
+ C.LLVM. IntType 64 -> do
1184
+ val <- C.LLVM. unpackMemValue sym (C.LLVM. LLVMPointerRepr $ knownNat @ 64 )
1185
+ =<< resolveSetupVal cc mem env tyenv nameEnv sval
1186
+ setReg reg val rs
1187
+ C.LLVM. IntType _ -> do
1188
+ C.LLVM. LLVMValInt base off <- resolveSetupVal cc mem env tyenv nameEnv sval
1189
+ case testLeq (incNat $ W4. bvWidth off) (knownNat @ 64 ) of
1190
+ Nothing -> fail " Argument bitvector does not fit in a single general-purpose register"
1191
+ Just LeqProof -> do
1192
+ off' <- W4. bvZext sym (knownNat @ 64 ) off
1169
1193
val <- C.LLVM. unpackMemValue sym (C.LLVM. LLVMPointerRepr $ knownNat @ 64 )
1170
- =<< resolveSetupVal cc mem env tyenv nameEnv sval
1194
+ $ C.LLVM. LLVMValInt base off'
1171
1195
setReg reg val rs
1172
- C.LLVM. IntType _ -> do
1173
- C.LLVM. LLVMValInt base off <- resolveSetupVal cc mem env tyenv nameEnv sval
1174
- case testLeq (incNat $ W4. bvWidth off) (knownNat @ 64 ) of
1175
- Nothing -> fail " Argument bitvector does not fit in a single general-purpose register"
1176
- Just LeqProof -> do
1177
- off' <- W4. bvZext sym (knownNat @ 64 ) off
1178
- val <- C.LLVM. unpackMemValue sym (C.LLVM. LLVMPointerRepr $ knownNat @ 64 )
1179
- $ C.LLVM. LLVMValInt base off'
1180
- setReg reg val rs
1181
- _ -> fail " Argument does not fit into a single general-purpose register"
1182
- regs <- use x86Regs
1183
- newRegs <- liftIO . foldlM setRegSetupValue regs $ zip argRegs args
1184
- x86Regs .= newRegs
1196
+ _ -> fail " Argument does not fit into a single general-purpose register"
1197
+ regs <- use x86Regs
1198
+ newRegs <- liftIO . foldlM setRegSetupValue regs $ zip argRegs args
1199
+ x86Regs .= newRegs
1200
+
1201
+ let stackArgs = reverse $ Prelude. drop (length argRegs) args
1202
+ forM_ stackArgs $ \ sval -> do
1203
+ liftIO $ exceptToFail (typeOfSetupValue cc tyenv nameEnv sval) >>= \ case
1204
+ C.LLVM. PtrType _ -> pure ()
1205
+ C.LLVM. IntType 64 -> pure ()
1206
+ _ -> fail " Stack argument is not a 64 bit integer."
1207
+
1208
+ regs' <- use x86Regs
1209
+ rsp <- getReg Macaw. RSP regs'
1210
+ rsp' <- liftIO $ C.LLVM. doPtrAddOffset bak mem rsp =<< W4. bvLit sym knownNat (BV. mkBV knownNat (- 8 ))
1211
+ newRegs' <- setReg Macaw. RSP rsp' regs'
1212
+ x86Regs .= newRegs'
1213
+
1214
+ val <- liftIO $ C.LLVM. unpackMemValue sym (C.LLVM. LLVMPointerRepr $ knownNat @ 64 )
1215
+ =<< resolveSetupVal cc mem env tyenv nameEnv sval
1216
+
1217
+ mem' <- use x86Mem
1218
+ mem'' <- liftIO $
1219
+ C.LLVM. doStore bak mem' rsp' (C.LLVM. LLVMPointerRepr $ knownNat @ 64 ) (C.LLVM. bitvectorType 8 ) C.LLVM. noAlignment val
1220
+ x86Mem .= mem''
1221
+
1185
1222
where argRegs = [Macaw. RDI , Macaw. RSI , Macaw. RDX , Macaw. RCX , Macaw. R8 , Macaw. R9 ]
1186
1223
1187
1224
--------------------------------------------------------------------------------
0 commit comments