Skip to content

Commit 690d989

Browse files
committed
crucible-llvm: Add llvm debug statements
1 parent 168f000 commit 690d989

File tree

3 files changed

+118
-4
lines changed

3 files changed

+118
-4
lines changed

Diff for: crucible-llvm/src/Lang/Crucible/LLVM/Extension/Syntax.hs

+70-1
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,43 @@ data LLVMStmt (f :: CrucibleType -> Type) :: CrucibleType -> Type where
227227
!(f (LLVMPointerType wptr)) {- Second pointer -} ->
228228
LLVMStmt f (BVType wptr)
229229

230+
-- | Debug information
231+
LLVM_Debug ::
232+
!(LLVM_Dbg f c) {- Debug variant -} ->
233+
LLVMStmt f UnitType
234+
235+
-- | Debug statement variants - these have no semantic meaning
236+
data LLVM_Dbg f c where
237+
-- | Annotates a value pointed to by a pointer with local-variable debug information
238+
--
239+
-- <https://llvm.org/docs/SourceLevelDebugging.html#llvm-dbg-addr>
240+
LLVM_Dbg_Addr ::
241+
HasPtrWidth wptr =>
242+
!(f (LLVMPointerType wptr)) {- Pointer to local variable -} ->
243+
L.DILocalVariable {- Local variable information -} ->
244+
L.DIExpression {- Complex expression -} ->
245+
LLVM_Dbg f (LLVMPointerType wptr)
246+
247+
-- | Annotates a value pointed to by a pointer with local-variable debug information
248+
--
249+
-- <https://llvm.org/docs/SourceLevelDebugging.html#llvm-dbg-declare>
250+
LLVM_Dbg_Declare ::
251+
HasPtrWidth wptr =>
252+
!(f (LLVMPointerType wptr)) {- Pointer to local variable -} ->
253+
L.DILocalVariable {- Local variable information -} ->
254+
L.DIExpression {- Complex expression -} ->
255+
LLVM_Dbg f (LLVMPointerType wptr)
256+
257+
-- | Annotates a value with local-variable debug information
258+
--
259+
-- <https://llvm.org/docs/SourceLevelDebugging.html#llvm-dbg-value>
260+
LLVM_Dbg_Value ::
261+
!(TypeRepr c) {- Type of local variable -} ->
262+
!(f c) {- Value of local variable -} ->
263+
L.DILocalVariable {- Local variable information -} ->
264+
L.DIExpression {- Complex expression -} ->
265+
LLVM_Dbg f c
266+
230267
$(return [])
231268

232269
instance TypeApp LLVMExtensionExpr where
@@ -315,6 +352,7 @@ instance TypeApp LLVMStmt where
315352
LLVM_PtrLe{} -> knownRepr
316353
LLVM_PtrAddOffset w _ _ _ -> LLVMPointerRepr w
317354
LLVM_PtrSubtract w _ _ _ -> BVRepr w
355+
LLVM_Debug{} -> knownRepr
318356

319357
instance PrettyApp LLVMStmt where
320358
ppApp pp = \case
@@ -342,6 +380,13 @@ instance PrettyApp LLVMStmt where
342380
pretty "ptrAddOffset" <+> ppGlobalVar mvar <+> pp x <+> pp y
343381
LLVM_PtrSubtract _ mvar x y ->
344382
pretty "ptrSubtract" <+> ppGlobalVar mvar <+> pp x <+> pp y
383+
LLVM_Debug dbg -> ppApp pp dbg
384+
385+
instance PrettyApp LLVM_Dbg where
386+
ppApp pp = \case
387+
LLVM_Dbg_Addr x _ _ -> pretty "dbg.addr" <+> pp x
388+
LLVM_Dbg_Declare x _ _ -> pretty "dbg.declare" <+> pp x
389+
LLVM_Dbg_Value _ x _ _ -> pretty "dbg.value" <+> pp x
345390

