elf 0.30 → 0.31
raw patch · 2 files changed
+87/−11 lines, 2 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Data.Elf: ElfRel :: Word64 -> Word64 -> Word8 -> Maybe Int64 -> ElfRel
+ Data.Elf: ElfRelocationSection :: [ElfSymbolTableEntry] -> ElfSection -> [ElfRel] -> ElfRelocationSection
+ Data.Elf: [elfRelOffset] :: ElfRel -> Word64
+ Data.Elf: [elfRelSectRelocated] :: ElfRelocationSection -> ElfSection
+ Data.Elf: [elfRelSectRelocations] :: ElfRelocationSection -> [ElfRel]
+ Data.Elf: [elfRelSectSymbolTable] :: ElfRelocationSection -> [ElfSymbolTableEntry]
+ Data.Elf: [elfRelSymAddend] :: ElfRel -> Maybe Int64
+ Data.Elf: [elfRelSymbol] :: ElfRel -> Word64
+ Data.Elf: [elfRelType] :: ElfRel -> Word8
+ Data.Elf: data ElfRel
+ Data.Elf: data ElfRelocationSection
+ Data.Elf: instance GHC.Classes.Eq Data.Elf.ElfRel
+ Data.Elf: instance GHC.Classes.Eq Data.Elf.ElfRelocationSection
+ Data.Elf: instance GHC.Show.Show Data.Elf.ElfRel
+ Data.Elf: instance GHC.Show.Show Data.Elf.ElfRelocationSection
+ Data.Elf: parseRelocations :: Elf -> [ElfRelocationSection]
Files
- elf.cabal +2/−2
- src/Data/Elf.hs +85/−9
elf.cabal view
@@ -1,5 +1,5 @@ Name: elf-Version: 0.30+Version: 0.31 License: BSD3 License-file: LICENSE Category: Data@@ -29,7 +29,7 @@ library build-depends: base >= 2 && < 5 , bytestring- , binary+ , binary >= 0.6 hs-source-dirs: src exposed-modules: Data.Elf default-language: Haskell2010
src/Data/Elf.hs view
@@ -1,28 +1,40 @@+{-# LANGUAGE ScopedTypeVariables #-}+ -- | Data.Elf is a module for parsing a ByteString of an ELF file into an Elf record. module Data.Elf ( parseElf , parseSymbolTables+ , parseRelocations , findSymbolDefinition+ -- * Top-level header , Elf(..)+ , ElfClass(..)+ , ElfData(..)+ , ElfOSABI(..)+ , ElfType(..)+ , ElfMachine(..)+ -- * Sections , ElfSection(..) , ElfSectionType(..) , ElfSectionFlags(..)+ -- * Segments , ElfSegment(..) , ElfSegmentType(..) , ElfSegmentFlag(..)- , ElfClass(..)- , ElfData(..)- , ElfOSABI(..)- , ElfType(..)- , ElfMachine(..)+ -- * Symbols , ElfSymbolTableEntry(..) , ElfSymbolType(..) , ElfSymbolBinding(..)- , ElfSectionIndex(..)) where+ , ElfSectionIndex(..)+ -- * Relocations+ , ElfRel(..)+ , ElfRelocationSection(..)+ ) where import Data.Binary import Data.Binary.Get as G import Data.Bits import Data.Maybe+import Data.Int import Control.Monad import qualified Data.ByteString as B import qualified Data.ByteString.Internal as B@@ -677,12 +689,18 @@ -- | Assumes the given section is a symbol table, type SHT_SYMTAB, or SHT_DYNSYM -- (guaranteed by parseSymbolTables). getSymbolTableEntries :: Elf -> ElfSection -> [ElfSymbolTableEntry]-getSymbolTableEntries e s = go decoder (L.fromChunks [elfSectionData s])+getSymbolTableEntries e s =+ decodeMany (getSymbolTableEntry e strtab) (L.fromStrict (elfSectionData s)) where link = elfSectionLink s strtab = lookup (fromIntegral link) (zip [0..] (elfSections e))- decoder = runGetIncremental (getSymbolTableEntry e strtab)- go :: Decoder ElfSymbolTableEntry -> L.ByteString -> [ElfSymbolTableEntry]++decodeMany :: forall a. Get a -> L.ByteString -> [a]+decodeMany get = go decoder+ where+ decoder = runGetIncremental get++ go :: Decoder a -> L.ByteString -> [a] go (Done leftover _ entry) input = entry : go decoder (L.Chunk leftover input) go (Partial k) input =@@ -869,3 +887,61 @@ stringByIndex n strtab = let str = (B.takeWhile (/=0) . B.drop (fromIntegral n)) strtab in if B.length str == 0 then Nothing else Just str++data ElfRel = ElfRel+ { elfRelOffset :: Word64+ , elfRelSymbol :: Word64+ , elfRelType :: Word8+ , elfRelSymAddend :: Maybe Int64+ } deriving (Eq, Show)++getElfRel :: ElfClass+ -> ElfReader+ -> Bool -- ^ explicit addend?+ -> Get ElfRel+getElfRel ELFCLASS64 er explicit = do+ offset <- getWord64 er+ info <- getWord64 er+ addend <- if explicit then Just <$> getWord64 er else pure Nothing+ return ElfRel { elfRelOffset = offset+ , elfRelSymbol = fromIntegral (info `shiftR` 32)+ , elfRelType = fromIntegral info+ , elfRelSymAddend = fromIntegral <$> addend+ }+getElfRel ELFCLASS32 er explicit = do+ offset <- getWord32 er+ info <- getWord32 er+ addend <- if explicit then Just <$> getWord32 er else pure Nothing+ return ElfRel { elfRelOffset = fromIntegral offset+ , elfRelSymbol = fromIntegral (info `shiftR` 8)+ , elfRelType = fromIntegral info+ , elfRelSymAddend = fromIntegral <$> addend+ }++getRelocations :: ElfClass -> ElfReader -> ElfSection -> [ElfRel]+getRelocations elf_class er s =+ decodeMany (getElfRel elf_class er explicit) (L.fromStrict (elfSectionData s))+ where+ explicit = elfSectionType s == SHT_RELA++data ElfRelocationSection = ElfRelocationSection+ { elfRelSectSymbolTable :: [ElfSymbolTableEntry]+ , elfRelSectRelocated :: ElfSection+ , elfRelSectRelocations :: [ElfRel]+ } deriving (Eq, Show)++parseRelocations :: Elf -> [ElfRelocationSection]+parseRelocations elf =+ [ ElfRelocationSection { elfRelSectSymbolTable = symtab+ , elfRelSectRelocated = relocated+ , elfRelSectRelocations = rels+ }+ | s <- elfSections elf+ , elfSectionType s `elem` [SHT_REL, SHT_RELA]+ , let symtab = getSymbolTableEntries elf (getSection (elfSectionLink s))+ relocated = getSection (elfSectionInfo s)+ rels = getRelocations (elfClass elf) er s+ ]+ where+ getSection i = elfSections elf !! fromIntegral i+ er = elfReader (elfData elf)