packages feed

elf 0.1 → 0.2

raw patch · 5 files changed

+49/−47 lines, 5 filesdep −containerssetup-changedPVP ok

version bump matches the API change (PVP)

Dependencies removed: containers

API changes (from Hackage documentation)

- Data.Elf: getElf :: ByteString -> Elf
+ Data.Elf: SHF_ALLOC :: ElfSectionFlags
+ Data.Elf: SHF_EXECINSTR :: ElfSectionFlags
+ Data.Elf: SHF_EXT :: Int -> ElfSectionFlags
+ Data.Elf: SHF_WRITE :: ElfSectionFlags
+ Data.Elf: SHT_DYNAMIC :: ElfSectionType
+ Data.Elf: SHT_DYNSYM :: ElfSectionType
+ Data.Elf: SHT_EXT :: Word32 -> ElfSectionType
+ Data.Elf: SHT_HASH :: ElfSectionType
+ Data.Elf: SHT_NOBITS :: ElfSectionType
+ Data.Elf: SHT_NOTE :: ElfSectionType
+ Data.Elf: SHT_NULL :: ElfSectionType
+ Data.Elf: SHT_PROGBITS :: ElfSectionType
+ Data.Elf: SHT_REL :: ElfSectionType
+ Data.Elf: SHT_RELA :: ElfSectionType
+ Data.Elf: SHT_SHLIB :: ElfSectionType
+ Data.Elf: SHT_STRTAB :: ElfSectionType
+ Data.Elf: SHT_SYMTAB :: ElfSectionType
+ Data.Elf: data ElfSectionFlags
+ Data.Elf: data ElfSectionType
+ Data.Elf: parseElf :: ByteString -> Elf

Files

Setup.hs view
@@ -3,4 +3,4 @@ 
 main = defaultMainWithHooks $ simpleUserHooks { runTests = runElfTests }
 
-runElfTests a b pd lb = system "runhaskell -i./src ./tests/ElfTest.hs" >> return ()
+runElfTests a b pd lb = system "runhaskell -i./src ./tests/Test.hs" >> return ()
elf.cabal view
@@ -1,5 +1,5 @@ Name:          elf
-Version:       0.1
+Version:       0.2
 License:       BSD3
 License-file:  LICENSE
 Category:      Data
@@ -12,9 +12,9 @@ Build-Type:    Custom
 Synopsis:      Parser for ELF object format.
 Description:   Parser for ELF object format.
