packages feed

dwarfadt 0.3.0.1 → 0.4

raw patch · 3 files changed

+221/−98 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Data.Dwarf.ADT: subprogUnspecifiedParameters :: Subprogram -> Bool
- Data.Dwarf.ADT: subprogVariables :: Subprogram -> [Boxed (Variable (Maybe String))]
- Data.Dwarf.ADT: subrHaveUnspecified :: SubroutineType -> Bool
+ Data.Dwarf.ADT: FormalParameters :: [Boxed FormalParameter] -> Bool -> FormalParameters
+ Data.Dwarf.ADT: InlinedSubroutine :: Maybe Word64 -> Maybe Word64 -> Maybe Word64 -> Word64 -> Subprogram -> InlinedSubroutine
+ Data.Dwarf.ADT: LexicalBlock :: Maybe Word64 -> Maybe Word64 -> Maybe Word64 -> Subprogram -> LexicalBlock
+ Data.Dwarf.ADT: MemberLocationConstant :: Word64 -> MemberLocation
+ Data.Dwarf.ADT: MemberLocationExpression :: DW_OP -> MemberLocation
+ Data.Dwarf.ADT: SubprogramChildDef :: Def -> SubprogramChild
+ Data.Dwarf.ADT: SubprogramChildInlinedSubroutine :: InlinedSubroutine -> SubprogramChild
+ Data.Dwarf.ADT: SubprogramChildLabel :: SubprogramChild
+ Data.Dwarf.ADT: SubprogramChildLexicalBlock :: LexicalBlock -> SubprogramChild
+ Data.Dwarf.ADT: SubprogramChildLocalVariable :: (Variable (Maybe String)) -> SubprogramChild
+ Data.Dwarf.ADT: SubprogramChildOther :: DW_TAG -> SubprogramChild
+ Data.Dwarf.ADT: data FormalParameters
+ Data.Dwarf.ADT: data InlinedSubroutine
+ Data.Dwarf.ADT: data LexicalBlock
+ Data.Dwarf.ADT: data MemberLocation
+ Data.Dwarf.ADT: data SubprogramChild
+ Data.Dwarf.ADT: formalParamConstVal :: FormalParameter -> Maybe Word64
+ Data.Dwarf.ADT: formalParameters :: FormalParameters -> [Boxed FormalParameter]
+ Data.Dwarf.ADT: formalParametersHasUnspecified :: FormalParameters -> Bool
+ Data.Dwarf.ADT: inlinedSubroutineCallFile :: InlinedSubroutine -> Maybe Word64
+ Data.Dwarf.ADT: inlinedSubroutineCallLine :: InlinedSubroutine -> Maybe Word64
+ Data.Dwarf.ADT: inlinedSubroutineEntryPC :: InlinedSubroutine -> Word64
+ Data.Dwarf.ADT: inlinedSubroutineRanges :: InlinedSubroutine -> Maybe Word64
+ Data.Dwarf.ADT: inlinedSubroutineSubprogram :: InlinedSubroutine -> Subprogram
+ Data.Dwarf.ADT: instance Eq FormalParameters
+ Data.Dwarf.ADT: instance Eq InlinedSubroutine
+ Data.Dwarf.ADT: instance Eq LexicalBlock
+ Data.Dwarf.ADT: instance Eq MemberLocation
+ Data.Dwarf.ADT: instance Functor Member
+ Data.Dwarf.ADT: instance Ord FormalParameters
+ Data.Dwarf.ADT: instance Ord InlinedSubroutine
+ Data.Dwarf.ADT: instance Ord LexicalBlock
+ Data.Dwarf.ADT: instance Ord MemberLocation
+ Data.Dwarf.ADT: instance Ord SubprogramChild
+ Data.Dwarf.ADT: instance Show FormalParameters
+ Data.Dwarf.ADT: instance Show InlinedSubroutine
+ Data.Dwarf.ADT: instance Show LexicalBlock
+ Data.Dwarf.ADT: instance Show MemberLocation
+ Data.Dwarf.ADT: instance Show SubprogramChild
+ Data.Dwarf.ADT: lexicalBlockHighPC :: LexicalBlock -> Maybe Word64
+ Data.Dwarf.ADT: lexicalBlockLowPC :: LexicalBlock -> Maybe Word64
+ Data.Dwarf.ADT: lexicalBlockRanges :: LexicalBlock -> Maybe Word64
+ Data.Dwarf.ADT: lexicalBlockSubprogram :: LexicalBlock -> Subprogram
+ Data.Dwarf.ADT: subprogChildren :: Subprogram -> [Boxed SubprogramChild]
+ Data.Dwarf.ADT: subprogramDefs :: Subprogram -> [Boxed Def]
- Data.Dwarf.ADT: FormalParameter :: Maybe String -> Decl -> Maybe Loc -> TypeRef -> FormalParameter
+ Data.Dwarf.ADT: FormalParameter :: Maybe String -> Decl -> Maybe Loc -> TypeRef -> Maybe Word64 -> FormalParameter
- Data.Dwarf.ADT: StructureType :: Maybe String -> Maybe Word -> Decl -> Bool -> [Boxed (Member DW_OP)] -> StructureType
+ Data.Dwarf.ADT: StructureType :: Maybe String -> Maybe Word -> Decl -> Bool -> [Boxed (Member MemberLocation)] -> StructureType
- Data.Dwarf.ADT: Subprogram :: Maybe String -> Decl -> Bool -> Bool -> Maybe Word64 -> Maybe Word64 -> Maybe Loc -> [Boxed FormalParameter] -> Bool -> [Boxed (Variable (Maybe String))] -> TypeRef -> Maybe InlineType -> Bool -> Bool -> Maybe String -> Subprogram
+ Data.Dwarf.ADT: Subprogram :: Maybe String -> TypeRef -> FormalParameters -> Decl -> Bool -> Bool -> Maybe Word64 -> Maybe Word64 -> Maybe Loc -> Maybe InlineType -> Bool -> Bool -> Maybe String -> [Boxed SubprogramChild] -> Subprogram
- Data.Dwarf.ADT: SubroutineType :: Bool -> TypeRef -> [Boxed FormalParameter] -> Bool -> SubroutineType
+ Data.Dwarf.ADT: SubroutineType :: Bool -> TypeRef -> FormalParameters -> SubroutineType
- Data.Dwarf.ADT: UnionType :: Maybe String -> Word -> Decl -> [Boxed (Member (Maybe DW_OP))] -> UnionType
+ Data.Dwarf.ADT: UnionType :: Maybe String -> Word -> Decl -> [Boxed (Member (Maybe MemberLocation))] -> UnionType
- Data.Dwarf.ADT: stMembers :: StructureType -> [Boxed (Member DW_OP)]
+ Data.Dwarf.ADT: stMembers :: StructureType -> [Boxed (Member MemberLocation)]
- Data.Dwarf.ADT: subprogFormalParameters :: Subprogram -> [Boxed FormalParameter]
+ Data.Dwarf.ADT: subprogFormalParameters :: Subprogram -> FormalParameters
- Data.Dwarf.ADT: subrFormalParameters :: SubroutineType -> [Boxed FormalParameter]
+ Data.Dwarf.ADT: subrFormalParameters :: SubroutineType -> FormalParameters
- Data.Dwarf.ADT: unionMembers :: UnionType -> [Boxed (Member (Maybe DW_OP))]
+ Data.Dwarf.ADT: unionMembers :: UnionType -> [Boxed (Member (Maybe MemberLocation))]

