{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE ImplicitParams #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ViewPatterns #-}
module Lang.Crucible.LLVM.Intrinsics.Common
( LLVMOverride(..)
, SomeLLVMOverride(..)
, MakeOverride(..)
, llvmSizeT
, llvmSSizeT
, OverrideTemplate(..)
, callStackFromMemVar'
, basic_llvm_override
, polymorphic1_llvm_override
, polymorphic1_vec_llvm_override
, build_llvm_override
, register_llvm_override
, register_1arg_polymorphic_override
, register_1arg_vec_polymorphic_override
, do_register_llvm_override
, alloc_and_register_override
) where
import qualified Text.LLVM.AST as L
import Control.Monad (when)
import Control.Monad.IO.Class (liftIO)
import Control.Lens
import qualified Data.List as List
import qualified Data.Text as Text
import Numeric (readDec)
import qualified System.Info as Info
import qualified ABI.Itanium as ABI
import qualified Data.Parameterized.Context as Ctx
import Data.Parameterized.Some (Some(..))
import Lang.Crucible.Backend
import Lang.Crucible.CFG.Common (GlobalVar)
import Lang.Crucible.Simulator.ExecutionTree (FnState(UseOverride))
import Lang.Crucible.Panic (panic)
import Lang.Crucible.Simulator.OverrideSim
import Lang.Crucible.Utils.MonadVerbosity (getLogFunction)
import Lang.Crucible.Simulator.RegMap
import Lang.Crucible.Types
import What4.FunctionName
import Lang.Crucible.LLVM.Extension
import Lang.Crucible.LLVM.Eval (callStackFromMemVar)
import Lang.Crucible.LLVM.Functions (registerFunPtr, bindLLVMFunc)
import Lang.Crucible.LLVM.MemModel
import Lang.Crucible.LLVM.MemModel.CallStack (CallStack)
import qualified Lang.Crucible.LLVM.Intrinsics.Cast as Cast
import qualified Lang.Crucible.LLVM.Intrinsics.Match as Match
import Lang.Crucible.LLVM.Translation.Monad
import Lang.Crucible.LLVM.Translation.Types
data LLVMOverride p sym ext args ret =
LLVMOverride
{ forall p sym ext (args :: Ctx CrucibleType) (ret :: CrucibleType).
LLVMOverride p sym ext args ret -> Declare
llvmOverride_declare :: L.Declare
, forall p sym ext (args :: Ctx CrucibleType) (ret :: CrucibleType).
LLVMOverride p sym ext args ret -> CtxRepr args
llvmOverride_args :: CtxRepr args
, forall p sym ext (args :: Ctx CrucibleType) (ret :: CrucibleType).
LLVMOverride p sym ext args ret -> TypeRepr ret
llvmOverride_ret :: TypeRepr ret
, forall p sym ext (args :: Ctx CrucibleType) (ret :: CrucibleType).
LLVMOverride p sym ext args ret
-> IsSymInterface sym =>
GlobalVar Mem
-> Assignment (RegEntry sym) args
-> forall rtp (args' :: Ctx CrucibleType) (ret' :: CrucibleType).
OverrideSim p sym ext rtp args' ret' (RegValue sym ret)
llvmOverride_def ::
IsSymInterface sym =>
GlobalVar Mem ->
Ctx.Assignment (RegEntry sym) args ->
forall rtp args' ret'.
OverrideSim p sym ext rtp args' ret' (RegValue sym ret)
}
data SomeLLVMOverride p sym ext =
forall args ret. SomeLLVMOverride (LLVMOverride p sym ext args ret)
llvmSizeT :: HasPtrWidth wptr => L.Type
llvmSizeT :: forall (wptr :: Natural). HasPtrWidth wptr => Type
llvmSizeT = PrimType -> Type
forall ident. PrimType -> Type' ident
L.PrimType (PrimType -> Type) -> PrimType -> Type
forall a b. (a -> b) -> a -> b
$ Word32 -> PrimType
L.Integer (Word32 -> PrimType) -> Word32 -> PrimType
forall a b. (a -> b) -> a -> b
$ Natural -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Natural -> Word32) -> Natural -> Word32
forall a b. (a -> b) -> a -> b
$ NatRepr wptr -> Natural
forall (n :: Natural). NatRepr n -> Natural
natValue (NatRepr wptr -> Natural) -> NatRepr wptr -> Natural
forall a b. (a -> b) -> a -> b
$ NatRepr wptr
forall (w :: Natural) (w' :: Natural).
(HasPtrWidth w, w ~ w') =>
NatRepr w'
PtrWidth
llvmSSizeT :: HasPtrWidth wptr => L.Type
llvmSSizeT :: forall (wptr :: Natural). HasPtrWidth wptr => Type
llvmSSizeT = PrimType -> Type
forall ident. PrimType -> Type' ident
L.PrimType (PrimType -> Type) -> PrimType -> Type
forall a b. (a -> b) -> a -> b
$ Word32 -> PrimType
L.Integer (Word32 -> PrimType) -> Word32 -> PrimType
forall a b. (a -> b) -> a -> b
$ Natural -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Natural -> Word32) -> Natural -> Word32
forall a b. (a -> b) -> a -> b
$ NatRepr wptr -> Natural
forall (n :: Natural). NatRepr n -> Natural
natValue (NatRepr wptr -> Natural) -> NatRepr wptr -> Natural
forall a b. (a -> b) -> a -> b
$ NatRepr wptr
forall (w :: Natural) (w' :: Natural).
(HasPtrWidth w, w ~ w') =>
NatRepr w'
PtrWidth
newtype MakeOverride p sym ext arch =
MakeOverride
{ forall p sym ext (arch :: LLVMArch).
MakeOverride p sym ext arch
-> Declare
-> Maybe DecodedName
-> LLVMContext arch
-> Maybe (SomeLLVMOverride p sym ext)
runMakeOverride ::
L.Declare ->
Maybe ABI.DecodedName ->
LLVMContext arch ->
Maybe (SomeLLVMOverride p sym ext)
}
data OverrideTemplate p sym ext arch =
OverrideTemplate
{
forall p sym ext (arch :: LLVMArch).
OverrideTemplate p sym ext arch -> TemplateMatcher
overrideTemplateMatcher :: Match.TemplateMatcher
, forall p sym ext (arch :: LLVMArch).
OverrideTemplate p sym ext arch -> MakeOverride p sym ext arch
overrideTemplateAction :: MakeOverride p sym ext arch
}
callStackFromMemVar' ::
GlobalVar Mem ->
OverrideSim p sym ext r args ret CallStack
callStackFromMemVar' :: forall p sym ext r (args :: Ctx CrucibleType)
(ret :: CrucibleType).
GlobalVar Mem -> OverrideSim p sym ext r args ret CallStack
callStackFromMemVar' GlobalVar Mem
mvar = Getting
CallStack
(SimState p sym ext r (OverrideLang ret) ('Just args))
CallStack
-> OverrideSim p sym ext r args ret CallStack
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
use ((SimState p sym ext r (OverrideLang ret) ('Just args) -> CallStack)
-> Getting
CallStack
(SimState p sym ext r (OverrideLang ret) ('Just args))
CallStack
forall (p :: Type -> Type -> Type) (f :: Type -> Type) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to ((SimState p sym ext r (OverrideLang ret) ('Just args)
-> GlobalVar Mem -> CallStack)
-> GlobalVar Mem
-> SimState p sym ext r (OverrideLang ret) ('Just args)
-> CallStack
forall a b c. (a -> b -> c) -> b -> a -> c
flip SimState p sym ext r (OverrideLang ret) ('Just args)
-> GlobalVar Mem -> CallStack
forall p sym ext rtp lang (args :: Maybe (Ctx CrucibleType)).
SimState p sym ext rtp lang args -> GlobalVar Mem -> CallStack
callStackFromMemVar GlobalVar Mem
mvar))
build_llvm_override ::
HasLLVMAnn sym =>
FunctionName ->
CtxRepr args ->
TypeRepr ret ->
CtxRepr args' ->
TypeRepr ret' ->
(forall rtp' l' a'. IsSymInterface sym =>
Ctx.Assignment (RegEntry sym) args ->
OverrideSim p sym ext rtp' l' a' (RegValue sym ret)) ->
OverrideSim p sym ext rtp l a (Override p sym ext args' ret')
build_llvm_override :: forall sym (args :: Ctx CrucibleType) (ret :: CrucibleType)
(args' :: Ctx CrucibleType) (ret' :: CrucibleType) p ext rtp
(l :: Ctx CrucibleType) (a :: CrucibleType).
HasLLVMAnn sym =>
FunctionName
-> CtxRepr args
-> TypeRepr ret
-> CtxRepr args'
-> TypeRepr ret'
-> (forall rtp' (l' :: Ctx CrucibleType) (a' :: CrucibleType).
IsSymInterface sym =>
Assignment (RegEntry sym) args
-> OverrideSim p sym ext rtp' l' a' (RegValue sym ret))
-> OverrideSim p sym ext rtp l a (Override p sym ext args' ret')
build_llvm_override FunctionName
fnm CtxRepr args
args TypeRepr ret
ret CtxRepr args'
args' TypeRepr ret'
ret' forall rtp' (l' :: Ctx CrucibleType) (a' :: CrucibleType).
IsSymInterface sym =>
Assignment (RegEntry sym) args
-> OverrideSim p sym ext rtp' l' a' (RegValue sym ret)
llvmOverride =
(forall bak.
IsSymBackend sym bak =>
bak
-> OverrideSim p sym ext rtp l a (Override p sym ext args' ret'))
-> OverrideSim p sym ext rtp l a (Override p sym ext args' ret')
forall sym p ext rtp (args :: Ctx CrucibleType)
(ret :: CrucibleType) a.
(forall bak.
IsSymBackend sym bak =>
bak -> OverrideSim p sym ext rtp args ret a)
-> OverrideSim p sym ext rtp args ret a
ovrWithBackend ((forall bak.
IsSymBackend sym bak =>
bak
-> OverrideSim p sym ext rtp l a (Override p sym ext args' ret'))
-> OverrideSim p sym ext rtp l a (Override p sym ext args' ret'))
-> (forall bak.
IsSymBackend sym bak =>
bak
-> OverrideSim p sym ext rtp l a (Override p sym ext args' ret'))
-> OverrideSim p sym ext rtp l a (Override p sym ext args' ret')
forall a b. (a -> b) -> a -> b
$ \bak
bak ->
do ArgCast p sym ext args' args
fargs <-
case FunctionName
-> bak
-> CtxRepr args
-> CtxRepr args'
-> Either ValCastError (ArgCast p sym ext args' args)
forall p sym ext bak (args :: Ctx CrucibleType)
(args' :: Ctx CrucibleType).
IsSymBackend sym bak =>
FunctionName
-> bak
-> CtxRepr args'
-> CtxRepr args
-> Either ValCastError (ArgCast p sym ext args args')
Cast.castLLVMArgs FunctionName
fnm bak
bak CtxRepr args
args CtxRepr args'
args' of
Left ValCastError
err ->
String
-> [String]
-> OverrideSim p sym ext rtp l a (ArgCast p sym ext args' args)
forall a. HasCallStack => String -> [String] -> a
panic String
"Intrinsics.build_llvm_override"
(ValCastError -> [String]
Cast.printValCastError ValCastError
err [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++
[ String
"in function: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Text -> String
Text.unpack (FunctionName -> Text
functionName FunctionName
fnm) ])
Right ArgCast p sym ext args' args
f -> ArgCast p sym ext args' args
-> OverrideSim p sym ext rtp l a (ArgCast p sym ext args' args)
forall a. a -> OverrideSim p sym ext rtp l a a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ArgCast p sym ext args' args
f
ValCast p sym ext ret ret'
fret <-
case FunctionName
-> bak
-> TypeRepr ret
-> TypeRepr ret'
-> Either ValCastError (ValCast p sym ext ret ret')
forall sym bak (ret :: CrucibleType) (ret' :: CrucibleType) p ext.
IsSymBackend sym bak =>
FunctionName
-> bak
-> TypeRepr ret
-> TypeRepr ret'
-> Either ValCastError (ValCast p sym ext ret ret')
Cast.castLLVMRet FunctionName
fnm bak
bak TypeRepr ret
ret TypeRepr ret'
ret' of
Left ValCastError
err ->
String
-> [String]
-> OverrideSim p sym ext rtp l a (ValCast p sym ext ret ret')
forall a. HasCallStack => String -> [String] -> a
panic String
"Intrinsics.build_llvm_override"
(ValCastError -> [String]
Cast.printValCastError ValCastError
err [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++
[ String
"in function: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Text -> String
Text.unpack (FunctionName -> Text
functionName FunctionName
fnm) ])
Right ValCast p sym ext ret ret'
f -> ValCast p sym ext ret ret'
-> OverrideSim p sym ext rtp l a (ValCast p sym ext ret ret')
forall a. a -> OverrideSim p sym ext rtp l a a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ValCast p sym ext ret ret'
f
Override p sym ext args' ret'
-> OverrideSim p sym ext rtp l a (Override p sym ext args' ret')
forall a. a -> OverrideSim p sym ext rtp l a a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Override p sym ext args' ret'
-> OverrideSim p sym ext rtp l a (Override p sym ext args' ret'))
-> Override p sym ext args' ret'
-> OverrideSim p sym ext rtp l a (Override p sym ext args' ret')
forall a b. (a -> b) -> a -> b
$ FunctionName
-> TypeRepr ret'
-> (forall {r}.
OverrideSim p sym ext r args' ret' (RegValue sym ret'))
-> Override p sym ext args' ret'
forall (ret :: CrucibleType) p sym ext (args :: Ctx CrucibleType).
FunctionName
-> TypeRepr ret
-> (forall r. OverrideSim p sym ext r args ret (RegValue sym ret))
-> Override p sym ext args ret
mkOverride' FunctionName
fnm TypeRepr ret'
ret' ((forall {r}.
OverrideSim p sym ext r args' ret' (RegValue sym ret'))
-> Override p sym ext args' ret')
-> (forall {r}.
OverrideSim p sym ext r args' ret' (RegValue sym ret'))
-> Override p sym ext args' ret'
forall a b. (a -> b) -> a -> b
$
do RegMap Assignment (RegEntry sym) args'
xs <- OverrideSim p sym ext r args' ret' (RegMap sym args')
forall p sym ext rtp (args :: Ctx CrucibleType)
(ret :: CrucibleType).
OverrideSim p sym ext rtp args ret (RegMap sym args)
getOverrideArgs
ValCast p sym ext ret ret'
-> forall rtp (l :: Ctx CrucibleType) (a :: CrucibleType).
RegValue sym ret
-> OverrideSim p sym ext rtp l a (RegValue sym ret')
forall p sym ext (tp :: CrucibleType) (tp' :: CrucibleType).
ValCast p sym ext tp tp'
-> forall rtp (l :: Ctx CrucibleType) (a :: CrucibleType).
RegValue sym tp -> OverrideSim p sym ext rtp l a (RegValue sym tp')
Cast.applyValCast ValCast p sym ext ret ret'
fret (RegValue sym ret
-> OverrideSim p sym ext r args' ret' (RegValue sym ret'))
-> OverrideSim p sym ext r args' ret' (RegValue sym ret)
-> OverrideSim p sym ext r args' ret' (RegValue sym ret')
forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< Assignment (RegEntry sym) args
-> OverrideSim p sym ext r args' ret' (RegValue sym ret)
forall rtp' (l' :: Ctx CrucibleType) (a' :: CrucibleType).
IsSymInterface sym =>
Assignment (RegEntry sym) args
-> OverrideSim p sym ext rtp' l' a' (RegValue sym ret)
llvmOverride (Assignment (RegEntry sym) args
-> OverrideSim p sym ext r args' ret' (RegValue sym ret))
-> OverrideSim
p sym ext r args' ret' (Assignment (RegEntry sym) args)
-> OverrideSim p sym ext r args' ret' (RegValue sym ret)
forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< ArgCast p sym ext args' args
-> forall rtp (l :: Ctx CrucibleType) (a :: CrucibleType).
Assignment (RegEntry sym) args'
-> OverrideSim p sym ext rtp l a (Assignment (RegEntry sym) args)
forall p sym ext (args :: Ctx CrucibleType)
(args' :: Ctx CrucibleType).
ArgCast p sym ext args args'
-> forall rtp (l :: Ctx CrucibleType) (a :: CrucibleType).
Assignment (RegEntry sym) args
-> OverrideSim p sym ext rtp l a (Assignment (RegEntry sym) args')
Cast.applyArgCast ArgCast p sym ext args' args
fargs Assignment (RegEntry sym) args'
xs
polymorphic1_llvm_override :: forall p sym ext arch wptr.
(IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr) =>
String ->
(forall w. (1 <= w) => NatRepr w -> SomeLLVMOverride p sym ext) ->
OverrideTemplate p sym ext arch
polymorphic1_llvm_override :: forall p sym ext (arch :: LLVMArch) (wptr :: Natural).
(IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr) =>
String
-> (forall (w :: Natural).
(1 <= w) =>
NatRepr w -> SomeLLVMOverride p sym ext)
-> OverrideTemplate p sym ext arch
polymorphic1_llvm_override String
prefix forall (w :: Natural).
(1 <= w) =>
NatRepr w -> SomeLLVMOverride p sym ext
fn =
TemplateMatcher
-> MakeOverride p sym ext arch -> OverrideTemplate p sym ext arch
forall p sym ext (arch :: LLVMArch).
TemplateMatcher
-> MakeOverride p sym ext arch -> OverrideTemplate p sym ext arch
OverrideTemplate (String -> TemplateMatcher
Match.PrefixMatch String
prefix) (String
-> (forall (w :: Natural).
(1 <= w) =>
NatRepr w -> SomeLLVMOverride p sym ext)
-> MakeOverride p sym ext arch
forall p sym ext (arch :: LLVMArch) (wptr :: Natural).
(IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr) =>
String
-> (forall (w :: Natural).
(1 <= w) =>
NatRepr w -> SomeLLVMOverride p sym ext)
-> MakeOverride p sym ext arch
register_1arg_polymorphic_override String
prefix NatRepr w -> SomeLLVMOverride p sym ext
forall (w :: Natural).
(1 <= w) =>
NatRepr w -> SomeLLVMOverride p sym ext
fn)
polymorphic1_vec_llvm_override :: forall p sym ext arch wptr.
(IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr) =>
String ->
(forall vecSz intSz.
(1 <= intSz) =>
NatRepr vecSz ->
NatRepr intSz ->
SomeLLVMOverride p sym ext) ->
OverrideTemplate p sym ext arch
polymorphic1_vec_llvm_override :: forall p sym ext (arch :: LLVMArch) (wptr :: Natural).
(IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr) =>
String
-> (forall (vecSz :: Natural) (intSz :: Natural).
(1 <= intSz) =>
NatRepr vecSz -> NatRepr intSz -> SomeLLVMOverride p sym ext)
-> OverrideTemplate p sym ext arch
polymorphic1_vec_llvm_override String
prefix forall (vecSz :: Natural) (intSz :: Natural).
(1 <= intSz) =>
NatRepr vecSz -> NatRepr intSz -> SomeLLVMOverride p sym ext
fn =
TemplateMatcher
-> MakeOverride p sym ext arch -> OverrideTemplate p sym ext arch
forall p sym ext (arch :: LLVMArch).
TemplateMatcher
-> MakeOverride p sym ext arch -> OverrideTemplate p sym ext arch
OverrideTemplate (String -> TemplateMatcher
Match.PrefixMatch String
prefix) (String
-> (forall (vecSz :: Natural) (intSz :: Natural).
(1 <= intSz) =>
NatRepr vecSz -> NatRepr intSz -> SomeLLVMOverride p sym ext)
-> MakeOverride p sym ext arch
forall p sym ext (arch :: LLVMArch) (wptr :: Natural).
(IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr) =>
String
-> (forall (vecSz :: Natural) (intSz :: Natural).
(1 <= intSz) =>
NatRepr vecSz -> NatRepr intSz -> SomeLLVMOverride p sym ext)
-> MakeOverride p sym ext arch
register_1arg_vec_polymorphic_override String
prefix NatRepr vecSz -> NatRepr intSz -> SomeLLVMOverride p sym ext
forall (vecSz :: Natural) (intSz :: Natural).
(1 <= intSz) =>
NatRepr vecSz -> NatRepr intSz -> SomeLLVMOverride p sym ext
fn)
register_1arg_polymorphic_override :: forall p sym ext arch wptr.
(IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr) =>
String ->
(forall w. (1 <= w) => NatRepr w -> SomeLLVMOverride p sym ext) ->
MakeOverride p sym ext arch
register_1arg_polymorphic_override :: forall p sym ext (arch :: LLVMArch) (wptr :: Natural).
(IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr) =>
String
-> (forall (w :: Natural).
(1 <= w) =>
NatRepr w -> SomeLLVMOverride p sym ext)
-> MakeOverride p sym ext arch
register_1arg_polymorphic_override String
prefix forall (w :: Natural).
(1 <= w) =>
NatRepr w -> SomeLLVMOverride p sym ext
overrideFn =
(Declare
-> Maybe DecodedName
-> LLVMContext arch
-> Maybe (SomeLLVMOverride p sym ext))
-> MakeOverride p sym ext arch
forall p sym ext (arch :: LLVMArch).
(Declare
-> Maybe DecodedName
-> LLVMContext arch
-> Maybe (SomeLLVMOverride p sym ext))
-> MakeOverride p sym ext arch
MakeOverride ((Declare
-> Maybe DecodedName
-> LLVMContext arch
-> Maybe (SomeLLVMOverride p sym ext))
-> MakeOverride p sym ext arch)
-> (Declare
-> Maybe DecodedName
-> LLVMContext arch
-> Maybe (SomeLLVMOverride p sym ext))
-> MakeOverride p sym ext arch
forall a b. (a -> b) -> a -> b
$ \(L.Declare{ decName :: Declare -> Symbol
L.decName = L.Symbol String
nm }) Maybe DecodedName
_ LLVMContext arch
_ ->
case String -> String -> Maybe String
forall a. Eq a => [a] -> [a] -> Maybe [a]
List.stripPrefix String
prefix String
nm of
Just (Char
'.':Char
'i': (ReadS Natural
forall a. (Eq a, Num a) => ReadS a
readDec -> (Natural
sz,[]):[(Natural, String)]
_))
| Some NatRepr x
w <- Natural -> Some NatRepr
mkNatRepr Natural
sz
, Just LeqProof 1 x
LeqProof <- NatRepr x -> Maybe (LeqProof 1 x)
forall (n :: Natural). NatRepr n -> Maybe (LeqProof 1 n)
isPosNat NatRepr x
w
-> SomeLLVMOverride p sym ext -> Maybe (SomeLLVMOverride p sym ext)
forall a. a -> Maybe a
Just (NatRepr x -> SomeLLVMOverride p sym ext
forall (w :: Natural).
(1 <= w) =>
NatRepr w -> SomeLLVMOverride p sym ext
overrideFn NatRepr x
w)
Maybe String
_ -> Maybe (SomeLLVMOverride p sym ext)
forall a. Maybe a
Nothing
register_1arg_vec_polymorphic_override :: forall p sym ext arch wptr.
(IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr) =>
String ->
(forall vecSz intSz.
(1 <= intSz) =>
NatRepr vecSz ->
NatRepr intSz ->
SomeLLVMOverride p sym ext) ->
MakeOverride p sym ext arch
register_1arg_vec_polymorphic_override :: forall p sym ext (arch :: LLVMArch) (wptr :: Natural).
(IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr) =>
String
-> (forall (vecSz :: Natural) (intSz :: Natural).
(1 <= intSz) =>
NatRepr vecSz -> NatRepr intSz -> SomeLLVMOverride p sym ext)
-> MakeOverride p sym ext arch
register_1arg_vec_polymorphic_override String
prefix forall (vecSz :: Natural) (intSz :: Natural).
(1 <= intSz) =>
NatRepr vecSz -> NatRepr intSz -> SomeLLVMOverride p sym ext
overrideFn =
(Declare
-> Maybe DecodedName
-> LLVMContext arch
-> Maybe (SomeLLVMOverride p sym ext))
-> MakeOverride p sym ext arch
forall p sym ext (arch :: LLVMArch).
(Declare
-> Maybe DecodedName
-> LLVMContext arch
-> Maybe (SomeLLVMOverride p sym ext))
-> MakeOverride p sym ext arch
MakeOverride ((Declare
-> Maybe DecodedName
-> LLVMContext arch
-> Maybe (SomeLLVMOverride p sym ext))
-> MakeOverride p sym ext arch)
-> (Declare
-> Maybe DecodedName
-> LLVMContext arch
-> Maybe (SomeLLVMOverride p sym ext))
-> MakeOverride p sym ext arch
forall a b. (a -> b) -> a -> b
$ \(L.Declare{ decName :: Declare -> Symbol
L.decName = L.Symbol String
nm }) Maybe DecodedName
_ LLVMContext arch
_ ->
case String -> String -> Maybe String
forall a. Eq a => [a] -> [a] -> Maybe [a]
List.stripPrefix String
prefix String
nm of
Just (Char
'.':Char
'v':String
suffix1)
| (String
vecSzStr, Char
'i':String
intSzStr) <- (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'i') String
suffix1
, (Natural
vecSzNat, []):[(Natural, String)]
_ <- ReadS Natural
forall a. (Eq a, Num a) => ReadS a
readDec String
vecSzStr
, (Natural
intSzNat, []):[(Natural, String)]
_ <- ReadS Natural
forall a. (Eq a, Num a) => ReadS a
readDec String
intSzStr
, Some NatRepr x
vecSzRepr <- Natural -> Some NatRepr
mkNatRepr Natural
vecSzNat
, Some NatRepr x
intSzRepr <- Natural -> Some NatRepr
mkNatRepr Natural
intSzNat
, Just LeqProof 1 x
LeqProof <- NatRepr x -> Maybe (LeqProof 1 x)
forall (n :: Natural). NatRepr n -> Maybe (LeqProof 1 n)
isPosNat NatRepr x
intSzRepr
-> SomeLLVMOverride p sym ext -> Maybe (SomeLLVMOverride p sym ext)
forall a. a -> Maybe a
Just (NatRepr x -> NatRepr x -> SomeLLVMOverride p sym ext
forall (vecSz :: Natural) (intSz :: Natural).
(1 <= intSz) =>
NatRepr vecSz -> NatRepr intSz -> SomeLLVMOverride p sym ext
overrideFn NatRepr x
vecSzRepr NatRepr x
intSzRepr)
Maybe String
_ -> Maybe (SomeLLVMOverride p sym ext)
forall a. Maybe a
Nothing
basic_llvm_override :: forall p args ret sym ext arch wptr.
(IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr) =>
LLVMOverride p sym ext args ret ->
OverrideTemplate p sym ext arch
basic_llvm_override :: forall p (args :: Ctx CrucibleType) (ret :: CrucibleType) sym ext
(arch :: LLVMArch) (wptr :: Natural).
(IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr) =>
LLVMOverride p sym ext args ret -> OverrideTemplate p sym ext arch
basic_llvm_override LLVMOverride p sym ext args ret
ovr = TemplateMatcher
-> MakeOverride p sym ext arch -> OverrideTemplate p sym ext arch
forall p sym ext (arch :: LLVMArch).
TemplateMatcher
-> MakeOverride p sym ext arch -> OverrideTemplate p sym ext arch
OverrideTemplate TemplateMatcher
matcher MakeOverride p sym ext arch
regOvr
where
ovrDecl :: Declare
ovrDecl = LLVMOverride p sym ext args ret -> Declare
forall p sym ext (args :: Ctx CrucibleType) (ret :: CrucibleType).
LLVMOverride p sym ext args ret -> Declare
llvmOverride_declare LLVMOverride p sym ext args ret
ovr
L.Symbol String
ovrNm = Declare -> Symbol
L.decName Declare
ovrDecl
isDarwin :: Bool
isDarwin = String
Info.os String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"darwin"
matcher :: Match.TemplateMatcher
matcher :: TemplateMatcher
matcher | Bool
isDarwin = String -> TemplateMatcher
Match.DarwinAliasMatch String
ovrNm
| Bool
otherwise = String -> TemplateMatcher
Match.ExactMatch String
ovrNm
regOvr :: MakeOverride p sym ext arch
regOvr :: MakeOverride p sym ext arch
regOvr = do
(Declare
-> Maybe DecodedName
-> LLVMContext arch
-> Maybe (SomeLLVMOverride p sym ext))
-> MakeOverride p sym ext arch
forall p sym ext (arch :: LLVMArch).
(Declare
-> Maybe DecodedName
-> LLVMContext arch
-> Maybe (SomeLLVMOverride p sym ext))
-> MakeOverride p sym ext arch
MakeOverride ((Declare
-> Maybe DecodedName
-> LLVMContext arch
-> Maybe (SomeLLVMOverride p sym ext))
-> MakeOverride p sym ext arch)
-> (Declare
-> Maybe DecodedName
-> LLVMContext arch
-> Maybe (SomeLLVMOverride p sym ext))
-> MakeOverride p sym ext arch
forall a b. (a -> b) -> a -> b
$ \Declare
requestedDecl Maybe DecodedName
_ LLVMContext arch
_ -> do
let L.Symbol String
requestedNm = Declare -> Symbol
L.decName Declare
requestedDecl
let ovr' :: LLVMOverride p sym ext args ret
ovr' | Bool
isDarwin
, String
ovrNm String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String -> String
Match.stripDarwinAliases String
requestedNm
= LLVMOverride p sym ext args ret
ovr { llvmOverride_declare =
ovrDecl { L.decName = L.Symbol requestedNm }}
| Bool
otherwise
= LLVMOverride p sym ext args ret
ovr
SomeLLVMOverride p sym ext -> Maybe (SomeLLVMOverride p sym ext)
forall a. a -> Maybe a
Just (LLVMOverride p sym ext args ret -> SomeLLVMOverride p sym ext
forall p sym ext (args :: Ctx CrucibleType) (ret :: CrucibleType).
LLVMOverride p sym ext args ret -> SomeLLVMOverride p sym ext
SomeLLVMOverride LLVMOverride p sym ext args ret
ovr')
isMatchingDeclaration ::
L.Declare ->
L.Declare ->
Bool
isMatchingDeclaration :: Declare -> Declare -> Bool
isMatchingDeclaration Declare
requested Declare
provided = [Bool] -> Bool
forall (t :: Type -> Type). Foldable t => t Bool -> Bool
and
[ Declare -> Symbol
L.decName Declare
requested Symbol -> Symbol -> Bool
forall a. Eq a => a -> a -> Bool
== Declare -> Symbol
L.decName Declare
provided
, [Type] -> [Type] -> Bool
matchingArgList (Declare -> [Type]
L.decArgs Declare
requested) (Declare -> [Type]
L.decArgs Declare
provided)
, Declare -> Type
L.decRetType Declare
requested Type -> Type -> Bool
forall ident. Eq ident => Type' ident -> Type' ident -> Bool
`L.eqTypeModuloOpaquePtrs` Declare -> Type
L.decRetType Declare
provided
]
where
matchingArgList :: [Type] -> [Type] -> Bool
matchingArgList [] [] = Bool
True
matchingArgList [] [Type]
_ = Declare -> Bool
L.decVarArgs Declare
requested
matchingArgList [Type]
_ [] = Declare -> Bool
L.decVarArgs Declare
provided
matchingArgList (Type
x:[Type]
xs) (Type
y:[Type]
ys) = Type
x Type -> Type -> Bool
forall ident. Eq ident => Type' ident -> Type' ident -> Bool
`L.eqTypeModuloOpaquePtrs` Type
y Bool -> Bool -> Bool
&& [Type] -> [Type] -> Bool
matchingArgList [Type]
xs [Type]
ys
register_llvm_override :: forall p args ret sym ext arch wptr rtp l a.
(IsSymInterface sym, HasPtrWidth wptr, HasLLVMAnn sym) =>
LLVMOverride p sym ext args ret ->
L.Declare ->
LLVMContext arch ->
OverrideSim p sym ext rtp l a ()
register_llvm_override :: forall p (args :: Ctx CrucibleType) (ret :: CrucibleType) sym ext
(arch :: LLVMArch) (wptr :: Natural) rtp (l :: Ctx CrucibleType)
(a :: CrucibleType).
(IsSymInterface sym, HasPtrWidth wptr, HasLLVMAnn sym) =>
LLVMOverride p sym ext args ret
-> Declare -> LLVMContext arch -> OverrideSim p sym ext rtp l a ()
register_llvm_override LLVMOverride p sym ext args ret
llvmOverride Declare
requestedDecl LLVMContext arch
llvmctx = do
let decl :: Declare
decl = LLVMOverride p sym ext args ret -> Declare
forall p sym ext (args :: Ctx CrucibleType) (ret :: CrucibleType).
LLVMOverride p sym ext args ret -> Declare
llvmOverride_declare LLVMOverride p sym ext args ret
llvmOverride
if Bool -> Bool
not (Declare -> Declare -> Bool
isMatchingDeclaration Declare
requestedDecl Declare
decl) then
do Bool
-> OverrideSim p sym ext rtp l a ()
-> OverrideSim p sym ext rtp l a ()
forall (f :: Type -> Type). Applicative f => Bool -> f () -> f ()
when (Declare -> Symbol
L.decName Declare
requestedDecl Symbol -> Symbol -> Bool
forall a. Eq a => a -> a -> Bool
== Declare -> Symbol
L.decName Declare
decl) (OverrideSim p sym ext rtp l a ()
-> OverrideSim p sym ext rtp l a ())
-> OverrideSim p sym ext rtp l a ()
-> OverrideSim p sym ext rtp l a ()
forall a b. (a -> b) -> a -> b
$
do Int -> String -> IO ()
logFn <- OverrideSim p sym ext rtp l a (Int -> String -> IO ())
forall (m :: Type -> Type).
MonadVerbosity m =>
m (Int -> String -> IO ())
getLogFunction
IO () -> OverrideSim p sym ext rtp l a ()
forall a. IO a -> OverrideSim p sym ext rtp l a a
forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
liftIO (IO () -> OverrideSim p sym ext rtp l a ())
-> IO () -> OverrideSim p sym ext rtp l a ()
forall a b. (a -> b) -> a -> b
$ Int -> String -> IO ()
logFn Int
3 (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines
[ String
"Mismatched declaration signatures"
, String
" *** requested: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Declare -> String
forall a. Show a => a -> String
show Declare
requestedDecl
, String
" *** found: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Declare -> String
forall a. Show a => a -> String
show Declare
decl
, String
""
]
else LLVMContext arch
-> LLVMOverride p sym ext args ret
-> OverrideSim p sym ext rtp l a ()
forall p (args :: Ctx CrucibleType) (ret :: CrucibleType) sym ext
(arch :: LLVMArch) (wptr :: Natural) (l :: Ctx CrucibleType)
(a :: CrucibleType) rtp.
(IsSymInterface sym, HasPtrWidth wptr, HasLLVMAnn sym) =>
LLVMContext arch
-> LLVMOverride p sym ext args ret
-> OverrideSim p sym ext rtp l a ()
do_register_llvm_override LLVMContext arch
llvmctx LLVMOverride p sym ext args ret
llvmOverride
do_register_llvm_override :: forall p args ret sym ext arch wptr l a rtp.
(IsSymInterface sym, HasPtrWidth wptr, HasLLVMAnn sym) =>
LLVMContext arch ->
LLVMOverride p sym ext args ret ->
OverrideSim p sym ext rtp l a ()
do_register_llvm_override :: forall p (args :: Ctx CrucibleType) (ret :: CrucibleType) sym ext
(arch :: LLVMArch) (wptr :: Natural) (l :: Ctx CrucibleType)
(a :: CrucibleType) rtp.
(IsSymInterface sym, HasPtrWidth wptr, HasLLVMAnn sym) =>
LLVMContext arch
-> LLVMOverride p sym ext args ret
-> OverrideSim p sym ext rtp l a ()
do_register_llvm_override LLVMContext arch
llvmctx LLVMOverride p sym ext args ret
llvmOverride = do
let decl :: Declare
decl = LLVMOverride p sym ext args ret -> Declare
forall p sym ext (args :: Ctx CrucibleType) (ret :: CrucibleType).
LLVMOverride p sym ext args ret -> Declare
llvmOverride_declare LLVMOverride p sym ext args ret
llvmOverride
let (L.Symbol String
str_nm) = Declare -> Symbol
L.decName Declare
decl
let fnm :: FunctionName
fnm = Text -> FunctionName
functionNameFromText (String -> Text
Text.pack String
str_nm)
let mvar :: GlobalVar Mem
mvar = LLVMContext arch -> GlobalVar Mem
forall (arch :: LLVMArch). LLVMContext arch -> GlobalVar Mem
llvmMemVar LLVMContext arch
llvmctx
let overrideArgs :: CtxRepr args
overrideArgs = LLVMOverride p sym ext args ret -> CtxRepr args
forall p sym ext (args :: Ctx CrucibleType) (ret :: CrucibleType).
LLVMOverride p sym ext args ret -> CtxRepr args
llvmOverride_args LLVMOverride p sym ext args ret
llvmOverride
let overrideRet :: TypeRepr ret
overrideRet = LLVMOverride p sym ext args ret -> TypeRepr ret
forall p sym ext (args :: Ctx CrucibleType) (ret :: CrucibleType).
LLVMOverride p sym ext args ret -> TypeRepr ret
llvmOverride_ret LLVMOverride p sym ext args ret
llvmOverride
let ?lc = LLVMContext arch
llvmctxLLVMContext arch
-> Getting TypeContext (LLVMContext arch) TypeContext
-> TypeContext
forall s a. s -> Getting a s a -> a
^.Getting TypeContext (LLVMContext arch) TypeContext
forall (arch :: LLVMArch) (f :: Type -> Type).
Functor f =>
(TypeContext -> f TypeContext)
-> LLVMContext arch -> f (LLVMContext arch)
llvmTypeCtx
Declare
-> (forall {args :: Ctx CrucibleType} {ret :: CrucibleType}.
CtxRepr args -> TypeRepr ret -> OverrideSim p sym ext rtp l a ())
-> OverrideSim p sym ext rtp l a ()
forall (wptr :: Natural) (m :: Type -> Type) a.
(?lc::TypeContext, HasPtrWidth wptr, MonadFail m) =>
Declare
-> (forall (args :: Ctx CrucibleType) (ret :: CrucibleType).
CtxRepr args -> TypeRepr ret -> m a)
-> m a
llvmDeclToFunHandleRepr' Declare
decl ((forall {args :: Ctx CrucibleType} {ret :: CrucibleType}.
CtxRepr args -> TypeRepr ret -> OverrideSim p sym ext rtp l a ())
-> OverrideSim p sym ext rtp l a ())
-> (forall {args :: Ctx CrucibleType} {ret :: CrucibleType}.
CtxRepr args -> TypeRepr ret -> OverrideSim p sym ext rtp l a ())
-> OverrideSim p sym ext rtp l a ()
forall a b. (a -> b) -> a -> b
$ \CtxRepr args
args TypeRepr ret
ret -> do
Override p sym ext args ret
o <- FunctionName
-> CtxRepr args
-> TypeRepr ret
-> CtxRepr args
-> TypeRepr ret
-> (forall rtp' (l' :: Ctx CrucibleType) (a' :: CrucibleType).
IsSymInterface sym =>
Assignment (RegEntry sym) args
-> OverrideSim p sym ext rtp' l' a' (RegValue sym ret))
-> OverrideSim p sym ext rtp l a (Override p sym ext args ret)
forall sym (args :: Ctx CrucibleType) (ret :: CrucibleType)
(args' :: Ctx CrucibleType) (ret' :: CrucibleType) p ext rtp
(l :: Ctx CrucibleType) (a :: CrucibleType).
HasLLVMAnn sym =>
FunctionName
-> CtxRepr args
-> TypeRepr ret
-> CtxRepr args'
-> TypeRepr ret'
-> (forall rtp' (l' :: Ctx CrucibleType) (a' :: CrucibleType).
IsSymInterface sym =>
Assignment (RegEntry sym) args
-> OverrideSim p sym ext rtp' l' a' (RegValue sym ret))
-> OverrideSim p sym ext rtp l a (Override p sym ext args' ret')
build_llvm_override FunctionName
fnm CtxRepr args
overrideArgs TypeRepr ret
overrideRet CtxRepr args
args TypeRepr ret
ret
(\Assignment (RegEntry sym) args
asgn -> LLVMOverride p sym ext args ret
-> IsSymInterface sym =>
GlobalVar Mem
-> Assignment (RegEntry sym) args
-> forall rtp (args' :: Ctx CrucibleType) (ret' :: CrucibleType).
OverrideSim p sym ext rtp args' ret' (RegValue sym ret)
forall p sym ext (args :: Ctx CrucibleType) (ret :: CrucibleType).
LLVMOverride p sym ext args ret
-> IsSymInterface sym =>
GlobalVar Mem
-> Assignment (RegEntry sym) args
-> forall rtp (args' :: Ctx CrucibleType) (ret' :: CrucibleType).
OverrideSim p sym ext rtp args' ret' (RegValue sym ret)
llvmOverride_def LLVMOverride p sym ext args ret
llvmOverride GlobalVar Mem
mvar Assignment (RegEntry sym) args
asgn)
GlobalVar Mem
-> Symbol
-> CtxRepr args
-> TypeRepr ret
-> FnState p sym ext args ret
-> OverrideSim p sym ext rtp l a ()
forall sym (wptr :: Natural) (args :: Ctx CrucibleType)
(ret :: CrucibleType) p ext rtp (l :: Ctx CrucibleType)
(a :: CrucibleType).
(IsSymInterface sym, HasPtrWidth wptr) =>
GlobalVar Mem
-> Symbol
-> Assignment TypeRepr args
-> TypeRepr ret
-> FnState p sym ext args ret
-> OverrideSim p sym ext rtp l a ()
bindLLVMFunc GlobalVar Mem
mvar (Declare -> Symbol
L.decName Declare
decl) CtxRepr args
args TypeRepr ret
ret (Override p sym ext args ret -> FnState p sym ext args ret
forall p sym ext (args :: Ctx CrucibleType) (ret :: CrucibleType).
Override p sym ext args ret -> FnState p sym ext args ret
UseOverride Override p sym ext args ret
o)
alloc_and_register_override ::
(IsSymBackend sym bak, HasPtrWidth wptr, HasLLVMAnn sym, ?memOpts :: MemOptions) =>
bak ->
LLVMContext arch ->
LLVMOverride p sym LLVM args ret ->
[L.Symbol] ->
OverrideSim p sym LLVM rtp l a ()
alloc_and_register_override :: forall sym bak (wptr :: Natural) (arch :: LLVMArch) p
(args :: Ctx CrucibleType) (ret :: CrucibleType) rtp
(l :: Ctx CrucibleType) (a :: CrucibleType).
(IsSymBackend sym bak, HasPtrWidth wptr, HasLLVMAnn sym,
?memOpts::MemOptions) =>
bak
-> LLVMContext arch
-> LLVMOverride p sym LLVM args ret
-> [Symbol]
-> OverrideSim p sym LLVM rtp l a ()
alloc_and_register_override bak
bak LLVMContext arch
llvmctx LLVMOverride p sym LLVM args ret
llvmOverride [Symbol]
aliases = do
let L.Declare { decName :: Declare -> Symbol
L.decName = symb :: Symbol
symb@(L.Symbol String
nm) } = LLVMOverride p sym LLVM args ret -> Declare
forall p sym ext (args :: Ctx CrucibleType) (ret :: CrucibleType).
LLVMOverride p sym ext args ret -> Declare
llvmOverride_declare LLVMOverride p sym LLVM args ret
llvmOverride
let mvar :: GlobalVar Mem
mvar = LLVMContext arch -> GlobalVar Mem
forall (arch :: LLVMArch). LLVMContext arch -> GlobalVar Mem
llvmMemVar LLVMContext arch
llvmctx
MemImpl sym
mem <- GlobalVar Mem -> OverrideSim p sym LLVM rtp l a (RegValue sym Mem)
forall sym (tp :: CrucibleType) p ext rtp
(args :: Ctx CrucibleType) (ret :: CrucibleType).
IsSymInterface sym =>
GlobalVar tp
-> OverrideSim p sym ext rtp args ret (RegValue sym tp)
readGlobal GlobalVar Mem
mvar
(LLVMPointer sym wptr
_ptr, MemImpl sym
mem') <- IO (LLVMPointer sym wptr, MemImpl sym)
-> OverrideSim
p sym LLVM rtp l a (LLVMPointer sym wptr, MemImpl sym)
forall a. IO a -> OverrideSim p sym LLVM rtp l a a
forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
liftIO (bak
-> MemImpl sym
-> String
-> Symbol
-> [Symbol]
-> IO (LLVMPtr sym wptr, MemImpl sym)
forall sym bak (wptr :: Natural).
(IsSymBackend sym bak, HasPtrWidth wptr, HasLLVMAnn sym,
?memOpts::MemOptions) =>
bak
-> MemImpl sym
-> String
-> Symbol
-> [Symbol]
-> IO (LLVMPtr sym wptr, MemImpl sym)
registerFunPtr bak
bak MemImpl sym
mem String
nm Symbol
symb [Symbol]
aliases)
GlobalVar Mem
-> RegValue sym Mem -> OverrideSim p sym LLVM rtp l a ()
forall (tp :: CrucibleType) sym p ext rtp
(args :: Ctx CrucibleType) (ret :: CrucibleType).
GlobalVar tp
-> RegValue sym tp -> OverrideSim p sym ext rtp args ret ()
writeGlobal GlobalVar Mem
mvar RegValue sym Mem
MemImpl sym
mem'
LLVMContext arch
-> LLVMOverride p sym LLVM args ret
-> OverrideSim p sym LLVM rtp l a ()
forall p (args :: Ctx CrucibleType) (ret :: CrucibleType) sym ext
(arch :: LLVMArch) (wptr :: Natural) (l :: Ctx CrucibleType)
(a :: CrucibleType) rtp.
(IsSymInterface sym, HasPtrWidth wptr, HasLLVMAnn sym) =>
LLVMContext arch
-> LLVMOverride p sym ext args ret
-> OverrideSim p sym ext rtp l a ()
do_register_llvm_override LLVMContext arch
llvmctx LLVMOverride p sym LLVM args ret
llvmOverride