@@ -17,24 +17,27 @@ import Data.ElfEdit qualified as Elf
1717import Data.Functor.Const (Const (Const , getConst ))
1818import Data.Functor.Product (Product (Pair ))
1919import Data.List qualified as List
20- import Data.Macaw.Dwarf qualified as D
2120import Data.Macaw.CFG qualified as M
21+ import Data.Macaw.Dwarf qualified as D
2222import Data.Macaw.Symbolic qualified as M
2323import Data.Macaw.Symbolic.Regs qualified as M
2424import Data.Maybe qualified as Maybe
2525import Data.Parameterized.Classes (knownRepr , ixF' )
2626import Data.Parameterized.Context qualified as Ctx
2727import Data.Parameterized.Some (Some (Some ))
2828import Data.Parameterized.SymbolRepr (someSymbol )
29+ import Data.Text (Text )
2930import Data.Text qualified as Text
3031import Data.Text.Encoding qualified as Text
31- import Data.Text (Text )
3232import Data.Void (Void , absurd )
3333import Lang.Crucible.CFG.Core qualified as C
3434import Lang.Crucible.Debug (ExtImpl , CommandExt )
3535import Lang.Crucible.Debug qualified as Debug
36+ import Lang.Crucible.LLVM.MemModel qualified as Mem
3637import Lang.Crucible.Pretty (IntrinsicPrinters , ppRegVal )
3738import Lang.Crucible.Simulator.EvalStmt qualified as C
39+ import Lang.Crucible.Simulator.ExecutionTree qualified as C
40+ import Lang.Crucible.Simulator.GlobalState qualified as C
3841import Lang.Crucible.Simulator.RegMap qualified as C
3942import Prettyprinter as PP
4043import What4.Interface qualified as W4
@@ -51,6 +54,7 @@ regNames archVals =
5154
5255data MacawCommand
5356 = MDwarfGlobals
57+ | MMem
5458 | MRegister
5559 | MTrace
5660 deriving (Bounded , Enum )
@@ -62,6 +66,7 @@ abbrev :: MacawCommand -> Text
6266abbrev =
6367 \ case
6468 MDwarfGlobals -> " mglob"
69+ MMem -> " mmem"
6570 MRegister -> " mreg"
6671 MTrace -> " mtr"
6772
@@ -72,6 +77,7 @@ detail =
7277 \When given no arguments, prints all globals described in DWARF. \
7378 \Otherwise, prints the globals with the given names, one per line.\
7479 \"
80+ MMem -> Just " Display LLVM memory"
7581 MRegister -> Just " \
7682 \When given no arguments, prints all machine registers. \
7783 \Otherwise, prints the registers with the given names, one per line.\
@@ -91,19 +97,24 @@ help :: MacawCommand -> Text
9197help =
9298 \ case
9399 MDwarfGlobals -> " print DWARF globals"
100+ MMem -> " display LLVM memory"
94101 MRegister -> " display machine registers"
95102 MTrace -> " print executed machine instructions"
96103
97104name :: MacawCommand -> Text
98105name =
99106 \ case
100107 MDwarfGlobals -> " mglobals"
108+ MMem -> " mmemory"
101109 MRegister -> " mregister"
102110 MTrace -> " mtrace"
103111
104112rMDwarfGlobals :: Debug. RegexRepr Debug. ArgTypeRepr (Debug. Star Debug. Text )
105113rMDwarfGlobals = knownRepr
106114
115+ rMemory :: Debug. RegexRepr Debug. ArgTypeRepr Debug. Empty
116+ rMemory = knownRepr
117+
107118rMRegister :: Debug. RegexRepr Debug. ArgTypeRepr (Debug. Star Debug. Text )
108119rMRegister = knownRepr
109120
@@ -129,6 +140,7 @@ regex ::
129140regex archVals =
130141 \ case
131142 MDwarfGlobals -> Some rMDwarfGlobals
143+ MMem -> Some rMemory
132144 MRegister ->
133145 case enumRepr (M. toListFC (Text. pack . getConst) (regNames archVals)) of
134146 Some r -> Some (Debug. Star r)
@@ -149,14 +161,18 @@ macawCommandExt archVals =
149161 }
150162
151163data MacawResponse
152- = RNoRegs
164+ = RMemory ( PP. Doc Void )
153165 | RMDwarfGlobals [String ] [(ByteString , PP. Doc Void )]
166+ | RMissingMemory
154167 | RMRegister [(String , PP. Doc Void )]
155168 | RMTrace [[Text ]]
169+ | RNoRegs
156170
157171instance PP. Pretty MacawResponse where
158172 pretty =
159173 \ case
174+ RMemory mem -> fmap absurd mem
175+ RMissingMemory -> " LLVM memory global variable was undefined!"
160176 RNoRegs -> " Couldn't find register struct"
161177 RMDwarfGlobals errs globals ->
162178 let warnings = if List. null errs
@@ -230,10 +246,11 @@ macawExtImpl ::
230246 M. PrettyF (M. ArchReg arch ) =>
231247 W4. IsExpr (W4. SymExpr sym ) =>
232248 IntrinsicPrinters sym ->
249+ C. GlobalVar Mem. Mem ->
233250 M. GenArchVals mem arch ->
234251 Maybe (Elf. Elf (M. ArchAddrWidth arch )) ->
235252 ExtImpl MacawCommand p sym (M. MacawExt arch ) t
236- macawExtImpl iFns archVals mElf =
253+ macawExtImpl iFns mVar archVals mElf =
237254 Debug. ExtImpl $
238255 \ case
239256 MDwarfGlobals ->
@@ -250,6 +267,23 @@ macawExtImpl iFns archVals mElf =
250267 let resp = Debug. XResponse (RMDwarfGlobals errs $ ppGlobals gNms vars)
251268 pure (Debug. EvalResult ctx C. ExecutionFeatureNoChange resp)
252269 }
270+ MMem ->
271+ Debug. CommandImpl
272+ { Debug. implRegex = rMemory
273+ , Debug. implBody =
274+ \ ctx execState Debug. MEmpty -> do
275+ let result = Debug. EvalResult ctx C. ExecutionFeatureNoChange Debug. Ok
276+ case Debug. execStateSimState execState of
277+ Left notApplicable ->
278+ pure result { Debug. evalResp = Debug. UserError (Debug. NotApplicable notApplicable) }
279+ Right (C. SomeSimState simState) -> do
280+ let globs = simState Lens. ^. C. stateTree . C. actFrame . C. gpGlobals
281+ case C. lookupGlobal mVar globs of
282+ Nothing -> pure result { Debug. evalResp = Debug. XResponse RMissingMemory }
283+ Just mem ->
284+ let resp = Debug. XResponse (RMemory (Mem. ppMem (Mem. memImplHeap mem))) in
285+ pure result { Debug. evalResp = resp }
286+ }
253287 MRegister ->
254288 Debug. CommandImpl
255289 { Debug. implRegex = rMRegister
0 commit comments