@@ -18,6 +18,7 @@ Stability : provisional
18
18
{-# Language TypeApplications #-}
19
19
{-# Language GADTs #-}
20
20
{-# Language DataKinds #-}
21
+ {-# Language RankNTypes #-}
21
22
{-# Language ConstraintKinds #-}
22
23
{-# Language GeneralizedNewtypeDeriving #-}
23
24
{-# Language TemplateHaskell #-}
@@ -226,6 +227,50 @@ cryptolUninterpreted env nm sc xs =
226
227
]
227
228
Right t -> liftIO $ scApplyAll sc t xs
228
229
230
+ llvmPointerBlock :: C.LLVM. LLVMPtr sym w -> W4. SymNat sym
231
+ llvmPointerBlock = fst . C.LLVM. llvmPointerView
232
+ llvmPointerOffset :: C.LLVM. LLVMPtr sym w -> W4. SymBV sym w
233
+ llvmPointerOffset = snd . C.LLVM. llvmPointerView
234
+
235
+ -- | Compare pointers that are not valid LLVM pointers. Comparing the offsets
236
+ -- as unsigned bitvectors is not sound, because of overflow (e.g. `base - 1` is
237
+ -- less than `base`, but -1 is not less than 0 when compared as unsigned). It
238
+ -- is safe to allow a small negative offset, because each pointer base is
239
+ -- mapped to an address that is not in the first page (4K), which is never
240
+ -- mapped on X86_64 Linux. Specifically, assume pointer1 = (base1, offset1) and
241
+ -- pointer2 = (base2, offset2), and size1 is the size of the allocation of
242
+ -- base1 and size2 is the size of the allocation of base2. If offset1 is in the
243
+ -- interval [-4096, size1], and offset2 is in the interval [-4096, size2], then
244
+ -- the unsigned comparison between pointer1 and pointer2 is equivalent with the
245
+ -- unsigned comparison between offset1 + 4096 and offset2 + 4096.
246
+ doPtrCmp ::
247
+ (sym -> W4. SymBV sym w -> W4. SymBV sym w -> IO (W4. Pred sym )) ->
248
+ Macaw. PtrOp sym w (C. RegValue sym C. BoolType )
249
+ doPtrCmp f = Macaw. ptrOp $ \ sym mem w xPtr xBits yPtr yBits x y -> do
250
+ let ptr_as_bv_for_cmp ptr = do
251
+ page_size <- W4. bvLit sym (W4. bvWidth $ llvmPointerOffset ptr) $
252
+ BV. mkBV (W4. bvWidth $ llvmPointerOffset ptr) 4096
253
+ ptr_as_bv <- W4. bvAdd sym (llvmPointerOffset ptr) page_size
254
+ is_valid <- Macaw. isValidPtr sym mem w ptr
255
+ is_negative_offset <- W4. bvIsNeg sym (llvmPointerOffset ptr)
256
+ is_not_overflow <- W4. notPred sym =<< W4. bvIsNeg sym ptr_as_bv
257
+ ok <- W4. orPred sym is_valid
258
+ =<< W4. andPred sym is_negative_offset is_not_overflow
259
+ return (ptr_as_bv, ok)
260
+ both_bits <- W4. andPred sym xBits yBits
261
+ both_ptrs <- W4. andPred sym xPtr yPtr
262
+ same_region <- W4. natEq sym (llvmPointerBlock x) (llvmPointerBlock y)
263
+ (x_ptr_as_bv, ok_x) <- ptr_as_bv_for_cmp x
264
+ (y_ptr_as_bv, ok_y) <- ptr_as_bv_for_cmp y
265
+ ok_both_ptrs <- W4. andPred sym both_ptrs
266
+ =<< W4. andPred sym same_region
267
+ =<< W4. andPred sym ok_x ok_y
268
+ res_both_bits <- f sym (llvmPointerOffset x) (llvmPointerOffset y)
269
+ res_both_ptrs <- f sym x_ptr_as_bv y_ptr_as_bv
270
+ undef <- Macaw. mkUndefinedBool sym " ptr_cmp"
271
+ W4. itePred sym both_bits res_both_bits
272
+ =<< W4. itePred sym ok_both_ptrs res_both_ptrs undef
273
+
229
274
-------------------------------------------------------------------------------
230
275
-- ** Entrypoint
231
276
@@ -329,17 +374,25 @@ llvm_verify_x86 (Some (llvmModule :: LLVMModule x)) path nm globsyms checkSat se
329
374
, show $ W4. ppExpr off
330
375
]
331
376
noExtraValidityPred _ _ _ _ = return Nothing
377
+ defaultMacawExtensions_x86_64 = Macaw. macawExtensions
378
+ (Macaw. x86_64MacawEvalFn sfs) mvar
379
+ (mkGlobalMap . Map. singleton 0 $ preState ^. x86GlobalBase)
380
+ funcLookup
381
+ noExtraValidityPred
382
+ sawMacawExtensions = defaultMacawExtensions_x86_64
383
+ { C. extensionExec = \ s0 st -> case s0 of
384
+ Macaw. PtrLt w x y -> doPtrCmp W4. bvUlt st mvar w x y
385
+ Macaw. PtrLeq w x y -> doPtrCmp W4. bvUle st mvar w x y
386
+ _ -> (C. extensionExec defaultMacawExtensions_x86_64) s0 st
387
+ }
332
388
ctx :: C. SimContext (Macaw. MacawSimulatorState Sym ) Sym (Macaw. MacawExt Macaw. X86_64 )
333
389
ctx = C. SimContext
334
390
{ C. _ctxSymInterface = sym
335
391
, C. ctxSolverProof = id
336
392
, C. ctxIntrinsicTypes = C.LLVM. llvmIntrinsicTypes
337
393
, C. simHandleAllocator = halloc
338
394
, C. printHandle = stdout
339
- , C. extensionImpl =
340
- Macaw. macawExtensions (Macaw. x86_64MacawEvalFn sfs) mvar
341
- (mkGlobalMap . Map. singleton 0 $ preState ^. x86GlobalBase)
342
- funcLookup noExtraValidityPred
395
+ , C. extensionImpl = sawMacawExtensions
343
396
, C. _functionBindings = C. FnBindings $ C. insertHandleMap (C. cfgHandle cfg) (C. UseCFG cfg $ C. postdomInfo cfg) C. emptyHandleMap
344
397
, C. _cruciblePersonality = Macaw. MacawSimulatorState
345
398
, C. _profilingMetrics = Map. empty
0 commit comments