-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMMap.idr
169 lines (137 loc) · 4.84 KB
/
MMap.idr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
module MMap
import Effects
import Effect.State
import Data.Bits
import CFFI
%include C "sys/mman.h"
%access public export
--mutual
data MMapFlag = ProtExec
| ProtWrite
| ProtRead
| ProtNone
| MapShared
| MapPrivate
| MapAnonymous
record MMapFlags where
constructor MkMMapFlags
prot, maps : Bits32
data MMap : Effect where
CallMMap : Ptr -> Bits64 -> MMapFlags -> Bits32 -> Bits64 -> sig MMap Ptr
CallUnMMap : Ptr -> Bits64 -> sig MMap Int
MMAP : EFFECT
MMAP = MkEff () MMap
addFlag : MMapFlag -> MMapFlags -> MMapFlags
addFlag ProtExec x = record { prot $= (or' {n=2} 0x4)} x
addFlag ProtWrite x = record { prot $= (or' {n=2} 0x2)} x
addFlag ProtRead x = record { prot $= (or' {n=2} 0x1)} x
addFlag ProtNone x = record { maps $= (or' {n=2} 0x0)} x
addFlag MapShared x = record { maps $= (or' {n=2} 0x1)} x
addFlag MapPrivate x = record { maps $= (or' {n=2} 0x2)} x
addFlag MapAnonymous x = record { maps $= (or' {n=2} 0x20)} x
flags : Foldable f => f MMapFlag -> MMapFlags
flags l = foldr addFlag (MkMMapFlags 0 0) l
PROT_EXEC : MMapFlag
PROT_EXEC = ProtExec
PROT_WRITE : MMapFlag
PROT_WRITE = ProtWrite
PROT_READ : MMapFlag
PROT_READ = ProtRead
PROT_NONE : MMapFlag
PROT_NONE = ProtNone
MAP_SHARED : MMapFlag
MAP_SHARED = MapShared
MAP_PRIVATE : MMapFlag
MAP_PRIVATE = MapPrivate
MAP_ANONYMOUS : MMapFlag
MAP_ANONYMOUS = MapAnonymous
concatXElem : Elem e (e::es) -> (l: List a) -> Elem e (l++(e::es))
concatXElem prf [] = Here
concatXElem prf (h::t) = There (concatXElem prf t)
--concatElemY : (l : List a) -> {auto ok : NonEmpty l} -> Elem (head {ok} l) l
--concatElemY l = with List the (Elem (head l) l) Here
{-mmap : (ptr:Ptr) -> (len:Bits64) -> (flags:MMapFlags)-> (fd:Bits32) -> (off:Bits64) ->
EffM m Ptr (x ++ [MMAP] ++ y)
(\v => updateResTy v (x ++ MMAP :: y) (concatXElem Here x) (CallMMap ptr len flags fd off))
mmap ptr len flags fd off {x} =
let prf = concatXElem Here x in call (CallMMap ptr len flags fd off) {prf}
munmap : (ptr:Ptr) -> (len:Bits64) ->
EffM m Int (x ++ [MMAP] ++ y)
(\v => updateResTy v (x ++ MMAP :: y) (concatXElem Here x) (CallUnMMap ptr len))
munmap ptr len {x} = let prf = concatXElem Here x in call (CallUnMMap ptr len) {prf}
mmap_exe : {x:List EFFECT} -> (t:Composite) -> EffM m Ptr (x ++ [MMAP] ++ y)
(\v => updateResTy v
(x ++ MMAP :: y)
(concatXElem Here x)
(CallMMap Prelude.Strings.null
(prim__zextInt_B64 (sizeOf t))
(flags [PROT_EXEC, PROT_WRITE, PROT_READ, MAP_PRIVATE, MAP_ANONYMOUS])
(prim__zextInt_B32 (-1))
0))
mmap_exe t {x} {y} =
(mmap null
(prim__zextInt_B64 $ sizeOf t)
(with List flags [PROT_EXEC, PROT_WRITE, PROT_READ, MAP_PRIVATE, MAP_ANONYMOUS])
(prim__zextInt_B32 (-1))
0)-}
namespace Eff
mmap : (ptr:Ptr) -> (len:Bits64) -> (flags:MMapFlags)-> (fd:Bits32) -> (off:Bits64) ->
Eff Ptr [MMAP]
mmap ptr len flags fd off = call (CallMMap ptr len flags fd off)
munmap : (ptr:Ptr) -> (len:Bits64) -> Eff Int [MMAP]
munmap ptr len = call (CallUnMMap ptr len)
mmap_exe : (t:Composite) -> Eff Ptr [MMAP]
mmap_exe t = mmap null
(prim__zextInt_B64 $ sizeOf t)
(with List flags [PROT_EXEC, PROT_WRITE, PROT_READ, MAP_PRIVATE, MAP_ANONYMOUS])
(prim__zextInt_B32 (-1))
0
withMMap : (ty:Composite) ->
{auto eli:SubElem MMAP effi} ->
{auto elo:SubElem MMAP effo} ->
{auto seli:SubList [MMAP] effi} ->
{auto selo:SubList [MMAP] effo} ->
{auto selel: SubList effi effo} ->
{auto updateInvariant1 : (updateWith [MMAP] effo selo) = effo} ->
{auto updateInvariant2 : (updateWith effi effo selel) = effo} ->
(f:Ptr -> Eff a effi) -> Eff a effo
withMMap ty f {effo} {a} {updateInvariant1} {updateInvariant2} = ?hmm
infixl 1 .|.
private
(.|.) : %static {n:Nat} -> machineTy n -> machineTy n -> machineTy n
(.|.) = or'
infixl 2 .&.
private
(.&.) : %static {n:Nat} -> machineTy n -> machineTy n -> machineTy n
(.&.) = and'
namespace IO
public export
mmap : Ptr -> Bits64 -> MMapFlags -> Bits32 -> Bits64 -> IO Ptr
mmap ptr len flags fd off =
foreign FFI_C "mmap"
(Ptr -> Bits64 -> Bits32 -> Bits32 -> Bits32 -> Bits64 -> IO Ptr)
ptr len (prot flags) (maps flags) fd off
public export
mmap_exe : Composite -> IO Ptr
mmap_exe t = mmap null
(prim__zextInt_B64 $ sizeOf t)
(flags [PROT_EXEC, PROT_WRITE, PROT_READ, MAP_PRIVATE, MAP_ANONYMOUS])
(prim__zextInt_B32 (-1))
0
public export
munmap : Ptr -> Bits64 -> IO Int
munmap ptr len = foreign FFI_C "munmap" (Ptr -> Bits64 -> IO Int) ptr len
public export
withMMap : Composite -> (CPtr -> IO a) -> IO a
withMMap t f = do
m <- mmap_exe t
r <- f m
munmap m (prim__zextInt_B64 $ sizeOf t)
pure r
Handler MMap IO where
handle ctx (CallMMap ptr len flags fd off) k = do
ptr <- IO.mmap ptr len flags fd off
k ptr ctx
handle ctx (CallUnMMap ptr len) k = do
res <- IO.munmap ptr len
k res ctx