data-elf 0.1.0.1 → 0.2
raw patch · 3 files changed
+557/−360 lines, 3 filesdep +data-serializerdep −binarydep −bytestringdep −data-endianPVP ok
version bump matches the API change (PVP)
Dependencies added: data-serializer
Dependencies removed: binary, bytestring, data-endian, text-latin1
API changes (from Hackage documentation)
- Data.Elf: DefSymVisi :: SymVisi
- Data.Elf: HiddenSymVisi :: SymVisi
- Data.Elf: IntSymVisi :: SymVisi
- Data.Elf: ProtSymVisi :: SymVisi
- Data.Elf: buildFileHdr32 :: Endian -> FileHdr32 -> Builder
- Data.Elf: buildFileHdr64 :: Endian -> FileHdr64 -> Builder
- Data.Elf: buildIdent :: Ident -> Builder
- Data.Elf: buildProgHdr32 :: Endian -> ProgHdr32 -> Builder
- Data.Elf: buildProgHdr64 :: Endian -> ProgHdr64 -> Builder
- Data.Elf: buildRelaEnt32 :: Endian -> RelaEnt32 -> Builder
- Data.Elf: buildRelaEnt64 :: Endian -> RelaEnt64 -> Builder
- Data.Elf: buildSecHdr32 :: Endian -> SecHdr32 -> Builder
- Data.Elf: buildSecHdr64 :: Endian -> SecHdr64 -> Builder
- Data.Elf: buildSymEnt32 :: Endian -> SymEnt32 -> Builder
- Data.Elf: buildSymEnt64 :: Endian -> SymEnt64 -> Builder
- Data.Elf: data SymVisi
- Data.Elf: fileHdr32Size :: Int
- Data.Elf: fileHdr64Size :: Int
- Data.Elf: getFileHdr32 :: Endian -> Get FileHdr32
- Data.Elf: getProgHdr32 :: Endian -> Get ProgHdr32
- Data.Elf: identSize :: Int
- Data.Elf: instance Data.Binary.Class.Binary Data.Elf.Ident
- Data.Elf: progHdr32Size :: Int
- Data.Elf: progHdr64Size :: Int
- Data.Elf: putFileHdr32 :: Endian -> FileHdr32 -> Put
- Data.Elf: putProgHdr32 :: Endian -> ProgHdr32 -> Put
- Data.Elf: relaEnt32Size :: Int
- Data.Elf: relaEnt64Size :: Int
- Data.Elf: secHdr32Size :: Int
- Data.Elf: secHdr64Size :: Int
- Data.Elf: symEnt32Size :: Int
- Data.Elf: symEnt64Size :: Int
- Data.Elf: unSymVisi :: SymVisi -> Word2
+ Data.Elf: SymVisi :: Word4 -> SymVisi
+ Data.Elf: [unSymVisi] :: SymVisi -> Word4
+ Data.Elf: aFileHdr32 :: Proxy FileHdr32
+ Data.Elf: aFileHdr64 :: Proxy FileHdr64
+ Data.Elf: aProgHdr32 :: Proxy ProgHdr32
+ Data.Elf: aProgHdr64 :: Proxy ProgHdr64
+ Data.Elf: aRelEnt32 :: Proxy RelEnt32
+ Data.Elf: aRelEnt64 :: Proxy RelEnt64
+ Data.Elf: aRelaEnt32 :: Proxy RelaEnt32
+ Data.Elf: aRelaEnt64 :: Proxy RelaEnt64
+ Data.Elf: aSecHdr32 :: Proxy SecHdr32
+ Data.Elf: aSecHdr64 :: Proxy SecHdr64
+ Data.Elf: aSymEnt32 :: Proxy SymEnt32
+ Data.Elf: aSymEnt64 :: Proxy SymEnt64
+ Data.Elf: anIdent :: Proxy Ident
+ Data.Elf: defSymVisi :: SymVisi
+ Data.Elf: elimSymVisi :: SymVisi
+ Data.Elf: exportSymVisi :: SymVisi
+ Data.Elf: hiddenSymVisi :: SymVisi
+ Data.Elf: instance Data.Deserializer.Deserializable Data.Elf.FileHdr32
+ Data.Elf: instance Data.Deserializer.Deserializable Data.Elf.FileHdr64
+ Data.Elf: instance Data.Deserializer.Deserializable Data.Elf.Ident
+ Data.Elf: instance Data.Deserializer.Deserializable Data.Elf.ProgHdr32
+ Data.Elf: instance Data.Deserializer.Deserializable Data.Elf.ProgHdr64
+ Data.Elf: instance Data.Deserializer.Deserializable Data.Elf.RelEnt32
+ Data.Elf: instance Data.Deserializer.Deserializable Data.Elf.RelEnt64
+ Data.Elf: instance Data.Deserializer.Deserializable Data.Elf.RelaEnt32
+ Data.Elf: instance Data.Deserializer.Deserializable Data.Elf.RelaEnt64
+ Data.Elf: instance Data.Deserializer.Deserializable Data.Elf.SecHdr32
+ Data.Elf: instance Data.Deserializer.Deserializable Data.Elf.SecHdr64
+ Data.Elf: instance Data.Deserializer.Deserializable Data.Elf.SymEnt32
+ Data.Elf: instance Data.Deserializer.Deserializable Data.Elf.SymEnt64
+ Data.Elf: instance Data.Elf.IsFileClass c => GHC.Classes.Eq (Data.Elf.FileHdr c)
+ Data.Elf: instance Data.Elf.IsFileClass c => GHC.Classes.Eq (Data.Elf.ProgHdr c)
+ Data.Elf: instance Data.Elf.IsFileClass c => GHC.Classes.Eq (Data.Elf.SecHdr c)
+ Data.Elf: instance Data.Elf.IsFileClass c => GHC.Classes.Eq (Data.Elf.SymEnt c)
+ Data.Elf: instance Data.Elf.IsFileClass c => GHC.Read.Read (Data.Elf.FileHdr c)
+ Data.Elf: instance Data.Elf.IsFileClass c => GHC.Read.Read (Data.Elf.ProgHdr c)
+ Data.Elf: instance Data.Elf.IsFileClass c => GHC.Read.Read (Data.Elf.SecHdr c)
+ Data.Elf: instance Data.Elf.IsFileClass c => GHC.Read.Read (Data.Elf.SymEnt c)
+ Data.Elf: instance Data.Elf.IsFileClass c => GHC.Show.Show (Data.Elf.FileHdr c)
+ Data.Elf: instance Data.Elf.IsFileClass c => GHC.Show.Show (Data.Elf.ProgHdr c)
+ Data.Elf: instance Data.Elf.IsFileClass c => GHC.Show.Show (Data.Elf.SecHdr c)
+ Data.Elf: instance Data.Elf.IsFileClass c => GHC.Show.Show (Data.Elf.SymEnt c)
+ Data.Elf: instance Data.Serializer.Serializable Data.Elf.FileHdr32
+ Data.Elf: instance Data.Serializer.Serializable Data.Elf.FileHdr64
+ Data.Elf: instance Data.Serializer.Serializable Data.Elf.Ident
+ Data.Elf: instance Data.Serializer.Serializable Data.Elf.ProgHdr32
+ Data.Elf: instance Data.Serializer.Serializable Data.Elf.ProgHdr64
+ Data.Elf: instance Data.Serializer.Serializable Data.Elf.RelEnt32
+ Data.Elf: instance Data.Serializer.Serializable Data.Elf.RelEnt64
+ Data.Elf: instance Data.Serializer.Serializable Data.Elf.RelaEnt32
+ Data.Elf: instance Data.Serializer.Serializable Data.Elf.RelaEnt64
+ Data.Elf: instance Data.Serializer.Serializable Data.Elf.SecHdr32
+ Data.Elf: instance Data.Serializer.Serializable Data.Elf.SecHdr64
+ Data.Elf: instance Data.Serializer.Serializable Data.Elf.SymEnt32
+ Data.Elf: instance Data.Serializer.Serializable Data.Elf.SymEnt64
+ Data.Elf: instance Data.Serializer.SizedSerializable Data.Elf.FileHdr32
+ Data.Elf: instance Data.Serializer.SizedSerializable Data.Elf.FileHdr64
+ Data.Elf: instance Data.Serializer.SizedSerializable Data.Elf.Ident
+ Data.Elf: instance Data.Serializer.SizedSerializable Data.Elf.ProgHdr32
+ Data.Elf: instance Data.Serializer.SizedSerializable Data.Elf.ProgHdr64
+ Data.Elf: instance Data.Serializer.SizedSerializable Data.Elf.RelEnt32
+ Data.Elf: instance Data.Serializer.SizedSerializable Data.Elf.RelEnt64
+ Data.Elf: instance Data.Serializer.SizedSerializable Data.Elf.RelaEnt32
+ Data.Elf: instance Data.Serializer.SizedSerializable Data.Elf.RelaEnt64
+ Data.Elf: instance Data.Serializer.SizedSerializable Data.Elf.SecHdr32
+ Data.Elf: instance Data.Serializer.SizedSerializable Data.Elf.SecHdr64
+ Data.Elf: instance Data.Serializer.SizedSerializable Data.Elf.SymEnt32
+ Data.Elf: instance Data.Serializer.SizedSerializable Data.Elf.SymEnt64
+ Data.Elf: instance GHC.Classes.Eq Data.Elf.Ident
+ Data.Elf: instance GHC.Read.Read Data.Elf.Ident
+ Data.Elf: instance GHC.Show.Show Data.Elf.Ident
+ Data.Elf: intSymVisi :: SymVisi
+ Data.Elf: newtype SymVisi
+ Data.Elf: protSymVisi :: SymVisi
+ Data.Elf: singSymVisi :: SymVisi
Files
- README.md +3/−0
- data-elf.cabal +2/−5
- src/Data/Elf.hs +552/−355
README.md view
@@ -1,5 +1,8 @@ Data-Elf ========++[](http://hackage.haskell.org/package/data-elf)+ This package provides Executable and Linkable Format (ELF) data structures. Installation
data-elf.cabal view
@@ -1,5 +1,5 @@ Name: data-elf-Version: 0.1.0.1+Version: 0.2 Category: Data Stability: experimental Synopsis: Executable and Linkable Format (ELF) data structures.@@ -28,12 +28,9 @@ Library Default-Language: Haskell2010 Build-Depends: base >= 4.7 && < 5- , bytestring >= 0.10.2- , binary >= 0.7- , data-endian >= 0.1 , data-sword >= 0.1.1 , data-flags >= 0.0.3- , text-latin1 >= 0.3+ , data-serializer >= 0.2 Hs-Source-Dirs: src GHC-Options: -Wall Exposed-Modules:
src/Data/Elf.hs view
@@ -1,14 +1,19 @@ {-# LANGUAGE UnicodeSyntax #-}+{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE TypeFamilies #-} -- | This module provides ELF data structures and (de)serialization routines. module Data.Elf- ( FileClass(..)+ (+ -- * File class+ FileClass(..) , invalidFileClass , elf32FileClass , elf64FileClass@@ -17,6 +22,8 @@ , anElf32 , Elf64(..) , anElf64+ -- * File header+ -- ** File type , FileType(..) , noneFileType , relFileType@@ -27,18 +34,23 @@ , hiOsFileType , loProcFileType , hiProcFileType+ -- ** Machine code , Machine(..) , undefMachine , i386Machine , amd64Machine+ -- ** Machine flags , MachFlags(..)+ -- ** ELF version , Version(..) , invalidVersion , firstVersion+ -- ** Data encoding , DataEnc(..) , invalidDataEnc , lsbDataEnc , msbDataEnc+ -- ** Operating system ABI , OsAbi(..) , sysvOsAbi , hpuxOsAbi@@ -58,18 +70,17 @@ , embedOsAbi , AbiVer(..) , undefAbiVer+ -- ** Identification , Ident(..)- , identSize- , buildIdent+ , anIdent+ -- ** File header , FileHdr(..) , FileHdr32+ , aFileHdr32 , FileHdr64- , fileHdr32Size- , fileHdr64Size- , putFileHdr32- , getFileHdr32- , buildFileHdr32- , buildFileHdr64+ , aFileHdr64+ -- * Program header+ -- ** Segment type , SegType(..) , unusedSegType , loadSegType@@ -82,22 +93,23 @@ , hiOsSegType , loProcSegType , hiProcSegType+ -- ** Segment flags , SegFlags(..) , execSegFlag , writeSegFlag , readSegFlag , osSegFlags , procSegFlags+ -- ** Program header , ProgHdr(..) , ProgHdr32+ , aProgHdr32 , ProgHdr64- , progHdr32Size- , progHdr64Size- , putProgHdr32- , getProgHdr32- , buildProgHdr32- , buildProgHdr64+ , aProgHdr64+ -- * Section header+ -- ** String table index , StrIx+ -- ** Section header table index , SecIx(..) , undefSecIx , lastSecIx@@ -108,6 +120,7 @@ , absSecIx , commonSecIx , xIndexSecIx+ -- ** Section type , SecType(..) , unusedSecType , progBitsSecType@@ -125,6 +138,7 @@ , hiOsSecType , loProcSecType , hiProcSecType+ -- ** Section flags , SecFlags(..) , writeSecFlag , allocSecFlag@@ -133,14 +147,15 @@ , infoLinkSecFlag , osSecFlags , procSecFlags+ -- ** Section header , SecHdr(..) , SecHdr32+ , aSecHdr32 , SecHdr64- , secHdr32Size- , secHdr64Size- , buildSecHdr32- , buildSecHdr64+ , aSecHdr64 , zeroSecHdr+ -- * Symbol table+ -- ** Symbol type , SymType(..) , undefSymType , objSymType@@ -153,6 +168,7 @@ , hiOsSymType , loProcSymType , hiProcSymType+ -- ** Symbol binding , SymBind(..) , localSymBind , globalSymBind@@ -161,51 +177,58 @@ , hiOsSymBind , loProcSymBind , hiProcSymBind+ -- ** Symbol visibility , SymVisi(..)- , unSymVisi+ , defSymVisi+ , intSymVisi+ , hiddenSymVisi+ , protSymVisi+ , exportSymVisi+ , singSymVisi+ , elimSymVisi+ -- ** Symbol table index , SymIx(..) , undefSymIx+ -- ** Symbol table entry , SymEnt(..) , SymEnt32+ , aSymEnt32 , SymEnt64- , symEnt32Size- , symEnt64Size- , buildSymEnt32- , buildSymEnt64+ , aSymEnt64 , zeroSymEnt+ -- * Relocation table+ -- ** Relocation type , RelType(..) , RelType32 , RelType64+ -- ** Relocation table entry , RelEnt(..) , RelEnt32+ , aRelEnt32 , RelEnt64+ , aRelEnt64 , RelaEnt(..) , RelaEnt32+ , aRelaEnt32 , RelaEnt64- , relaEnt32Size- , relaEnt64Size- , buildRelaEnt32- , buildRelaEnt64+ , aRelaEnt64 ) where import Data.Typeable (Typeable) import Data.Data (Data) import Data.Proxy (Proxy(..)) import Data.Ix (Ix)-import Data.Endian-import Data.Bits (Bits, shiftL, (.|.), FiniteBits)+import Data.Bits (Bits, shiftL, shiftR, (.|.), FiniteBits) import Data.Flags (Flags(noFlags), BoundedFlags) import Data.Word (Word8, Word16, Word32, Word64)-import Data.ShortWord (Word2, Word4, Word24)+import Data.ShortWord (Word4, Word24) import Data.Monoid ((<>))-import qualified Data.ByteString.Builder as BB-import Data.Binary (Binary)-import qualified Data.Binary as Bin-import qualified Data.Binary.Put as Bin-import qualified Data.Binary.Get as Bin-import Text.Ascii (ascii)+import Data.Serializer (Serializable, SizedSerializable)+import qualified Data.Serializer as S+import Data.Deserializer (Deserializable, (<?>))+import qualified Data.Deserializer as D import Control.Applicative ((<$>))-import Control.Monad (unless)+import Control.Monad (void, unless) -- | File class. newtype FileClass = FileClass { unFileClass ∷ Word8 }@@ -456,71 +479,41 @@ , idDataEnc ∷ DataEnc , idOsAbi ∷ OsAbi , idAbiVer ∷ AbiVer }- deriving (Typeable, Data)+ deriving (Typeable, Data, Show, Read, Eq) --- | Identification serialized size.-identSize ∷ Int-identSize = 16-{-# INLINE identSize #-}+-- | 'Ident' proxy value.+anIdent ∷ Proxy Ident+anIdent = Proxy -instance Binary Ident where- put (Ident {..}) = do- Bin.putWord8 0x7F- Bin.putWord8 (ascii 'E')- Bin.putWord8 (ascii 'L')- Bin.putWord8 (ascii 'F')- Bin.putWord8 (unFileClass idClass)- Bin.putWord8 (unDataEnc idDataEnc)- Bin.putWord8 (unVersion idVersion)- Bin.putWord8 (unOsAbi idOsAbi)- Bin.putWord8 (unAbiVer idAbiVer)- Bin.putWord8 0- Bin.putWord8 0- Bin.putWord8 0- Bin.putWord8 0- Bin.putWord8 0- Bin.putWord8 0- Bin.putWord8 0+instance Serializable Ident where+ put (Ident {..})+ = S.byteString "\127ELF"+ <> S.word8 (unFileClass idClass)+ <> S.word8 (unDataEnc idDataEnc)+ <> S.word8 (unVersion idVersion)+ <> S.word8 (unOsAbi idOsAbi)+ <> S.word8 (unAbiVer idAbiVer)+ <> S.byteString "\0\0\0\0\0\0\0"++instance SizedSerializable Ident where+ size _ = 16+ {-# INLINE size #-}++instance Deserializable Ident where get = do- b₀ ← Bin.getWord8- unless (b₀ == 0x7F) $ fail "Invalid ELF magic number"- b₁ ← Bin.getWord8- unless (b₁ == ascii 'E') $ fail "Invalid ELF magic number"- b₂ ← Bin.getWord8- unless (b₂ == ascii 'L') $ fail "Invalid ELF magic number"- b₃ ← Bin.getWord8- unless (b₃ == ascii 'F') $ fail "Invalid ELF magic number"- fileCls ← FileClass <$> Bin.getWord8- dataEnc ← DataEnc <$> Bin.getWord8- version ← Version <$> Bin.getWord8- osAbi ← OsAbi <$> Bin.getWord8- abiVer ← AbiVer <$> Bin.getWord8- Bin.skip 7+ void $ D.bytes "\127ELF" <?> "ELF magic number"+ fileCls ← FileClass <$> D.word8 <?> "file class"+ dataEnc ← DataEnc <$> D.word8 <?> "data encoding"+ version ← Version <$> D.word8 <?> "file version"+ osAbi ← OsAbi <$> D.word8 <?> "OS ABI code"+ abiVer ← AbiVer <$> D.word8 <?> "OS ABI version"+ D.skip 7 return $ Ident { idClass = fileCls , idDataEnc = dataEnc , idVersion = version , idOsAbi = osAbi , idAbiVer = abiVer } --- | Serialize identification via 'ByteString' builder.-buildIdent ∷ Ident → BB.Builder-buildIdent (Ident {..}) = BB.word8 0x7F- <> BB.word8 (ascii 'E')- <> BB.word8 (ascii 'L')- <> BB.word8 (ascii 'F')- <> BB.word8 (unFileClass idClass)- <> BB.word8 (unDataEnc idDataEnc)- <> BB.word8 (unVersion idVersion)- <> BB.word8 (unOsAbi idOsAbi)- <> BB.word8 (unAbiVer idAbiVer)- <> BB.word8 0- <> BB.word8 0- <> BB.word8 0- <> BB.word8 0- <> BB.word8 0- <> BB.word8 0- <> BB.word8 0- -- | File header. data FileHdr c = FileHdr { fhType ∷ FileType , fhMachine ∷ Machine@@ -534,65 +527,120 @@ deriving Typeable deriving instance (Data c, IsFileClass c) ⇒ Data (FileHdr c)+deriving instance IsFileClass c ⇒ Show (FileHdr c)+deriving instance IsFileClass c ⇒ Read (FileHdr c)+deriving instance IsFileClass c ⇒ Eq (FileHdr c) -- | ELF32 file header. type FileHdr32 = FileHdr Elf32 +-- | 'FileHdr32' proxy value.+aFileHdr32 ∷ Proxy FileHdr32+aFileHdr32 = Proxy++instance Serializable FileHdr32 where+ put (FileHdr {..}) + = S.word16 (unFileType fhType)+ <> S.word16 (unMachine fhMachine)+ <> S.word32 1+ <> S.word32 fhEntry+ <> S.word32 fhPhOff+ <> S.word32 fhShOff+ <> S.word32 (unMachFlags fhFlags)+ <> S.word16 (fromIntegral $ S.size anIdent + S.size aFileHdr32)+ <> S.word16 (fromIntegral $ S.size aProgHdr32)+ <> S.word16 fhPhNum+ <> S.word16 (fromIntegral $ S.size aSecHdr32)+ <> S.word16 fhShNum+ <> S.word16 (unSecIx fhSnStIx)++instance SizedSerializable FileHdr32 where+ size _ = 36+ {-# INLINE size #-}++instance Deserializable FileHdr32 where+ get = do+ fileType ← FileType <$> D.word16 <?> "file type"+ machine ← Machine <$> D.word16 <?> "machine"+ version ← D.word32 <?> "version"+ unless (version == 1) $ D.unexpected "Unexpected ELF version"+ entry ← D.word32 <?> "entry point address"+ phOff ← D.word32 <?> "program header table offset"+ shOff ← D.word32 <?> "section header table offset"+ flags ← MachFlags <$> D.word32 <?> "machine flags"+ fileHdrSize ← D.word16 <?> "file header size"+ unless (fileHdrSize ==+ fromIntegral (S.size anIdent + S.size aFileHdr32)) $+ D.unexpected "Unexpected ELF file header size"+ progHdrSize ← D.word16 <?> "program header size"+ unless (progHdrSize == fromIntegral (S.size aProgHdr32)) $+ D.unexpected "Unexpected ELF program header size"+ phNum ← D.word16 <?> "program header table size"+ secHdrSize ← D.word16 <?> "section header size"+ unless (secHdrSize == fromIntegral (S.size aSecHdr32)) $+ D.unexpected "Unexpected ELF section header size"+ shNum ← D.word16 <?> "section header table size"+ snStIx ← SecIx <$> D.word16 <?> "section name string table section index"+ return $ FileHdr { fhType = fileType+ , fhMachine = machine+ , fhEntry = entry+ , fhPhOff = phOff+ , fhShOff = shOff+ , fhFlags = flags+ , fhPhNum = phNum+ , fhShNum = shNum+ , fhSnStIx = snStIx }+ -- | ELF64 file header. type FileHdr64 = FileHdr Elf64 --- | ELF32 file header size.-fileHdr32Size ∷ Int-fileHdr32Size = 36+-- | 'FileHdr64' proxy value.+aFileHdr64 ∷ Proxy FileHdr64+aFileHdr64 = Proxy --- | ELF64 file header size.-fileHdr64Size ∷ Int-fileHdr64Size = 56+instance Serializable FileHdr64 where+ put (FileHdr {..})+ = S.word16 (unFileType fhType)+ <> S.word16 (unMachine fhMachine)+ <> S.word32 1+ <> S.word64 fhEntry+ <> S.word64 fhPhOff+ <> S.word64 fhShOff+ <> S.word32 (unMachFlags fhFlags)+ <> S.word16 (fromIntegral $ S.size anIdent + S.size aFileHdr64)+ <> S.word16 (fromIntegral $ S.size aProgHdr64)+ <> S.word16 fhPhNum+ <> S.word16 (fromIntegral $ S.size aSecHdr64)+ <> S.word16 fhShNum+ <> S.word16 (unSecIx fhSnStIx) --- | Serialize ELF32 file header via 'Bin.PutM' monad.-putFileHdr32 ∷ Endian → FileHdr32 → Bin.Put-putFileHdr32 endian (FileHdr {..}) = do- word16 (unFileType fhType)- word16 (unMachine fhMachine)- word32 1- word32 fhEntry- word32 fhPhOff- word32 fhShOff- word32 (unMachFlags fhFlags)- word16 (fromIntegral $ identSize + fileHdr32Size)- word16 (fromIntegral progHdr32Size)- word16 fhPhNum- word16 (fromIntegral secHdr32Size)- word16 fhShNum- word16 (unSecIx fhSnStIx)- where word16 | isLittleEndian endian = Bin.putWord16le- | otherwise = Bin.putWord16be- word32 | isLittleEndian endian = Bin.putWord32le- | otherwise = Bin.putWord32be+instance SizedSerializable FileHdr64 where+ size _ = 56+ {-# INLINE size #-} --- | Deserialize ELF32 file header via 'Bin.Get' monad.-getFileHdr32 ∷ Endian → Bin.Get FileHdr32-getFileHdr32 endian = do- fileType ← FileType <$> word16- machine ← Machine <$> word16- version ← word32- unless (version == 1) $ fail "Unexpected ELF version"- entry ← word32- phOff ← word32- shOff ← word32- flags ← MachFlags <$> word32- fileHdrSize ← word16- unless (fileHdrSize == fromIntegral (identSize + fileHdr32Size)) $- fail "Unexpected ELF file header size"- progHdrSize ← word16- unless (progHdrSize == fromIntegral progHdr32Size) $- fail "Unexpected ELF program header size"- phNum ← word16- secHdrSize ← word16- unless (secHdrSize == fromIntegral secHdr32Size) $- fail "Unexpected ELF section header size"- shNum ← word16- snStIx ← SecIx <$> word16+instance Deserializable FileHdr64 where+ get = do+ fileType ← FileType <$> D.word16 <?> "file type"+ machine ← Machine <$> D.word16 <?> "machine code"+ version ← D.word32 <?> "version"+ unless (version == 1) $ D.unexpected "Unexpected ELF version"+ entry ← D.word64 <?> "entry point address"+ phOff ← D.word64 <?> "program header table offset"+ shOff ← D.word64 <?> "section header table offset"+ flags ← MachFlags <$> D.word32 <?> "machine flags"+ fileHdrSize ← D.word16 <?> "file header size"+ unless (fileHdrSize ==+ fromIntegral (S.size anIdent + S.size aFileHdr64)) $+ D.unexpected "Unexpected ELF file header size"+ progHdrSize ← D.word16 <?> "program header size"+ unless (progHdrSize == fromIntegral (S.size aProgHdr64)) $+ D.unexpected "Unexpected ELF program header size"+ phNum ← D.word16 <?> "program header table size"+ secHdrSize ← D.word16 <?> "section header size"+ unless (secHdrSize == fromIntegral (S.size aSecHdr64)) $+ D.unexpected "Unexpected ELF section header size"+ shNum ← D.word16 <?> "section header table size"+ snStIx ← SecIx <$> D.word16 <?> "section name string table section index" return $ FileHdr { fhType = fileType , fhMachine = machine , fhEntry = entry@@ -602,50 +650,7 @@ , fhPhNum = phNum , fhShNum = shNum , fhSnStIx = snStIx }- where word16 | isLittleEndian endian = Bin.getWord16le- | otherwise = Bin.getWord16be- word32 | isLittleEndian endian = Bin.getWord32le- | otherwise = Bin.getWord32be --- | Serialize ELF32 file header via 'ByteString' builder.-buildFileHdr32 ∷ Endian → FileHdr32 → BB.Builder-buildFileHdr32 endian (FileHdr {..})- = word16 (unFileType fhType)- <> word16 (unMachine fhMachine)- <> word32 1- <> word32 fhEntry- <> word32 fhPhOff- <> word32 fhShOff- <> word32 (unMachFlags fhFlags)- <> word16 (fromIntegral $ identSize + fileHdr32Size)- <> word16 (fromIntegral progHdr32Size)- <> word16 fhPhNum- <> word16 (fromIntegral secHdr32Size)- <> word16 fhShNum- <> word16 (unSecIx fhSnStIx)- where word16 = if isLittleEndian endian then BB.word16LE else BB.word16BE- word32 = if isLittleEndian endian then BB.word32LE else BB.word32BE---- | Serialize ELF64 file header via 'ByteString' builder.-buildFileHdr64 ∷ Endian → FileHdr64 → BB.Builder-buildFileHdr64 endian (FileHdr {..})- = word16 (unFileType fhType)- <> word16 (unMachine fhMachine)- <> word32 1- <> word64 fhEntry- <> word64 fhPhOff- <> word64 fhShOff- <> word32 (unMachFlags fhFlags)- <> word16 (fromIntegral $ identSize + fileHdr64Size)- <> word16 (fromIntegral progHdr64Size)- <> word16 fhPhNum- <> word16 (fromIntegral secHdr64Size)- <> word16 fhShNum- <> word16 (unSecIx fhSnStIx)- where word16 = if isLittleEndian endian then BB.word16LE else BB.word16BE- word32 = if isLittleEndian endian then BB.word32LE else BB.word32BE- word64 = if isLittleEndian endian then BB.word64LE else BB.word64BE- -- | Segment type. newtype SegType = SegType { unSegType ∷ Word32 } deriving (Typeable, Data, Show, Read,@@ -732,46 +737,83 @@ deriving Typeable deriving instance (Data c, IsFileClass c) ⇒ Data (ProgHdr c)+deriving instance IsFileClass c ⇒ Show (ProgHdr c)+deriving instance IsFileClass c ⇒ Read (ProgHdr c)+deriving instance IsFileClass c ⇒ Eq (ProgHdr c) -- | ELF32 program header table entry. type ProgHdr32 = ProgHdr Elf32 +-- | 'ProgHdr32' proxy value.+aProgHdr32 ∷ Proxy ProgHdr32+aProgHdr32 = Proxy++instance Serializable ProgHdr32 where+ put (ProgHdr {..})+ = S.word32 (unSegType phType)+ <> S.word32 phOff+ <> S.word32 phVirtAddr+ <> S.word32 phPhysAddr+ <> S.word32 phFileSize+ <> S.word32 phMemSize+ <> S.word32 (unSegFlags phFlags)+ <> S.word32 phAlign++instance SizedSerializable ProgHdr32 where+ size _ = 32+ {-# INLINE size #-}++instance Deserializable ProgHdr32 where+ get = do+ segType ← SegType <$> D.word32 <?> "type"+ off ← D.word32 <?> "offset"+ virtAddr ← D.word32 <?> "virtual address"+ physAddr ← D.word32 <?> "physical address"+ fileSize ← D.word32 <?> "in-file size"+ memSize ← D.word32 <?> "in-memory size"+ flags ← SegFlags <$> D.word32 <?> "flags"+ align ← D.word32 <?> "alignment"+ return $ ProgHdr { phType = segType+ , phOff = off+ , phVirtAddr = virtAddr+ , phPhysAddr = physAddr+ , phFileSize = fileSize+ , phMemSize = memSize+ , phFlags = flags+ , phAlign = align }+ -- | ELF64 program header table entry. type ProgHdr64 = ProgHdr Elf64 --- | ELF32 program header table entry size.-progHdr32Size ∷ Int-progHdr32Size = 32+-- | 'ProgHdr64' proxy value.+aProgHdr64 ∷ Proxy ProgHdr64+aProgHdr64 = Proxy --- | ELF64 program header table entry size.-progHdr64Size ∷ Int-progHdr64Size = 56+instance Serializable ProgHdr64 where+ put (ProgHdr {..})+ = S.word32 (unSegType phType)+ <> S.word32 (unSegFlags phFlags)+ <> S.word64 phOff+ <> S.word64 phVirtAddr+ <> S.word64 phPhysAddr+ <> S.word64 phFileSize+ <> S.word64 phMemSize+ <> S.word64 phAlign --- | Serialize ELF32 program header via 'Bin.PutM' monad.-putProgHdr32 ∷ Endian → ProgHdr32 → Bin.Put-putProgHdr32 endian (ProgHdr {..}) = do- word32 (unSegType phType)- word32 phOff- word32 phVirtAddr- word32 phPhysAddr- word32 phFileSize- word32 phMemSize- word32 (unSegFlags phFlags)- word32 phAlign- where word32 | isLittleEndian endian = Bin.putWord32le- | otherwise = Bin.putWord32be+instance SizedSerializable ProgHdr64 where+ size _ = 56+ {-# INLINE size #-} --- | Deserialize ELF32 program header via 'Bin.Get' monad.-getProgHdr32 ∷ Endian → Bin.Get ProgHdr32-getProgHdr32 endian = do- segType ← SegType <$> word32- off ← word32- virtAddr ← word32- physAddr ← word32- fileSize ← word32- memSize ← word32- flags ← SegFlags <$> word32- align ← word32+instance Deserializable ProgHdr64 where+ get = do+ segType ← SegType <$> D.word32 <?> "type"+ flags ← SegFlags <$> D.word32 <?> "flags"+ off ← D.word64 <?> "offset"+ virtAddr ← D.word64 <?> "virtual address"+ physAddr ← D.word64 <?> "physical address"+ fileSize ← D.word64 <?> "in-file size"+ memSize ← D.word64 <?> "in-memory size"+ align ← D.word64 <?> "alignment" return $ ProgHdr { phType = segType , phOff = off , phVirtAddr = virtAddr@@ -780,36 +822,7 @@ , phMemSize = memSize , phFlags = flags , phAlign = align }- where word32 | isLittleEndian endian = Bin.getWord32le- | otherwise = Bin.getWord32be --- | Serialize ELF32 program header via 'ByteString' builder.-buildProgHdr32 ∷ Endian → ProgHdr32 → BB.Builder-buildProgHdr32 endian (ProgHdr {..})- = word32 (unSegType phType)- <> word32 phOff- <> word32 phVirtAddr- <> word32 phPhysAddr- <> word32 phFileSize- <> word32 phMemSize- <> word32 (unSegFlags phFlags)- <> word32 phAlign- where word32 = if isLittleEndian endian then BB.word32LE else BB.word32BE---- | Serialize ELF64 program header via 'ByteString' builder.-buildProgHdr64 ∷ Endian → ProgHdr64 → BB.Builder-buildProgHdr64 endian (ProgHdr {..})- = word32 (unSegType phType)- <> word32 (unSegFlags phFlags)- <> word64 phOff- <> word64 phVirtAddr- <> word64 phPhysAddr- <> word64 phFileSize- <> word64 phMemSize- <> word64 phAlign- where word32 = if isLittleEndian endian then BB.word32LE else BB.word32BE- word64 = if isLittleEndian endian then BB.word64LE else BB.word64BE- -- | String table index. type StrIx = Word32 @@ -972,51 +985,103 @@ deriving Typeable deriving instance (Data c, IsFileClass c) ⇒ Data (SecHdr c)+deriving instance IsFileClass c ⇒ Show (SecHdr c)+deriving instance IsFileClass c ⇒ Read (SecHdr c)+deriving instance IsFileClass c ⇒ Eq (SecHdr c) -- | ELF32 section header table entry. type SecHdr32 = SecHdr Elf32 +-- | 'SecHdr32' proxy value.+aSecHdr32 ∷ Proxy SecHdr32+aSecHdr32 = Proxy++instance Serializable SecHdr32 where+ put (SecHdr {..})+ = S.word32 shName+ <> S.word32 (unSecType shType)+ <> S.word32 (unSecFlags shFlags)+ <> S.word32 shAddr+ <> S.word32 shOff+ <> S.word32 shSize+ <> S.word32 shLink+ <> S.word32 shInfo+ <> S.word32 shAlign+ <> S.word32 shEntSize++instance SizedSerializable SecHdr32 where+ size _ = 40+ {-# INLINE size #-}++instance Deserializable SecHdr32 where+ get = do+ name ← D.word32 <?> "name"+ tp ← SecType <$> D.word32 <?> "type"+ flags ← SecFlags <$> D.word32 <?> "flags"+ addr ← D.word32 <?> "address"+ off ← D.word32 <?> "offset"+ size ← D.word32 <?> "size"+ link ← D.word32 <?> "link"+ info ← D.word32 <?> "extra information"+ align ← D.word32 <?> "alignment"+ entSize ← D.word32 <?> "entry size"+ return $ SecHdr { shName = name+ , shType = tp+ , shFlags = flags+ , shAddr = addr+ , shOff = off+ , shSize = size+ , shLink = link+ , shInfo = info+ , shAlign = align+ , shEntSize = entSize }+ -- | ELF64 section header table entry. type SecHdr64 = SecHdr Elf64 --- | ELF32 section header table entry size.-secHdr32Size ∷ Int-secHdr32Size = 40+-- | 'SecHdr64' proxy value.+aSecHdr64 ∷ Proxy SecHdr64+aSecHdr64 = Proxy --- | ELF64 section header table entry size.-secHdr64Size ∷ Int-secHdr64Size = 64+instance Serializable SecHdr64 where+ put (SecHdr {..})+ = S.word32 shName+ <> S.word32 (unSecType shType)+ <> S.word64 (fromIntegral (unSecFlags shFlags))+ <> S.word64 shAddr+ <> S.word64 shOff+ <> S.word64 shSize+ <> S.word32 shLink+ <> S.word32 shInfo+ <> S.word64 shAlign+ <> S.word64 shEntSize --- | Serialize ELF32 section header via 'ByteString' builder.-buildSecHdr32 ∷ Endian → SecHdr32 → BB.Builder-buildSecHdr32 endian (SecHdr {..})- = word32 shName- <> word32 (unSecType shType)- <> word32 (unSecFlags shFlags)- <> word32 shAddr- <> word32 shOff- <> word32 shSize- <> word32 shLink- <> word32 shInfo- <> word32 shAlign- <> word32 shEntSize- where word32 = if isLittleEndian endian then BB.word32LE else BB.word32BE+instance SizedSerializable SecHdr64 where+ size _ = 64+ {-# INLINE size #-} --- | Serialize ELF64 section header via 'ByteString' builder.-buildSecHdr64 ∷ Endian → SecHdr64 → BB.Builder-buildSecHdr64 endian (SecHdr {..})- = word32 shName- <> word32 (unSecType shType)- <> word64 (fromIntegral (unSecFlags shFlags))- <> word64 shAddr- <> word64 shOff- <> word64 shSize- <> word32 shLink- <> word32 shInfo- <> word64 shAlign- <> word64 shEntSize- where word32 = if isLittleEndian endian then BB.word32LE else BB.word32BE- word64 = if isLittleEndian endian then BB.word64LE else BB.word64BE+instance Deserializable SecHdr64 where+ get = do+ name ← D.word32 <?> "name"+ tp ← SecType <$> D.word32 <?> "type"+ flags ← SecFlags . fromIntegral <$> D.word64 <?> "flags"+ addr ← D.word64 <?> "address"+ off ← D.word64 <?> "offset"+ size ← D.word64 <?> "size"+ link ← D.word32 <?> "link"+ info ← D.word32 <?> "extra information"+ align ← D.word64 <?> "alignment"+ entSize ← D.word64 <?> "entry size"+ return $ SecHdr { shName = name+ , shType = tp+ , shFlags = flags+ , shAddr = addr+ , shOff = off+ , shSize = size+ , shLink = link+ , shInfo = info+ , shAlign = align+ , shEntSize = entSize } -- | Section header filled with zeros. zeroSecHdr ∷ IsFileClass c ⇒ SecHdr c@@ -1114,22 +1179,40 @@ hiProcSymBind = SymBind 15 -- | Symbol visibility.-data SymVisi = DefSymVisi -- ^ Default (specified by the binding type)- -- (@STV_DEFAULT@)- | IntSymVisi -- ^ Internal (processor-specific hidden type)- -- (@STV_INTERNAL@)- | HiddenSymVisi -- ^ Hidden (@STV_HIDDEN@)- | ProtSymVisi -- ^ Protected (@STV_PROTECTED@)- deriving (Typeable, Data, Show, Read,- Eq, Ord, Bounded, Enum, Ix)+newtype SymVisi = SymVisi { unSymVisi ∷ Word4 }+ deriving (Typeable, Data, Show, Read,+ Eq, Ord, Bounded, Enum, Ix) --- | Symbol visibility code.-unSymVisi ∷ SymVisi → Word2-unSymVisi DefSymVisi = 0-unSymVisi IntSymVisi = 1-unSymVisi HiddenSymVisi = 2-unSymVisi ProtSymVisi = 3+-- | Default symbol visibility (specified by the binding type;+-- @STV_DEFAULT@).+defSymVisi ∷ SymVisi+defSymVisi = SymVisi 0 +-- | Internal symbol visibility (processor-specific hidden type;+-- @STV_INTERNAL@).+intSymVisi ∷ SymVisi+intSymVisi = SymVisi 1++-- | Hidden symbol (@STV_HIDDEN@).+hiddenSymVisi ∷ SymVisi+hiddenSymVisi = SymVisi 2++-- | Protected symbol (@STV_PROTECTED@).+protSymVisi ∷ SymVisi+protSymVisi = SymVisi 3++-- | Global symbol (@STV_EXPORTED@).+exportSymVisi ∷ SymVisi+exportSymVisi = SymVisi 4++-- | Global singleton symbol (@STV_SINGLETON@).+singSymVisi ∷ SymVisi+singSymVisi = SymVisi 5++-- | Extra hidden symbol (@STV_ELIMINATE@).+elimSymVisi ∷ SymVisi+elimSymVisi = SymVisi 6+ -- | Symbol table index. newtype SymIx c = SymIx { unSymIx ∷ UnSymIx c } deriving Typeable@@ -1163,54 +1246,94 @@ deriving Typeable deriving instance (Data c, IsFileClass c) ⇒ Data (SymEnt c)+deriving instance IsFileClass c ⇒ Show (SymEnt c)+deriving instance IsFileClass c ⇒ Read (SymEnt c)+deriving instance IsFileClass c ⇒ Eq (SymEnt c) -- | ELF32 symbol table entry. type SymEnt32 = SymEnt Elf32 +-- | 'SymEnt32' proxy value.+aSymEnt32 ∷ Proxy SymEnt32+aSymEnt32 = Proxy++instance Serializable SymEnt32 where+ put (SymEnt {..})+ = S.word32 symName+ <> S.word32 symAddr+ <> S.word32 symSize+ <> S.word8 (shiftL (fromIntegral $ unSymBind symBind) 4 .|.+ fromIntegral (unSymType symType))+ <> S.word8 (fromIntegral (unSymVisi symVisi))+ <> S.word16 (unSecIx symSecIx)++instance SizedSerializable SymEnt32 where+ size _ = 16+ {-# INLINE size #-}++instance Deserializable SymEnt32 where+ get = do+ name ← D.word32 <?> "name"+ addr ← D.word32 <?> "address"+ size ← D.word32 <?> "size"+ info ← D.word8 <?> "info"+ let bind = SymBind (fromIntegral $ shiftR info 4)+ tp = SymType (fromIntegral info)+ visi ← SymVisi . fromIntegral <$> D.word8 <?> "visibility"+ secIx ← SecIx <$> D.word16 <?> "section index"+ return $ SymEnt { symName = name+ , symAddr = addr+ , symSize = size+ , symBind = bind+ , symType = tp+ , symVisi = visi+ , symSecIx = secIx }+ -- | ELF64 symbol table entry. type SymEnt64 = SymEnt Elf64 --- | ELF32 symbol table entry size.-symEnt32Size ∷ Int-symEnt32Size = 16+-- | 'SymEnt64' proxy value.+aSymEnt64 ∷ Proxy SymEnt64+aSymEnt64 = Proxy --- | ELF64 symbol table entry size.-symEnt64Size ∷ Int-symEnt64Size = 24+instance Serializable SymEnt64 where+ put (SymEnt {..})+ = S.word32 symName+ <> S.word8 (shiftL (fromIntegral $ unSymBind symBind) 4 .|.+ fromIntegral (unSymType symType))+ <> S.word8 (fromIntegral (unSymVisi symVisi))+ <> S.word16 (unSecIx symSecIx)+ <> S.word64 symAddr+ <> S.word64 symSize --- | Serialize ELF32 symbol table entry via 'ByteString' builder.-buildSymEnt32 ∷ Endian → SymEnt32 → BB.Builder-buildSymEnt32 endian (SymEnt {..})- = word32 symName- <> word32 symAddr- <> word32 symSize- <> BB.word8 (shiftL (fromIntegral $ unSymBind symBind) 4 .|.- fromIntegral (unSymType symType))- <> BB.word8 (fromIntegral (unSymVisi symVisi))- <> word16 (unSecIx symSecIx)- where word16 = if isLittleEndian endian then BB.word16LE else BB.word16BE- word32 = if isLittleEndian endian then BB.word32LE else BB.word32BE+instance SizedSerializable SymEnt64 where+ size _ = 24+ {-# INLINE size #-} --- | Serialize ELF64 symbol table entry via 'ByteString' builder.-buildSymEnt64 ∷ Endian → SymEnt64 → BB.Builder-buildSymEnt64 endian (SymEnt {..})- = word32 symName- <> BB.word8 (shiftL (fromIntegral $ unSymBind symBind) 4 .|.- fromIntegral (unSymType symType))- <> BB.word8 (fromIntegral $ unSymVisi symVisi)- <> word16 (unSecIx symSecIx)- <> word64 symAddr- <> word64 symSize- where word16 = if isLittleEndian endian then BB.word16LE else BB.word16BE- word32 = if isLittleEndian endian then BB.word32LE else BB.word32BE- word64 = if isLittleEndian endian then BB.word64LE else BB.word64BE+instance Deserializable SymEnt64 where+ get = do+ name ← D.word32 <?> "name"+ info ← D.word8 <?> "info"+ let bind = SymBind (fromIntegral $ shiftR info 4)+ tp = SymType (fromIntegral info)+ visi ← SymVisi . fromIntegral <$> D.word8 <?> "visibility"+ secIx ← SecIx <$> D.word16 <?> "section index"+ addr ← D.word64 <?> "address"+ size ← D.word64 <?> "size"+ return $ SymEnt { symName = name+ , symAddr = addr+ , symSize = size+ , symBind = bind+ , symType = tp+ , symVisi = visi+ , symSecIx = secIx } -- | Symbol table entry filled with zeros. zeroSymEnt ∷ IsFileClass c ⇒ SymEnt c zeroSymEnt = SymEnt { symName = 0 , symBind = localSymBind , symType = undefSymType- , symVisi = DefSymVisi+ , symVisi = defSymVisi , symSecIx = undefSecIx , symAddr = 0 , symSize = 0 }@@ -1248,9 +1371,57 @@ -- | ELF32 relocation table entry (REL). type RelEnt32 = RelEnt Elf32 +-- | 'RelEnt32' proxy value.+aRelEnt32 ∷ Proxy RelEnt32+aRelEnt32 = Proxy++instance Serializable RelEnt32 where+ put (RelEnt {..})+ = S.word32 relOff+ <> S.word32 (shiftL (fromIntegral relSymIx) 8 .|.+ fromIntegral (unRelType relType))++instance SizedSerializable RelEnt32 where+ size _ = 8+ {-# INLINE size #-}++instance Deserializable RelEnt32 where+ get = do+ off ← D.word32 <?> "offset"+ info ← D.word32 <?> "info"+ let symIx = SymIx $ fromIntegral $ shiftR info 8+ tp = RelType $ fromIntegral info+ return $ RelEnt { relOff = off+ , relSymIx = symIx+ , relType = tp }+ -- | ELF64 relocation table entry (REL). type RelEnt64 = RelEnt Elf64 +-- | 'RelEnt64' proxy value.+aRelEnt64 ∷ Proxy RelEnt64+aRelEnt64 = Proxy++instance Serializable RelEnt64 where+ put (RelEnt {..})+ = S.word64 relOff+ <> S.word64 (shiftL (fromIntegral relSymIx) 32 .|.+ fromIntegral (unRelType relType))++instance SizedSerializable RelEnt64 where+ size _ = 16+ {-# INLINE size #-}++instance Deserializable RelEnt64 where+ get = do+ off ← D.word64 <?> "offset"+ info ← D.word64 <?> "info"+ let symIx = SymIx $ fromIntegral $ shiftR info 32+ tp = RelType $ fromIntegral info+ return $ RelEnt { relOff = off+ , relSymIx = symIx+ , relType = tp }+ -- | Relocation table entry (RELA). data RelaEnt c = RelaEnt { relaOff ∷ Addr c , relaSymIx ∷ SymIx c@@ -1258,41 +1429,67 @@ , relaAddend ∷ Addr c } deriving Typeable +deriving instance (Data c, IsFileClass c) ⇒ Data (RelaEnt c)+deriving instance IsFileClass c ⇒ Show (RelaEnt c)+deriving instance IsFileClass c ⇒ Read (RelaEnt c)+deriving instance IsFileClass c ⇒ Eq (RelaEnt c)+ -- | ELF32 relocation table entry (RELA). type RelaEnt32 = RelaEnt Elf32 +-- | 'RelaEnt32' proxy value.+aRelaEnt32 ∷ Proxy RelaEnt32+aRelaEnt32 = Proxy++instance Serializable RelaEnt32 where+ put (RelaEnt {..})+ = S.word32 relaOff+ <> S.word32 (shiftL (fromIntegral relaSymIx) 8 .|.+ fromIntegral (unRelType relaType))+ <> S.word32 relaAddend++instance SizedSerializable RelaEnt32 where+ size _ = 12+ {-# INLINE size #-}++instance Deserializable RelaEnt32 where+ get = do+ off ← D.word32 <?> "offset"+ info ← D.word32 <?> "info"+ let symIx = SymIx $ fromIntegral $ shiftR info 8+ tp = RelType $ fromIntegral info+ addend ← D.word32 <?> "addend"+ return $ RelaEnt { relaOff = off+ , relaSymIx = symIx+ , relaType = tp+ , relaAddend = addend }+ -- | ELF64 relocation table entry (RELA). type RelaEnt64 = RelaEnt Elf64 -deriving instance (Data c, IsFileClass c) ⇒ Data (RelaEnt c)-deriving instance IsFileClass c ⇒ Show (RelaEnt c)-deriving instance IsFileClass c ⇒ Read (RelaEnt c)-deriving instance IsFileClass c ⇒ Eq (RelaEnt c)---- | ELF32 relocation table entry (RELA) size.-relaEnt32Size ∷ Int-relaEnt32Size = 12+-- | 'RelaEnt64' proxy value.+aRelaEnt64 ∷ Proxy RelaEnt64+aRelaEnt64 = Proxy --- | ELF64 relocation table entry (RELA) size.-relaEnt64Size ∷ Int-relaEnt64Size = 24+instance Serializable RelaEnt64 where+ put (RelaEnt {..})+ = S.word64 relaOff+ <> S.word64 (shiftL (fromIntegral relaSymIx) 32 .|.+ fromIntegral (unRelType relaType))+ <> S.word64 relaAddend --- | Serialize ELF32 relocation table entry (RELA) via 'ByteString'--- builder.-buildRelaEnt32 ∷ Endian → RelaEnt32 → BB.Builder-buildRelaEnt32 endian (RelaEnt {..})- = word32 relaOff- <> word32 (shiftL (fromIntegral relaSymIx) 8 .|.- fromIntegral (unRelType relaType))- <> word32 relaAddend- where word32 = if isLittleEndian endian then BB.word32LE else BB.word32BE+instance SizedSerializable RelaEnt64 where+ size _ = 24+ {-# INLINE size #-} --- | Serialize ELF64 relocation table entry (RELA) via 'ByteString'--- builder.-buildRelaEnt64 ∷ Endian → RelaEnt64 → BB.Builder-buildRelaEnt64 endian (RelaEnt {..})- = word64 relaOff- <> word64 (shiftL (fromIntegral relaSymIx) 32 .|.- fromIntegral (unRelType relaType))- <> word64 relaAddend- where word64 = if isLittleEndian endian then BB.word64LE else BB.word64BE+instance Deserializable RelaEnt64 where+ get = do+ off ← D.word64 <?> "offset"+ info ← D.word64 <?> "info"+ let symIx = SymIx $ fromIntegral $ shiftR info 32+ tp = RelType $ fromIntegral info+ addend ← D.word64 <?> "addend"+ return $ RelaEnt { relaOff = off+ , relaSymIx = symIx+ , relaType = tp+ , relaAddend = addend }