-Data-Files:    tests/*.elf tests/ElfTest.hs
+Data-Files:    tests/empty.elf tests/Test.hs
 
 library
-    build-depends:   base, bytestring, containers, binary
+    build-depends:   base, bytestring, binary
     hs-source-dirs:  src
     exposed-modules: Data.Elf
src/Data/Elf.hs view
@@ -1,5 +1,14 @@ -- | Data.Elf  is a module for parsing a ByteString of an ELF file into an Elf record.
-module Data.Elf (getElf, Elf(..), ElfSection(..), ElfClass(..), ElfData(..), ElfOSABI(..), ElfType(..), ElfMachine(..)) where
+module Data.Elf (parseElf
+                , Elf(..)
+                , ElfSection(..)
+                , ElfSectionType(..)
+                , ElfSectionFlags(..)
+                , ElfClass(..)
+                , ElfData(..)
+                , ElfOSABI(..)
+                , ElfType(..)
+                , ElfMachine(..)) where
 
 import Data.Binary
 import Data.Binary.Get
@@ -11,8 +20,6 @@ import qualified Data.ByteString.Internal as B
 import qualified Data.ByteString.Lazy     as L
 
-import System.IO.Unsafe
-
 data Elf = Elf
     { elfClass      :: ElfClass      -- ^ Identifies the class of the object file.
     , elfData       :: ElfData       -- ^ Identifies the data encoding of the object file.
@@ -22,7 +29,7 @@     , elfType       :: ElfType       -- ^ Identifies the object file type.
     , elfMachine    :: ElfMachine    -- ^ Identifies the target architecture.
     , elfEntry      :: Word64        -- ^ Virtual address of the program entry point. 0 for non-executable Elfs.
-    , elfSections   :: [ElfSection]  -- ^ Map from section name to section data.
+    , elfSections   :: [ElfSection]  -- ^ List of sections in the file.
     } deriving (Eq, Show)
 
 data ElfSection = ElfSection
@@ -88,21 +95,15 @@     | SHF_EXECINSTR -- ^ Section contains executable instructions
     | SHF_EXT Int   -- ^ Processor- or environment-specific flag
     deriving (Eq, Show)
-getElfSectionFlags32 er = getWord32 er >>= return . getElfSectionFlags_ 31
-    where getElfSectionFlags_ 0 word = []
-          getElfSectionFlags_ 1 word | testBit word 1 = SHF_WRITE     : getElfSectionFlags_ 0 word
-          getElfSectionFlags_ 2 word | testBit word 2 = SHF_ALLOC     : getElfSectionFlags_ 1 word
-          getElfSectionFlags_ 3 word | testBit word 4 = SHF_EXECINSTR : getElfSectionFlags_ 2 word
-          getElfSectionFlags_ n word | testBit word n = SHF_EXT n     : getElfSectionFlags_ (n-1) word
-          getElfSectionFlags_ n word = getElfSectionFlags_ (n-1) word
-getElfSectionFlags64 er = getWord64 er >>= return . getElfSectionFlags_ 63
-    where getElfSectionFlags_ 0 word = []
-          getElfSectionFlags_ 1 word | testBit word 1 = SHF_WRITE     : getElfSectionFlags_ 0 word
-          getElfSectionFlags_ 2 word | testBit word 2 = SHF_ALLOC     : getElfSectionFlags_ 1 word
-          getElfSectionFlags_ 3 word | testBit word 4 = SHF_EXECINSTR : getElfSectionFlags_ 2 word
-          getElfSectionFlags_ n word | testBit word n = SHF_EXT n     : getElfSectionFlags_ (n-1) word
-          getElfSectionFlags_ n word = getElfSectionFlags_ (n-1) word
-
+getElfSectionFlags 0 word = []
+getElfSectionFlags 1 word | testBit word 1 = SHF_WRITE     : getElfSectionFlags 0 word
+getElfSectionFlags 2 word | testBit word 2 = SHF_ALLOC     : getElfSectionFlags 1 word
+getElfSectionFlags 3 word | testBit word 4 = SHF_EXECINSTR : getElfSectionFlags 2 word
+getElfSectionFlags n word | testBit word n = SHF_EXT n     : getElfSectionFlags (n-1) word
+getElfSectionFlags n word = getElfSectionFlags (n-1) word
+getElfSectionFlags32 er = getWord32 er >>= return . getElfSectionFlags 31
+getElfSectionFlags64 er = getWord64 er >>= return . getElfSectionFlags 63
+    
 data ElfClass
     = ELFCLASS32 -- ^ 32-bit ELF format
     | ELFCLASS64 -- ^ 64-bit ELF format
@@ -503,9 +504,10 @@ divide bs s 0 = []
 divide bs s n = let (x,y) = B.splitAt s bs in x:(divide y s (n-1))
 
--- | Parses a ByteString into an Elf record. An error is thrown for unrecognized ByteStrings.
-getElf :: B.ByteString -> Elf
-getElf b =
+-- | Parses a ByteString into an Elf record. Parse failures call error. 32-bit ELF objects have their
+-- fields promoted to 64-bit so that the 32- and 64-bit ELF records can be the same.
+parseElf :: B.ByteString -> Elf
+parseElf b =
     let (e, e_shoff, e_shentsize, e_shnum, e_shstrndx) = runGet getElf_Ehdr $ L.fromChunks [b]
         sh                                             = B.take (fromIntegral (e_shentsize * e_shnum)) $ B.drop (fromIntegral e_shoff) b
         (shstroff, shstrsize)                          = runGet (getElf_Shdr_OffsetSize (elfClass e) (elfReader $ elfData e)) $ L.fromChunks [B.drop (fromIntegral (e_shentsize * e_shstrndx)) sh]
− tests/ElfTest.hs
@@ -1,21 +0,0 @@-module Main where
-
-import Data.Elf
-import System.IO
-import Test.HUnit
-import Control.Monad
-import qualified Control.Exception as E
-import qualified Data.ByteString as B
-
-testEmptyElf = withBinaryFile "./tests/empty.elf" ReadMode $ \h -> do
-    fil <- B.hGetContents h
-    res <- E.try (E.evaluate (getElf fil)) :: IO (Either E.SomeException Elf)
-    case res of
-        Left  e -> return ()
-        Right a -> assertFailure "Empty ELF did not cause an exception."
-
-tests = TestList
-    [ TestLabel "Empty ELF" $ TestCase testEmptyElf
-    ]
-
-main = runTestTT tests
+ tests/Test.hs view
@@ -0,0 +1,21 @@+module Main where
+
+import Data.Elf
+import System.IO
+import Test.HUnit
+import Control.Monad
+import qualified Control.Exception as E
+import qualified Data.ByteString as B
+
+testEmptyElf = withBinaryFile "./tests/empty.elf" ReadMode $ \h -> do
+    fil <- B.hGetContents h
+    res <- E.try (E.evaluate (parseElf fil)) :: IO (Either E.SomeException Elf)
+    case res of
+        Left  e -> return ()
+        Right a -> assertFailure "Empty ELF did not cause an exception."
+
+tests = TestList
+    [ TestLabel "Empty ELF" $ TestCase testEmptyElf
+    ]
+
+main = runTestTT tests