346391
-- TODO: move to a Pretty instance
347392
ppGlobalVar :: GlobalVar Mem -> Doc ann
@@ -351,6 +396,26 @@ ppGlobalVar = viaShow
351396
ppAlignment :: Alignment -> Doc ann
352397
ppAlignment = viaShow
353398

399+
instance TestEqualityFC LLVM_Dbg where
400+
testEqualityFC testSubterm = $(U.structuralTypeEquality [t|LLVM_Dbg|]
401+
[(U.DataArg 0 `U.TypeApp` U.AnyType, [|testSubterm|])
402+
,(U.ConType [t|TypeRepr|] `U.TypeApp` U.AnyType, [|testEquality|])
403+
])
404+
405+
instance OrdFC LLVM_Dbg where
406+
compareFC compareSubterm = $(U.structuralTypeOrd [t|LLVM_Dbg|]
407+
[(U.DataArg 0 `U.TypeApp` U.AnyType, [|compareSubterm|])
408+
,(U.ConType [t|TypeRepr|] `U.TypeApp` U.AnyType, [|compareF|])
409+
])
410+
411+
instance FoldableFC LLVM_Dbg where
412+
foldMapFC = foldMapFCDefault
413+
instance FunctorFC LLVM_Dbg where
414+
fmapFC = fmapFCDefault
415+
416+
instance TraversableFC LLVM_Dbg where
417+
traverseFC = $(U.structuralTraversal [t|LLVM_Dbg|] [])
418+
354419
instance TestEqualityFC LLVMStmt where
355420
testEqualityFC testSubterm =
356421
$(U.structuralTypeEquality [t|LLVMStmt|]
@@ -359,6 +424,7 @@ instance TestEqualityFC LLVMStmt where
359424
,(U.ConType [t|GlobalVar|] `U.TypeApp` U.AnyType, [|testEquality|])
360425
,(U.ConType [t|CtxRepr|] `U.TypeApp` U.AnyType, [|testEquality|])
361426
,(U.ConType [t|TypeRepr|] `U.TypeApp` U.AnyType, [|testEquality|])
427+
,(U.ConType [t|LLVM_Dbg|] `U.TypeApp` U.DataArg 0 `U.TypeApp` U.AnyType, [|testEqualityFC testSubterm|])
362428
])
363429

364430
instance OrdFC LLVMStmt where
@@ -369,6 +435,7 @@ instance OrdFC LLVMStmt where
369435
,(U.ConType [t|GlobalVar|] `U.TypeApp` U.AnyType, [|compareF|])
370436
,(U.ConType [t|CtxRepr|] `U.TypeApp` U.AnyType, [|compareF|])
371437
,(U.ConType [t|TypeRepr|] `U.TypeApp` U.AnyType, [|compareF|])
438+
,(U.ConType [t|LLVM_Dbg|] `U.TypeApp` U.DataArg 0 `U.TypeApp` U.AnyType, [|compareFC compareSubterm|])
372439
])
373440

374441
instance FunctorFC LLVMStmt where
@@ -379,4 +446,6 @@ instance FoldableFC LLVMStmt where
379446

380447
instance TraversableFC LLVMStmt where
381448
traverseFC =
382-
$(U.structuralTraversal [t|LLVMStmt|] [])
449+
$(U.structuralTraversal [t|LLVMStmt|]
450+
[(U.ConType [t|LLVM_Dbg|] `U.TypeApp` U.DataArg 0 `U.TypeApp` U.AnyType, [|traverseFC|])
451+
])

Diff for: crucible-llvm/src/Lang/Crucible/LLVM/MemModel.hs

+2
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,8 @@ evalStmt sym = eval
518518
eval (LLVM_PtrSubtract _w mvar (regValue -> x) (regValue -> y)) =
519519
do mem <- getMem mvar
520520
liftIO $ doPtrSubtract sym mem x y
521+
522+
eval LLVM_Debug{} = pure ()
521523

522524

523525
mkMemVar :: Text

Diff for: crucible-llvm/src/Lang/Crucible/LLVM/Translation/Instruction.hs

