Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

llvm: Refactor override matching #1197

Merged
merged 5 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions crucible-llvm/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# next

* The `RegOverrideM` monad was replaced by the `MakeOverride` function newtype.
* Several type parameters were removed from `OverrideTemplate`, and the `ext`
parameter was added. This had downstream effects in `basic_llvm_override`,
`polymorphic1_llvm_override`, and other functions for registering overrides.
* Override registration code was generalized. `bind_llvm_{handle,func}`
now don't require a whole `LLVMContext`, just a `GlobalVar Mem`, and are
polymorphic over `ext`.
Expand Down
1 change: 1 addition & 0 deletions crucible-llvm/crucible-llvm.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ library
Lang.Crucible.LLVM.Extension.Syntax
Lang.Crucible.LLVM.Intrinsics.Common
Lang.Crucible.LLVM.Intrinsics.Libcxx
Lang.Crucible.LLVM.Intrinsics.Match
Lang.Crucible.LLVM.Intrinsics.Options
Lang.Crucible.LLVM.MemModel.Common
Lang.Crucible.LLVM.MemModel.Options
Expand Down
55 changes: 21 additions & 34 deletions crucible-llvm/src/Lang/Crucible/LLVM/Intrinsics.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,11 @@ module Lang.Crucible.LLVM.Intrinsics

, module Lang.Crucible.LLVM.Intrinsics.Common
, module Lang.Crucible.LLVM.Intrinsics.Options
, module Lang.Crucible.LLVM.Intrinsics.Match
) where

import Control.Lens hiding (op, (:>), Empty)
import Control.Monad (forM_)
import Control.Monad.Reader (ReaderT(..))
import Control.Monad.Trans.Maybe
import Data.Foldable (asum)
import Data.List (stripPrefix, tails, isPrefixOf)
import qualified Text.LLVM.AST as L

import qualified ABI.Itanium as ABI
Expand All @@ -57,6 +54,7 @@ import Lang.Crucible.LLVM.Intrinsics.Common
import qualified Lang.Crucible.LLVM.Intrinsics.LLVM as LLVM
import qualified Lang.Crucible.LLVM.Intrinsics.Libc as Libc
import qualified Lang.Crucible.LLVM.Intrinsics.Libcxx as Libcxx
import Lang.Crucible.LLVM.Intrinsics.Match
import Lang.Crucible.LLVM.Intrinsics.Options

