Skip to content

Commit 54af25d

Browse files
debug: Add command to print LLVM memory
1 parent f060be2 commit 54af25d

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

crucible-macaw-debug/crucible-macaw-debug.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ library
118118
containers,
119119
crucible,
120120
crucible-debug,
121+
crucible-llvm,
121122
elf-edit,
122123
lens,
123124
macaw-base,

crucible-macaw-debug/src/Data/Macaw/Symbolic/Debug.hs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,27 @@ import Data.ElfEdit qualified as Elf
1717
import Data.Functor.Const (Const(Const, getConst))
1818
import Data.Functor.Product (Product(Pair))
1919
import Data.List qualified as List
20-
import Data.Macaw.Dwarf qualified as D
2120
import Data.Macaw.CFG qualified as M
21+
import Data.Macaw.Dwarf qualified as D
2222
import Data.Macaw.Symbolic qualified as M
2323
import Data.Macaw.Symbolic.Regs qualified as M
2424
import Data.Maybe qualified as Maybe
2525
import Data.Parameterized.Classes (knownRepr, ixF')
2626
import Data.Parameterized.Context qualified as Ctx
2727
import Data.Parameterized.Some (Some(Some))
2828
import Data.Parameterized.SymbolRepr (someSymbol)
29+
import Data.Text (Text)
2930
import Data.Text qualified as Text
3031
import Data.Text.Encoding qualified as Text
31-
import Data.Text (Text)
3232
import Data.Void (Void, absurd)
3333
import Lang.Crucible.CFG.Core qualified as C
3434
import Lang.Crucible.Debug (ExtImpl, CommandExt)
3535
import Lang.Crucible.Debug qualified as Debug
36+
import Lang.Crucible.LLVM.MemModel qualified as Mem
3637
import Lang.Crucible.Pretty (IntrinsicPrinters, ppRegVal)
3738
import 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
3841
import Lang.Crucible.Simulator.RegMap qualified as C
3942
import Prettyprinter as PP
4043
import What4.Interface qualified as W4
@@ -51,6 +54,7 @@ regNames archVals =
5154

5255
data MacawCommand
5356
= MDwarfGlobals
57+
| MMem
5458
| MRegister
5559
| MTrace
5660
deriving (Bounded, Enum)
@@ -62,6 +66,7 @@ abbrev :: MacawCommand -> Text
6266
abbrev =
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
9197
help =
9298
\case
9399
MDwarfGlobals -> "print DWARF globals"
100+
MMem -> "display LLVM memory"
94101
MRegister -> "display machine registers"
95102
MTrace -> "print executed machine instructions"
96103

97104
name :: MacawCommand -> Text
98105
name =
99106
\case
100107
MDwarfGlobals -> "mglobals"
108+
MMem -> "mmemory"
101109
MRegister -> "mregister"
102110
MTrace -> "mtrace"
103111

104112
rMDwarfGlobals :: Debug.RegexRepr Debug.ArgTypeRepr (Debug.Star Debug.Text)
105113
rMDwarfGlobals = knownRepr
106114

115+
rMemory :: Debug.RegexRepr Debug.ArgTypeRepr Debug.Empty
116+
rMemory = knownRepr
117+
107118
rMRegister :: Debug.RegexRepr Debug.ArgTypeRepr (Debug.Star Debug.Text)
108119
rMRegister = knownRepr
109120

@@ -129,6 +140,7 @@ regex ::
129140
regex 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

151163
data 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

157171
instance 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

Comments
 (0)