+46-3
Original file line numberDiff line numberDiff line change
@@ -1820,13 +1820,32 @@ callFunctionWithCont :: forall s arch ret a.
18201820
LLVMGenerator s arch ret a {- ^ continuation for next instructions -} ->
18211821
LLVMGenerator s arch ret a
18221822
callFunctionWithCont instr tailCall_ fnTy fn args assign_f k
1823+
1824+
| L.ValSymbol "llvm.dbg.declare" <- fn =
1825+
do (val, lv, di) <- dbgArgs args
1826+
ptr <- case asScalar val of
1827+
Scalar _ PtrRepr ptr -> pure ptr
1828+
_ -> fail "dbg.declare: expected pointer"
1829+
extensionStmt (LLVM_Debug (LLVM_Dbg_Declare ptr lv di)) >> k
1830+
1831+
| L.ValSymbol "llvm.dbg.addr" <- fn =
1832+
do (val, lv, di) <- dbgArgs args
1833+
ptr <- case asScalar val of
1834+
Scalar _ PtrRepr ptr -> pure ptr
1835+
_ -> fail "dbg.addr: expected pointer"
1836+
extensionStmt (LLVM_Debug (LLVM_Dbg_Addr ptr lv di)) >> k
1837+
1838+
| L.ValSymbol "llvm.dbg.value" <- fn =
1839+
do (val, lv, di) <- dbgArgs args
1840+
case asScalar val of
1841+
Scalar _ repr v1 -> extensionStmt (LLVM_Debug (LLVM_Dbg_Value repr v1 lv di)) >> k
1842+
NotScalar -> fail "dbg.value: expected scalar"
1843+
18231844
-- Skip calls to debugging intrinsics. We might want to support these in some way
18241845
-- in the future. However, they take metadata values as arguments, which
18251846
-- would require some work to support.
18261847
| L.ValSymbol nm <- fn
1827-
, nm `elem` [ "llvm.dbg.declare"
1828-
, "llvm.dbg.value"
1829-
, "llvm.dbg.label"
1848+
, nm `elem` [ "llvm.dbg.label"
18301849
, "llvm.lifetime.start"
18311850
, "llvm.lifetime.start.p0i8"
18321851
, "llvm.lifetime.end"
@@ -1847,6 +1866,30 @@ callFunctionWithCont instr tailCall_ fnTy fn args assign_f k
18471866

18481867
| otherwise = callFunction (Just instr) tailCall_ fnTy fn args assign_f >> k
18491868

1869+
-- | Match the arguments used by @dbg.addr@, @dbg.declare@, and @dbg.value@.
1870+
dbgArgs ::
1871+
[L.Typed L.Value] {- ^ debug call arguments -} ->
1872+
LLVMGenerator s arch ret (LLVMExpr s arch, L.DILocalVariable, L.DIExpression)
1873+
dbgArgs args =
1874+
do (valArg, lvArg, diArg) <-
1875+
case args of
1876+
[valArg, lvArg, diArg] -> pure (valArg, lvArg, diArg)
1877+
_ -> fail "dbg expected 3 arguments"
1878+
val <-
1879+
case valArg of
1880+
L.Typed _ (L.ValMd (L.ValMdValue val)) -> pure val
1881+
_ -> fail "dbg: argument 1 expected value metadata"
1882+
lv <-
1883+
case lvArg of
1884+
L.Typed _ (L.ValMd (L.ValMdDebugInfo (L.DebugInfoLocalVariable lv))) -> pure lv
1885+
_ -> fail "dbg: argument 2 expected local variable metadata"
1886+
di <-
1887+
case diArg of
1888+
L.Typed _ (L.ValMd (L.ValMdDebugInfo (L.DebugInfoExpression di))) -> pure di
1889+
_ -> fail "dbg: argument 3 expected DIExpression"
1890+
v <- transTypedValue val
1891+
pure (v, lv, di)
1892+
18501893
typedValueAsCrucibleValue ::
18511894
L.Typed L.Value ->
18521895
LLVMGenerator s arch ret (Some (Value s))

0 commit comments

Comments
 (0)