llvmIntrinsicTypes :: IsSymInterface sym => IntrinsicTypes sym
Expand All @@ -70,8 +68,8 @@ register_llvm_overrides ::
( IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr, wptr ~ ArchWidth arch
, ?intrinsicsOpts :: IntrinsicsOptions, ?memOpts :: MemOptions ) =>
L.Module ->
[OverrideTemplate p sym arch rtp l a] {- ^ Additional "define" overrides -} ->
[OverrideTemplate p sym arch rtp l a] {- ^ Additional "declare" overrides -} ->
[OverrideTemplate p sym LLVM arch] {- ^ Additional \"define\" overrides -} ->
[OverrideTemplate p sym LLVM arch] {- ^ Additional \"declare\" overrides -} ->
LLVMContext arch ->
OverrideSim p sym LLVM rtp l a ()
register_llvm_overrides llvmModule defineOvrs declareOvrs llvmctx =
Expand All @@ -86,46 +84,35 @@ register_llvm_overrides llvmModule defineOvrs declareOvrs llvmctx =
-- more detail, including examining function arguments
-- and the structure of C++ demangled names to extract more information.
filterTemplates ::
[OverrideTemplate p sym arch rtp l a] ->
[OverrideTemplate p sym ext arch] ->
L.Declare ->
[OverrideTemplate p sym arch rtp l a]
filterTemplates ts decl = filter (f . overrideTemplateMatcher) ts
where
L.Symbol nm = L.decName decl

f (ExactMatch x) = x == nm
f (PrefixMatch pfx) = pfx `isPrefixOf` nm
f (SubstringsMatch as) = filterSubstrings as nm
-- See Note [Darwin aliases] in Lang.Crucible.LLVM.Intrinsics.Common
f (DarwinAliasMatch x) = x == stripDarwinAliases nm

filterSubstrings [] _ = True
filterSubstrings (a:as) xs =
case restAfterSubstring a xs of
Nothing -> False
Just rest -> filterSubstrings as rest

restAfterSubstring :: String -> String -> Maybe String
restAfterSubstring sub xs = asum [ stripPrefix sub tl | tl <- tails xs ]

[OverrideTemplate p sym ext arch]
filterTemplates ts decl = filter (matches nm . overrideTemplateMatcher) ts
where L.Symbol nm = L.decName decl

-- | Helper function for registering overrides
register_llvm_overrides_ ::
(IsSymInterface sym, HasLLVMAnn sym) =>
LLVMContext arch ->
[OverrideTemplate p sym arch rtp l a] ->
[OverrideTemplate p sym ext arch] ->
[L.Declare] ->
OverrideSim p sym LLVM rtp l a ()
OverrideSim p sym ext rtp l a ()
register_llvm_overrides_ llvmctx acts decls =
llvmPtrWidth llvmctx $ \wptr -> withPtrWidth wptr $
forM_ decls $ \decl ->
do let acts' = filterTemplates acts decl
let L.Symbol nm = L.decName decl
let declnm = either (const Nothing) Just $ ABI.demangleName nm
runMaybeT (flip runReaderT (decl,declnm,llvmctx) $ asum (map overrideTemplateAction acts'))
forM_ (map overrideTemplateAction acts') $ \(MakeOverride act) ->
case act decl declnm llvmctx of
Nothing -> pure ()
Just (SomeLLVMOverride ov) ->
register_llvm_override ov decl llvmctx

register_llvm_define_overrides ::
(IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr, wptr ~ ArchWidth arch) =>
L.Module ->
[OverrideTemplate p sym arch rtp l a] ->
[OverrideTemplate p sym LLVM arch] ->
LLVMContext arch ->
OverrideSim p sym LLVM rtp l a ()
register_llvm_define_overrides llvmModule addlOvrs llvmctx =
Expand All @@ -137,7 +124,7 @@ register_llvm_declare_overrides ::
( IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr, wptr ~ ArchWidth arch
, ?intrinsicsOpts :: IntrinsicsOptions, ?memOpts :: MemOptions ) =>
L.Module ->
[OverrideTemplate p sym arch rtp l a] ->
[OverrideTemplate p sym LLVM arch] ->
LLVMContext arch ->
OverrideSim p sym LLVM rtp l a ()
register_llvm_declare_overrides llvmModule addlOvrs llvmctx =
Expand All @@ -149,7 +136,7 @@ register_llvm_declare_overrides llvmModule addlOvrs llvmctx =
declare_overrides ::
( IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr, wptr ~ ArchWidth arch
, ?lc :: TypeContext, ?intrinsicsOpts :: IntrinsicsOptions, ?memOpts :: MemOptions ) =>
[OverrideTemplate p sym arch rtp l a]
[OverrideTemplate p sym LLVM arch]
declare_overrides =
concat
[ map (\(SomeLLVMOverride ov) -> basic_llvm_override ov) Libc.libc_overrides
Expand All @@ -165,7 +152,7 @@ declare_overrides =
-- function has a definition
define_overrides ::
(IsSymInterface sym, HasLLVMAnn sym, HasPtrWidth wptr, wptr ~ ArchWidth arch, ?lc :: TypeContext) =>
[OverrideTemplate p sym arch rtp l a]
[OverrideTemplate p sym LLVM arch]
define_overrides =
[ Libcxx.register_cpp_override Libcxx.putToOverride12
, Libcxx.register_cpp_override Libcxx.putToOverride9
Expand Down
Loading
Loading