Files

dwarfadt.cabal view
@@ -1,5 +1,5 @@ name:                dwarfadt-version:             0.3.0.1+version:             0.4 synopsis:            High-level wrapper around the dwarf library description:         dwarf is an excellent library to read dwarf files, but the output of                      parsing dwarf is very low-level and difficult to work with.
src/Data/Dwarf/ADT.hs view
@@ -12,18 +12,23 @@   , PtrType(..)   , ConstType(..)   , VolatileType(..)-  , Member(..), StructureType(..), UnionType(..)+  , FormalParameters(..)+  , MemberLocation(..), Member(..), StructureType(..), UnionType(..)   , SubrangeType(..), ArrayType(..)   , EnumerationType(..), Enumerator(..)   , SubroutineType(..), FormalParameter(..)   , InlineType(..)-  , Subprogram(..)+  , InlinedSubroutine(..)+  , LexicalBlock(..)+  , SubprogramChild(..)+  , Subprogram(..), subprogramDefs   , Variable(..)   ) where  import Control.Applicative (Applicative(..), (<$>))-import Control.Lens (_1)+import Control.Lens (Lens') import Control.Lens.Operators+import Control.Lens.Tuple import Control.Monad (when) import Control.Monad.Fix (MonadFix, mfix) import Control.Monad.Trans.Class (lift)@@ -32,7 +37,7 @@ import Control.Monad.Trans.Writer (Writer, runWriter) import Data.Dwarf (DieID, DIEMap, DIE(..), DW_TAG(..), DW_AT(..), DW_ATVAL(..)) import Data.Dwarf.AttrGetter (AttrGetterT)-import Data.Dwarf.Lens (_ATVAL_INT, _ATVAL_UINT, _ATVAL_REF, _ATVAL_STRING, _ATVAL_BLOB, _ATVAL_BOOL)+import Data.Dwarf.Lens (_ATVAL_INT, _ATVAL_UINT, _ATVAL_REF, _ATVAL_STRING, _ATVAL_BOOL) import Data.Int (Int64) import Data.List (intercalate) import Data.Map (Map)@@ -231,6 +236,11 @@ parseVolatileType :: AttrGetterT M VolatileType parseVolatileType = VolatileType <$> parseTypeRef +data MemberLocation+  = MemberLocationConstant Word64+  | MemberLocationExpression Dwarf.DW_OP+  deriving (Eq, Ord, Show)+ -- DW_AT_name=(DW_ATVAL_STRING "__val") -- DW_AT_decl_file=(DW_ATVAL_UINT 4) -- DW_AT_decl_line=(DW_ATVAL_UINT 144)@@ -244,15 +254,15 @@   , membByteSize :: Maybe Word64   , membBitSize :: Maybe Word64   , membBitOffset :: Maybe Word64-  } deriving (Eq, Ord, Show)+  } deriving (Eq, Ord, Show, Functor)  parseMember :: (Dwarf.Reader -> AttrGetterT M loc) -> DIE -> M (Boxed (Member loc))-parseMember getLoc die =+parseMember getMemberLocation die =   box DW_TAG_member die $   Member   <$> getMName   <*> getDecl-  <*> getLoc (dieReader die)+  <*> getMemberLocation (dieReader die)   <*> parseTypeRef   <*> AttrGetter.findAttr DW_AT_byte_size _ATVAL_UINT   <*> AttrGetter.findAttr DW_AT_bit_size _ATVAL_UINT@@ -267,12 +277,21 @@   , stByteSize :: Maybe Word -- Does not exist for forward-declarations   , stDecl :: Decl   , stIsDeclaration :: Bool -- is forward-declaration-  , stMembers :: [Boxed (Member Dwarf.DW_OP)]+  , stMembers :: [Boxed (Member MemberLocation)]   } deriving (Eq, Ord, Show)  flag :: DW_AT -> AttrGetterT M Bool flag atId = ((Just True ==) <$> AttrGetter.findAttr atId _ATVAL_BOOL) +parseMemberLocation :: Dwarf.Reader -> DW_ATVAL -> MemberLocation+parseMemberLocation reader attrVal =+  case attrVal of+    Dwarf.DW_ATVAL_BLOB opStr -> MemberLocationExpression $ Dwarf.parseDW_OP reader opStr+    Dwarf.DW_ATVAL_UINT uint -> MemberLocationConstant uint+    _ ->+      -- TODO: Use function from AttrGetter to get better error+      error $ "member location of unknown type: " ++ show attrVal+ parseStructureType :: [DIE] -> AttrGetterT M StructureType parseStructureType children =   StructureType@@ -280,12 +299,15 @@   <*> getMByteSize   <*> getDecl   <*> flag DW_AT_declaration-  <*> mapM (lift . parseMember getLoc) children+  <*> mapM (lift . parseMember getStructMemberLocation) children   where-    getLoc reader =-      Dwarf.parseDW_OP reader <$>-      AttrGetter.getAttr DW_AT_data_member_location _ATVAL_BLOB-  -- TODO: Parse the member_location, It's a blob with a DWARF program..+    getStructMemberLocation reader = do+      mAttrVal <- AttrGetter.findAttrVal DW_AT_data_member_location+      return $ case mAttrVal of+        Nothing ->+          -- TODO: Use function from AttrGetter to get better error+          error "StructureType must have a member location"+        Just attrVal -> parseMemberLocation reader attrVal  -- DW_AT_type=(DW_ATVAL_REF (DieID 101)) -- DW_AT_upper_bound=(DW_ATVAL_UINT 1)@@ -320,7 +342,7 @@   { unionName :: Maybe String   , unionByteSize :: Word   , unionDecl :: Decl-  , unionMembers :: [Boxed (Member (Maybe Dwarf.DW_OP))]+  , unionMembers :: [Boxed (Member (Maybe MemberLocation))]   } deriving (Eq, Ord, Show)  parseUnionType :: [DIE] -> AttrGetterT M UnionType@@ -329,11 +351,11 @@   <$> getMName   <*> getByteSize   <*> getDecl-  <*> mapM (lift . parseMember getLoc) children+  <*> mapM (lift . parseMember getUnionMemberLocation) children   where-    getLoc reader =-      fmap (Dwarf.parseDW_OP reader) <$>-      AttrGetter.findAttr DW_AT_data_member_location _ATVAL_BLOB+    getUnionMemberLocation reader = do+      mAttr <- AttrGetter.findAttrVal DW_AT_data_member_location+      return $ fmap (parseMemberLocation reader) mAttr  -- DW_AT_name=(DW_ATVAL_STRING "_SC_ARG_MAX") -- DW_AT_const_value=(DW_ATVAL_INT 0)@@ -373,6 +395,7 @@   , formalParamDecl :: Decl   , formalParamLocation :: Maybe Loc   , formalParamType :: TypeRef+  , formalParamConstVal :: Maybe Word64   } deriving (Eq, Ord, Show)  parseLoc :: Dwarf.Reader -> DW_ATVAL -> Loc@@ -393,41 +416,65 @@       <*> getDecl       <*> (fmap (parseLoc (dieReader die)) <$> AttrGetter.findAttrVal DW_AT_location)       <*> parseTypeRef+      <*> AttrGetter.findAttr DW_AT_const_value _ATVAL_UINT --- DW_AT_prototyped=(DW_ATVAL_BOOL True)--- DW_AT_type=(DW_ATVAL_REF (DieID 62))+data FormalParameters = FormalParameters+  { formalParameters :: [Boxed FormalParameter]+  , formalParametersHasUnspecified :: Bool+  } deriving (Eq, Ord, Show)++formalParametersLens :: Lens' FormalParameters [Boxed FormalParameter]+formalParametersLens f (FormalParameters pars unspec) = (`FormalParameters` unspec) <$> f pars++parseFormalParameters :: [DIE] -> M (FormalParameters, [DIE])+parseFormalParameters = go+  where+    go dies =+      case dies of+      [] -> pure (FormalParameters [] False, [])+      (die:rest)+        | dieTag die == DW_TAG_unspecified_parameters -> pure (FormalParameters [] True, rest)+        | dieTag die == DW_TAG_formal_parameter -> do+            param <- parseFormalParameter die+            go rest <&> _1 . formalParametersLens %~ (param :)+        | otherwise -> go rest <&> _2 %~ (die:)+ data SubroutineType = SubroutineType   { subrPrototyped :: Bool   , subrRetType :: TypeRef-    -- TODO: Reduce duplication with subprogram formal params-  , subrFormalParameters :: [Boxed FormalParameter]-  , subrHaveUnspecified :: Bool+  , subrFormalParameters :: FormalParameters   } deriving (Eq, Ord, Show) +-- DW_AT_prototyped=(DW_ATVAL_BOOL True)+-- DW_AT_type=(DW_ATVAL_REF (DieID 62)) parseSubroutineType :: [DIE] -> AttrGetterT M SubroutineType parseSubroutineType children = do-  (params, haveUnspecified) <- lift (parseParameters children)-  SubroutineType-    <$> flag DW_AT_prototyped-    <*> parseTypeRef-    <*> pure params-    <*> pure haveUnspecified-  where-    parseParameters [] = pure ([], False)-    parseParameters [die] | dieTag die == DW_TAG_unspecified_parameters = pure ([], True)-    parseParameters (die:dies) = do-      param <- parseFormalParameter die-      parseParameters dies <&> _1 %~ (param :)+  (params, extraChildren) <- lift $ parseFormalParameters children+  case extraChildren of+    [] ->+      SubroutineType+      <$> flag DW_AT_prototyped+      <*> parseTypeRef+      <*> pure params+    _ -> fail $ "Unexpected children of SubroutineType: " ++ show extraChildren  getLowPC :: AttrGetterT M Word64 getLowPC = AttrGetter.getAttr DW_AT_low_pc _ATVAL_UINT +getMRanges :: AttrGetterT M (Maybe Word64)+getMRanges = AttrGetter.findAttr DW_AT_ranges _ATVAL_UINT+ getMLowPC :: AttrGetterT M (Maybe Word64) getMLowPC = AttrGetter.findAttr DW_AT_low_pc _ATVAL_UINT  getMHighPC :: AttrGetterT M (Maybe Word64) getMHighPC = AttrGetter.findAttr DW_AT_high_pc _ATVAL_UINT +getMFrameBase :: Dwarf.Reader -> AttrGetterT M (Maybe Loc)+getMFrameBase reader =+  fmap (parseLoc reader) <$>+  AttrGetter.findAttrVal DW_AT_frame_base+ data InlineType = InlineType   { inlineRequested :: Bool   , inlineHappened :: Bool@@ -460,88 +507,146 @@   , varConstVal :: Maybe Word64   } deriving (Eq, Ord, Show) -parseVariable :: Dwarf.Reader -> AttrGetterT M name -> AttrGetterT M (Variable name)-parseVariable reader getVarName = do-  -- for now, ignore abstract origins-  _ <- AttrGetter.findAttrVal DW_AT_abstract_origin-  Variable-    <$> getVarName-    <*> getDecl-    <*> (fmap (parseLoc reader) <$> AttrGetter.findAttrVal DW_AT_location)-    <*> flag DW_AT_external-    <*> flag DW_AT_declaration-    <*> flag DW_AT_artificial-    <*> parseTypeRef-    <*> AttrGetter.findAttr DW_AT_const_value _ATVAL_UINT+noChildren :: DIE -> a -> a+noChildren     DIE{dieChildren=[]} = id+noChildren die@DIE{dieChildren=cs} = error $ "Unexpected children: " ++ show cs ++ " in " ++ show die +-- TODO: Use Alternative/MonadPlus instance so that we can combine+-- parsers with <|> rather than test outside if it is DW_TAG_variable+-- and then rely on it here unsafely+parseVariable :: DIE -> AttrGetterT M name -> M (Boxed (Variable name))+parseVariable die getVarName =+  noChildren die $ mkBox die $ do+    -- for now, ignore abstract origins+    _ <- AttrGetter.findAttrVal DW_AT_abstract_origin+    Variable+      <$> getVarName+      <*> getDecl+      <*> (fmap (parseLoc (dieReader die)) <$> AttrGetter.findAttrVal DW_AT_location)+      <*> flag DW_AT_external+      <*> flag DW_AT_declaration+      <*> flag DW_AT_artificial+      <*> parseTypeRef+      <*> AttrGetter.findAttr DW_AT_const_value _ATVAL_UINT++data InlinedSubroutine = InlinedSubroutine+  { inlinedSubroutineCallFile :: Maybe Word64+  , inlinedSubroutineCallLine :: Maybe Word64+  , inlinedSubroutineRanges :: Maybe Word64+  , inlinedSubroutineEntryPC :: Word64+  , inlinedSubroutineSubprogram :: Subprogram+  } deriving (Eq, Ord, Show)++parseInlinedSubroutine :: DIE -> M (Boxed InlinedSubroutine)+parseInlinedSubroutine die =+  mkBox die $ InlinedSubroutine+  <$> AttrGetter.findAttr DW_AT_call_file _ATVAL_UINT+  <*> AttrGetter.findAttr DW_AT_call_line _ATVAL_UINT+  <*> getMRanges+  <*> AttrGetter.getAttr DW_AT_entry_pc  _ATVAL_UINT+  <*> parseSubprogram (dieReader die) (dieChildren die)++data LexicalBlock = LexicalBlock+  { lexicalBlockRanges :: Maybe Word64+  , lexicalBlockLowPC :: Maybe Word64+  , lexicalBlockHighPC :: Maybe Word64+  , lexicalBlockSubprogram :: Subprogram+  } deriving (Eq, Ord, Show)++parseLexicalBlock :: DIE -> M (Boxed LexicalBlock)+parseLexicalBlock die =+  mkBox die $ LexicalBlock+  <$> getMRanges+  <*> getMLowPC+  <*> getMHighPC+  <*> parseSubprogram (dieReader die) (dieChildren die)++data SubprogramChild+  = SubprogramChildDef Def+  | SubprogramChildLexicalBlock LexicalBlock -- TODO: Lexical blocks don't quite have everything a subprogram does+  | SubprogramChildInlinedSubroutine InlinedSubroutine+  | SubprogramChildLocalVariable (Variable (Maybe String))+  | SubprogramChildLabel -- TODO: Label content+  | SubprogramChildOther DW_TAG+  deriving (Eq, Ord, Show)++subprogramChildDefs :: Boxed SubprogramChild -> [Boxed Def]+subprogramChildDefs (Boxed dId item) =+  case item of+  SubprogramChildDef def -> [Boxed dId def]+  SubprogramChildLexicalBlock x -> subprogramDefs (lexicalBlockSubprogram x)+  SubprogramChildInlinedSubroutine x -> subprogramDefs (inlinedSubroutineSubprogram x)+  SubprogramChildLocalVariable _ -> []+  SubprogramChildLabel -> []+  SubprogramChildOther _ -> []+ data Subprogram = Subprogram   { subprogName :: Maybe String -- abstract-origin subprograms are anonymous+  , subprogType :: TypeRef+  , subprogFormalParameters :: FormalParameters   , subprogDecl :: Decl   , subprogPrototyped :: Bool   , subprogExternal :: Bool   , subprogLowPC :: Maybe Word64   , subprogHighPC :: Maybe Word64   , subprogFrameBase :: Maybe Loc-  , subprogFormalParameters :: [Boxed FormalParameter]-  , subprogUnspecifiedParameters :: Bool-  , subprogVariables :: [Boxed (Variable (Maybe String))]-  , subprogType :: TypeRef   , subprogInline :: Maybe InlineType   , subprogDeclaration :: Bool   , subprogArtificial :: Bool   , subprogLinkageName :: Maybe String+  , subprogChildren :: [Boxed SubprogramChild]   } deriving (Eq, Ord, Show) -data SubprogramChild-  = SubprogramChildFormalParameter (Boxed FormalParameter)-  | SubprogramChildVariable (Boxed (Variable (Maybe String)))-  | SubprogramChildIgnored-  | SubprogramChildUnspecifiedParameters-  deriving (Eq)--noChildren :: DIE -> a -> a-noChildren     DIE{dieChildren=[]} = id-noChildren die@DIE{dieChildren=cs} = error $ "Unexpected children: " ++ show cs ++ " in " ++ show die+subprogramDefs :: Subprogram -> [Boxed Def]+subprogramDefs = concatMap subprogramChildDefs . subprogChildren  parseSubprogram :: Dwarf.Reader -> [DIE] -> AttrGetterT M Subprogram parseSubprogram reader children = do-  parsedChildren <- mapM (lift . parseChild) children+  (params, extraChildren) <- lift $ parseFormalParameters children   -- for now, ignore abstract origins & GNU extended attr for now   _ <- AttrGetter.findAttrVal $ DW_AT_user 0x2117   _ <- AttrGetter.findAttrVal $ DW_AT_user 0x2116   _ <- AttrGetter.findAttrVal DW_AT_abstract_origin   Subprogram     <$> getMName+    <*> parseTypeRef+    <*> pure params     <*> getDecl     <*> flag DW_AT_prototyped     <*> flag DW_AT_external     <*> getMLowPC     <*> getMHighPC-    <*> (fmap (parseLoc reader) <$> AttrGetter.findAttrVal DW_AT_frame_base)-    <*> pure [x | SubprogramChildFormalParameter x <- parsedChildren]-    <*> pure (SubprogramChildUnspecifiedParameters `elem` parsedChildren)-    <*> pure [x | SubprogramChildVariable x <- parsedChildren]-    <*> parseTypeRef+    <*> getMFrameBase reader     <*> getInlineType     <*> flag DW_AT_declaration     <*> flag DW_AT_artificial     <*> AttrGetter.findAttr DW_AT_linkage_name _ATVAL_STRING+    <*> mapM (lift . parseChild) extraChildren   where+    fakeBox child = pure . Boxed (dieId child)     parseChild child =       case dieTag child of-      DW_TAG_formal_parameter ->-        SubprogramChildFormalParameter <$> parseFormalParameter child-      DW_TAG_lexical_block -> pure SubprogramChildIgnored -- TODO: Parse content?-      DW_TAG_label -> pure SubprogramChildIgnored-      DW_TAG_variable ->-        noChildren child $-        SubprogramChildVariable <$> mkBox child (parseVariable reader getMName)-      DW_TAG_inlined_subroutine -> pure SubprogramChildIgnored-      DW_TAG_user 137 -> pure SubprogramChildIgnored -- GNU extensions, safe to ignore here-      DW_TAG_unspecified_parameters -> pure SubprogramChildUnspecifiedParameters-      DW_TAG_structure_type -> pure SubprogramChildIgnored-      DW_TAG_union_type -> pure SubprogramChildIgnored-      _ -> error $ "unsupported child tag in child: " ++ show child+      DW_TAG_formal_parameter -> error $ "BUG: formal_parameter not captured by parseFormalParameters: " ++ show child+      DW_TAG_unspecified_parameters -> error $ "BUG: unspecified_parameters not captured by parseFormalParameters: " ++ show child+      DW_TAG_lexical_block -> fmap SubprogramChildLexicalBlock <$> parseLexicalBlock child+      DW_TAG_variable -> fmap SubprogramChildLocalVariable <$> parseVariable child getMName+      DW_TAG_label -> fakeBox child $ SubprogramChildLabel+      DW_TAG_inlined_subroutine -> fmap SubprogramChildInlinedSubroutine <$> parseInlinedSubroutine child+      tag | tag `elem`+        [ DW_TAG_base_type+        , DW_TAG_typedef+        , DW_TAG_pointer_type+        , DW_TAG_const_type+        , DW_TAG_volatile_type+        , DW_TAG_structure_type+        , DW_TAG_array_type+        , DW_TAG_union_type+        , DW_TAG_enumeration_type+        , DW_TAG_subroutine_type+        , DW_TAG_variable+        , DW_TAG_subprogram+        ] -> fmap SubprogramChildDef <$> parseDef child+      _ -> fakeBox child $ SubprogramChildOther $ dieTag child -- GNU extensions, safe to ignore here  data DefType   = DefBaseType BaseType@@ -581,12 +686,8 @@ parseDef :: DIE -> M (Boxed Def) parseDef die =   case dieTag die of-  DW_TAG_variable ->-    mkBox die . noChildren die $-    DefVariable <$> parseVariable (dieReader die) getName-  DW_TAG_subprogram ->-    mkBox die $-    DefSubprogram <$> parseSubprogram (dieReader die) (dieChildren die)+  DW_TAG_variable -> fmap DefVariable <$> parseVariable die getName+  DW_TAG_subprogram -> mkBox die $ DefSubprogram <$> parseSubprogram (dieReader die) (dieChildren die)   _ ->     (fmap . fmap) DefType .     cachedMake (dieId die) $@@ -623,7 +724,7 @@   <*> AttrGetter.getAttr DW_AT_comp_dir _ATVAL_STRING   <*> getLowPC   <*> getMHighPC-  <*> AttrGetter.findAttr DW_AT_ranges _ATVAL_UINT+  <*> getMRanges   <*> AttrGetter.getAttr DW_AT_stmt_list _ATVAL_UINT   -- lineNumInfo   <*> mapM (lift . parseDef) (dieChildren die)
src/Data/Dwarf/ADT/Pretty.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} module Data.Dwarf.ADT.Pretty (compilationUnit, dwarf) where +import Control.Applicative ((<$>)) import Data.Dwarf (DW_ATE(..)) import Data.Dwarf.ADT (Boxed(..), Def(..), DefType(..)) import Data.Maybe (mapMaybe)@@ -85,8 +86,8 @@  data Precedence = Prefix | Postfix -paramList :: [Boxed ADT.FormalParameter] -> Bool -> PP.Doc-paramList params haveUnspecifiedParams =+paramList :: ADT.FormalParameters -> PP.Doc+paramList (ADT.FormalParameters params haveUnspecifiedParams) =   "(" <> PP.hcat (List.intersperse ", " (map param params ++ ["..." | haveUnspecifiedParams])) <> ")"   where     param@@ -143,8 +144,8 @@         annotate (simplePrecedence Postfix) (<> PP.parens                   (PP.hcat $ PP.punctuate PP.comma (map (subRange . bData) r))) $ recurseType t       DefSubroutineType ADT.SubroutineType-        { ADT.subrRetType = t, ADT.subrFormalParameters = params, ADT.subrHaveUnspecified = unspec } ->-        annotate (simplePrecedence Postfix) (<> paramList params unspec) $ recurseType t+        { ADT.subrRetType = t, ADT.subrFormalParameters = params } ->+        annotate (simplePrecedence Postfix) (<> paramList params) $ recurseType t  defTypedef :: ADT.Typedef -> PP.Doc defTypedef (ADT.Typedef name _ typeRef) = "typedef " <> ppType (Just name) typeRef@@ -158,6 +159,25 @@ defEnumerationType :: ADT.EnumerationType -> PP.Doc defEnumerationType = enumerationType +lexicalBlock :: ADT.LexicalBlock -> PP.Doc+lexicalBlock (ADT.LexicalBlock _ _ _ s) =+  PP.text "lexical block " <> defSubprogram s++inlinedSubroutine :: ADT.InlinedSubroutine -> PP.Doc+inlinedSubroutine (ADT.InlinedSubroutine _ _ _ _ s) =+  PP.text "inlined " <> defSubprogram s++subprogChild :: Boxed ADT.SubprogramChild -> Maybe PP.Doc+subprogChild (Boxed dId dat) =+  (showPP dId <> " " <>) . (<> ";") <$>+  case dat of+  ADT.SubprogramChildDef x -> def (Boxed dId x)+  ADT.SubprogramChildLexicalBlock x -> Just $ lexicalBlock x+  ADT.SubprogramChildInlinedSubroutine x -> Just $ inlinedSubroutine x+  ADT.SubprogramChildLabel -> Nothing+  ADT.SubprogramChildLocalVariable _ -> Nothing+  ADT.SubprogramChildOther _ -> Nothing+ defSubprogram :: ADT.Subprogram -> PP.Doc defSubprogram ADT.Subprogram   { ADT.subprogName = name@@ -165,12 +185,14 @@   , ADT.subprogFormalParameters = params   , ADT.subprogLowPC = lowPC   , ADT.subprogHighPC = highPC-  , ADT.subprogUnspecifiedParameters = unspec+  , ADT.subprogChildren = children   } =-  PP.hcat-  [ ppType name typ, paramList params unspec-  , " at (", m lowPC, ":", m highPC, ")"-  ]+  PP.vcat $+  [ PP.hcat+    [ ppType name typ, paramList params+    , " at (", m lowPC, ":", m highPC, ")"+    ]+  ] ++ mapMaybe subprogChild children   where     m = maybe "" showPP