{-# LANGUAGE OverloadedStrings #-} module Data.Dwarf.Elf ( loadElfDwarf , elfSectionByName , parseElfDwarfADT ) where import Control.Applicative (Applicative(..), (<$>)) import qualified Data.ByteString as BS import qualified Data.Dwarf as Dwarf import Data.Dwarf.ADT (Dwarf) import qualified Data.Dwarf.ADT as Dwarf.ADT import Data.Elf (parseElf, Elf(..), ElfSection(..)) import Data.List (find) import Data.Monoid ((<>)) import Data.Text (Text) import qualified Data.Text as Text import System.IO.Posix.MMap (unsafeMMapFile) elfSectionByName :: Elf -> Text -> Either Text BS.ByteString elfSectionByName elf name = maybe (Left ("Missing section " <> name)) Right . fmap elfSectionData . find ((== name) . Text.pack . elfSectionName) $ elfSections elf loadElfDwarf :: Dwarf.Endianess -> FilePath -> IO (Elf, ([Dwarf.DIE], Dwarf.DIEMap)) loadElfDwarf endianess filename = do bs <- unsafeMMapFile filename let elf = parseElf bs get = elfSectionByName elf sections <- either (fail . Text.unpack) return $ Dwarf.Sections <$> get ".debug_info" <*> get ".debug_abbrev" <*> get ".debug_str" pure (elf, Dwarf.parseInfo endianess sections) parseElfDwarfADT :: Dwarf.Endianess -> FilePath -> IO (Dwarf, [Dwarf.ADT.Warning]) parseElfDwarfADT endianess filename = do (_elf, (cuDies, dieMap)) <- loadElfDwarf endianess filename pure $ Dwarf.ADT.fromDies dieMap cuDies