packages feed

data-elf (empty) → 0.1

raw patch · 5 files changed

+1377/−0 lines, 5 filesdep +basedep +binarydep +bytestringsetup-changed

Dependencies added: base, binary, bytestring, data-endian, data-flags, data-sword, text-latin1

Files

+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) 2014-2016 Mikhail Vorozhtsov+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++- Redistributions of source code must retain the above copyright notice,+  this list of conditions and the following disclaimer.+- Redistributions in binary form must reproduce the above copyright+  notice, this list of conditions and the following disclaimer in the+  documentation and/or other materials provided with the distribution.+- Neither the names of the copyright owners nor the names of the+  contributors may be used to endorse or promote products derived+  from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+
+ README.md view
@@ -0,0 +1,10 @@+Data-Elf+========+This package provides Executable and Linkable Format (ELF) data structures.++Installation+------------+The usual:++	$ cabal install+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ data-elf.cabal view
@@ -0,0 +1,40 @@+Name: data-elf+Version: 0.1+Category: Data+Stability: experimental+Synopsis: Executable and Linkable Format (ELF) data structures.+Description:+  This package provides Executable and Linkable Format (ELF) data structures.++Homepage: https://github.com/mvv/data-elf+Bug-Reports: https://github.com/mvv/data-elf/issues++Author: Mikhail Vorozhtsov <mikhail.vorozhtsov@gmail.com>+Maintainer: Mikhail Vorozhtsov <mikhail.vorozhtsov@gmail.com>+Copyright: 2014-2016 Mikhail Vorozhtsov <mikhail.vorozhtsov@gmail.com>+License: BSD3+License-File: LICENSE++Extra-Source-Files:+  README.md++Cabal-Version: >= 1.10.0+Build-Type: Simple++Source-Repository head+  Type: git+  Location: https://github.com/mvv/data-elf.git++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+  Hs-Source-Dirs: src+  GHC-Options: -Wall+  Exposed-Modules:+    Data.Elf
+ src/Data/Elf.hs view
@@ -0,0 +1,1298 @@+{-# LANGUAGE UnicodeSyntax #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TypeFamilies #-}++-- | This module provides ELF data structures and (de)serialization routines.+module Data.Elf+  ( FileClass(..)+  , invalidFileClass+  , elf32FileClass+  , elf64FileClass+  , IsFileClass(..)+  , Elf32(..)+  , anElf32+  , Elf64(..)+  , anElf64+  , FileType(..)+  , noneFileType+  , relFileType+  , execFileType+  , dynFileType+  , coreFileType+  , loOsFileType+  , hiOsFileType+  , loProcFileType+  , hiProcFileType+  , Machine(..)+  , undefMachine+  , i386Machine+  , amd64Machine+  , MachFlags(..)+  , Version(..)+  , invalidVersion+  , firstVersion+  , DataEnc(..)+  , invalidDataEnc+  , lsbDataEnc+  , msbDataEnc+  , OsAbi(..)+  , sysvOsAbi+  , hpuxOsAbi+  , netBsdOsAbi+  , gnuOsAbi+  , solarisOsAbi+  , aixOsAbi+  , irixOsAbi+  , freeBsdOsAbi+  , tru64OsAbi+  , modestoOsAbi+  , openBsdOsAbi+  , openVmsOsAbi+  , nskOsAbi+  , arosOsAbi+  , fenixOsAbi+  , embedOsAbi+  , AbiVer(..)+  , undefAbiVer+  , Ident(..)+  , identSize+  , buildIdent+  , FileHdr(..)+  , FileHdr32+  , FileHdr64+  , fileHdr32Size+  , fileHdr64Size+  , putFileHdr32+  , getFileHdr32+  , buildFileHdr32+  , buildFileHdr64+  , SegType(..)+  , unusedSegType+  , loadSegType+  , dynSegType+  , interpSegType+  , noteSegType+  , shlibSegType+  , phdrSegType+  , loOsSegType+  , hiOsSegType+  , loProcSegType+  , hiProcSegType+  , SegFlags(..)+  , execSegFlag+  , writeSegFlag+  , readSegFlag+  , osSegFlags+  , procSegFlags+  , ProgHdr(..)+  , ProgHdr32+  , ProgHdr64+  , progHdr32Size+  , progHdr64Size+  , putProgHdr32+  , getProgHdr32+  , buildProgHdr32+  , buildProgHdr64+  , StrIx+  , SecIx(..)+  , undefSecIx+  , lastSecIx+  , loOsSecIx+  , hiOsSecIx+  , loProcSecIx+  , hiProcSecIx+  , absSecIx+  , commonSecIx+  , xIndexSecIx+  , SecType(..)+  , unusedSecType+  , progBitsSecType+  , symSecType+  , strSecType+  , relaSecType+  , hashSecType+  , dynSecType+  , noteSecType+  , noBitsSecType+  , relSecType+  , shlibSecType+  , dynSymSecType+  , loOsSecType+  , hiOsSecType+  , loProcSecType+  , hiProcSecType+  , SecFlags(..)+  , writeSecFlag+  , allocSecFlag+  , execSecFlag+  , mergeSecFlag+  , infoLinkSecFlag+  , osSecFlags+  , procSecFlags+  , SecHdr(..)+  , SecHdr32+  , SecHdr64+  , secHdr32Size+  , secHdr64Size+  , buildSecHdr32+  , buildSecHdr64+  , zeroSecHdr+  , SymType(..)+  , undefSymType+  , objSymType+  , funSymType+  , secSymType+  , fileSymType+  , commonSymType+  , tlsSymType+  , loOsSymType+  , hiOsSymType+  , loProcSymType+  , hiProcSymType+  , SymBind(..)+  , localSymBind+  , globalSymBind+  , weakSymBind+  , loOsSymBind+  , hiOsSymBind+  , loProcSymBind+  , hiProcSymBind+  , SymVisi(..)+  , unSymVisi+  , SymIx(..)+  , undefSymIx+  , SymEnt(..)+  , SymEnt32+  , SymEnt64+  , symEnt32Size+  , symEnt64Size+  , buildSymEnt32+  , buildSymEnt64+  , zeroSymEnt+  , RelType(..)+  , RelType32+  , RelType64+  , RelEnt(..)+  , RelEnt32+  , RelEnt64+  , RelaEnt(..)+  , RelaEnt32+  , RelaEnt64+  , relaEnt32Size+  , relaEnt64Size+  , buildRelaEnt32+  , buildRelaEnt64+  ) 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.Flags (Flags(noFlags), BoundedFlags)+import Data.Word (Word8, Word16, Word32, Word64)+import Data.ShortWord (Word2, 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 Control.Applicative ((<$>))+import Control.Monad (unless)++-- | File class.+newtype FileClass = FileClass { unFileClass ∷ Word8 }+                    deriving (Typeable, Data, Show, Read,+                              Eq, Ord, Bounded, Enum, Ix)++-- | Invalid class (@ELFCLASSNONE@).+invalidFileClass ∷ FileClass+invalidFileClass = FileClass 0++-- | ELF32 class (@ELFCLASS32@).+elf32FileClass ∷ FileClass+elf32FileClass = FileClass 1++-- | ELF64 class (@ELFCLASS64@).+elf64FileClass ∷ FileClass+elf64FileClass = FileClass 2++-- | File class type-level index.+class (Typeable c,+       Typeable (Addr c), Data (Addr c),+       Typeable (Off c), Data (Off c),+       Typeable (UnSymIx c), Data (UnSymIx c),+       Typeable (UnRelType c), Data (UnRelType c),+       Show (Addr c), Read (Addr c),+       Show (Off c), Read (Off c),+       Show (UnSymIx c), Read (UnSymIx c),+       Show (UnRelType c), Read (UnRelType c),+       Eq (Addr c), Ord (Addr c), Bounded (Addr c), Enum (Addr c),+       Num (Addr c), Integral (Addr c), Real (Addr c),+       Bits (Addr c), FiniteBits (Addr c),+       Eq (Off c), Ord (Off c), Bounded (Off c), Enum (Off c),+       Num (Off c), Integral (Off c), Real (Off c),+       Bits (Off c), FiniteBits (Off c),+       Eq (UnSymIx c), Ord (UnSymIx c), Bounded (UnSymIx c), Enum (UnSymIx c),+       Ix (UnSymIx c), Num (UnSymIx c), Integral (UnSymIx c),+       Real (UnSymIx c), Bits (UnSymIx c), FiniteBits (UnSymIx c),+       Eq (UnRelType c), Ord (UnRelType c), Bounded (UnRelType c),+       Enum (UnRelType c), Ix (UnRelType c))+      ⇒ IsFileClass c where+  type Addr c+  type Off c+  type UnSymIx c+  type UnRelType c+  fileClass ∷ Proxy c → FileClass++-- | 32-bit ELF class type-level index.+data Elf32 = Elf32 deriving (Typeable, Data)++-- | 'Elf32' proxy value.+anElf32 ∷ Proxy Elf32+anElf32 = Proxy++instance IsFileClass Elf32 where+  type Addr Elf32 = Word32+  type Off Elf32 = Word32+  type UnSymIx Elf32 = Word24+  type UnRelType Elf32 = Word8+  fileClass _ = elf32FileClass++-- | 64-bit ELF class type-level index.+data Elf64 = Elf64 deriving (Typeable, Data)++-- | 'Elf64' proxy value.+anElf64 ∷ Proxy Elf64+anElf64 = Proxy++instance IsFileClass Elf64 where+  type Addr Elf64 = Word64+  type Off Elf64 = Word64+  type UnSymIx Elf64 = Word32+  type UnRelType Elf64 = Word32+  fileClass _ = elf64FileClass++-- | File type.+newtype FileType = FileType { unFileType ∷ Word16 }+                   deriving (Typeable, Data, Show, Read,+                             Eq, Ord, Bounded, Enum, Ix)++-- | No file type (@ET_NONE@).+noneFileType ∷ FileType+noneFileType = FileType 0++-- | Relocatable object file (@ET_REL@).+relFileType ∷ FileType+relFileType = FileType 1++-- | Executable file (@ET_EXEC@).+execFileType ∷ FileType+execFileType = FileType 2++-- | Shared object file (@ET_DYN@).+dynFileType ∷ FileType+dynFileType = FileType 3++-- | Core file (@ET_CORE@).+coreFileType ∷ FileType+coreFileType = FileType 4++-- | First environment-specific type (@ET_LOOS@).+loOsFileType ∷ FileType+loOsFileType = FileType 0xFE00++-- | Last environment-specific type (@ET_HIOS@).+hiOsFileType ∷ FileType+hiOsFileType = FileType 0xFEFF++-- | First processor-specific type (@ET_LOPROC@).+loProcFileType ∷ FileType+loProcFileType = FileType 0xFF00++-- | Last processor-specific type (@ET_HIPROC@).+hiProcFileType ∷ FileType+hiProcFileType = FileType 0xFFFF++-- | Machine architecture.+newtype Machine = Machine { unMachine ∷ Word16 }+                  deriving (Typeable, Data, Show, Read,+                            Eq, Ord, Bounded, Enum, Ix)++-- | No machine (@EM_NONE@).+undefMachine ∷ Machine+undefMachine = Machine 0++-- | Intel 80386 (@EM_386@).+i386Machine ∷ Machine+i386Machine = Machine 3++-- | AMD x86-64 (@EM_X86_64@).+amd64Machine ∷ Machine+amd64Machine = Machine 62++-- | Architecture-specific flags.+newtype MachFlags = MachFlags { unMachFlags ∷ Word32 }+                    deriving (Typeable, Data, Show, Read,+                              Eq, Flags, BoundedFlags)++-- | ELF version.+newtype Version = Version { unVersion ∷ Word8 }+                  deriving (Typeable, Data, Show, Read,+                            Eq, Ord, Bounded, Enum, Ix)+-- | Invalid version.+invalidVersion ∷ Version+invalidVersion = Version 0++-- | Version 1.+firstVersion ∷ Version+firstVersion = Version 1++-- | Data encoding.+newtype DataEnc = DataEnc { unDataEnc ∷ Word8 }+                  deriving (Typeable, Data, Show, Read,+                            Eq, Ord, Bounded, Enum, Ix)++-- | Invalid data encoding.+invalidDataEnc ∷ DataEnc+invalidDataEnc = DataEnc 0++-- | Little-endian data encoding (@ELFDATA2LSB@).+lsbDataEnc ∷ DataEnc+lsbDataEnc = DataEnc 1++-- | Big-endian data encoding (@ELFDATA2MSB@).+msbDataEnc ∷ DataEnc+msbDataEnc = DataEnc 1++-- | System ABI.+newtype OsAbi = OsAbi { unOsAbi ∷ Word8 }+                deriving (Typeable, Data, Show, Read,+                          Eq, Ord, Bounded, Enum, Ix)++-- | System V (@ELFOSABI_NONE@).+sysvOsAbi ∷ OsAbi+sysvOsAbi = OsAbi 0++-- | HP-UX (@ELFOSABI_HPUX@).+hpuxOsAbi ∷ OsAbi+hpuxOsAbi = OsAbi 1++-- | NetBSD (@ELFOSABI_NETBSD@).+netBsdOsAbi ∷ OsAbi+netBsdOsAbi = OsAbi 2++-- | GNU (@ELFOSABI_GNU@, @ELFOSABI_LINUX@).+gnuOsAbi ∷ OsAbi+gnuOsAbi = OsAbi 3++-- | Solaris (@ELFOSABI_SOLARIS@).+solarisOsAbi ∷ OsAbi+solarisOsAbi = OsAbi 6++-- | AIX (@ELFOSABI_AIX@).+aixOsAbi ∷ OsAbi+aixOsAbi = OsAbi 7++-- | IRIX (@ELFOSABI_IRIX@).+irixOsAbi ∷ OsAbi+irixOsAbi = OsAbi 8++-- | FreeBSD (@ELFOSABI_FREEBSD@).+freeBsdOsAbi ∷ OsAbi+freeBsdOsAbi = OsAbi 9++-- | Tru64 UNIX (@ELFOSABI_TRU64@).+tru64OsAbi ∷ OsAbi+tru64OsAbi = OsAbi 10++-- | Novell Modesto (@ELFOSABI_MODESTO@).+modestoOsAbi ∷ OsAbi+modestoOsAbi = OsAbi 11++-- | OpenBSD (@ELFOSABI_OPENBSD@).+openBsdOsAbi ∷ OsAbi+openBsdOsAbi = OsAbi 12++-- | OpenVMS (@ELFOSABI_OPENVMS@).+openVmsOsAbi ∷ OsAbi+openVmsOsAbi = OsAbi 13++-- | Hewlett-Packard Non-Stop Kernel (@ELFOSABI_NSK@).+nskOsAbi ∷ OsAbi+nskOsAbi = OsAbi 14++-- | Amiga Research OS (@ELFOSABI_AROS@).+arosOsAbi ∷ OsAbi+arosOsAbi = OsAbi 15++-- | FenixOS (@ELFOSABI_FENIXOS@).+fenixOsAbi ∷ OsAbi+fenixOsAbi = OsAbi 16++-- | Standalone (embedded) application.+embedOsAbi ∷ OsAbi+embedOsAbi = OsAbi 255++-- | ABI version.+newtype AbiVer = AbiVer { unAbiVer ∷ Word8 }+                 deriving (Typeable, Data, Show, Read,+                           Eq, Ord, Bounded, Enum, Ix)++-- | Undefined ABI version.+undefAbiVer ∷ AbiVer+undefAbiVer = AbiVer 0++-- | Identification.+data Ident = Ident { idClass   ∷ FileClass+                   , idVersion ∷ Version+                   , idDataEnc ∷ DataEnc+                   , idOsAbi   ∷ OsAbi+                   , idAbiVer  ∷ AbiVer }+             deriving (Typeable, Data)++-- | Identification serialized size.+identSize ∷ Int+identSize = 16+{-# INLINE identSize #-}++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+  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+    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+                         , fhEntry   ∷ Addr c+                         , fhFlags   ∷ MachFlags+                         , fhPhOff   ∷ Off c+                         , fhPhNum   ∷ Word16+                         , fhShOff   ∷ Off c+                         , fhShNum   ∷ Word16+                         , fhSnStIx  ∷ SecIx }+                 deriving Typeable++deriving instance (Data c, IsFileClass c) ⇒ Data (FileHdr c)++-- | ELF32 file header.+type FileHdr32 = FileHdr Elf32++-- | ELF64 file header.+type FileHdr64 = FileHdr Elf64++-- | ELF32 file header size.+fileHdr32Size ∷ Int+fileHdr32Size = 36++-- | ELF64 file header size.+fileHdr64Size ∷ Int+fileHdr64Size = 56++-- | 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++-- | 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+    return $ FileHdr { fhType    = fileType+                     , fhMachine = machine+                     , fhEntry   = entry+                     , fhPhOff   = phOff+                     , fhShOff   = shOff+                     , fhFlags   = flags+                     , 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,+                            Eq, Ord, Bounded, Enum, Ix)++-- | Unused program header entry (@PT_NULL@).+unusedSegType ∷ SegType+unusedSegType = SegType 0++-- | Loadable segment (@PT_LOAD@).+loadSegType ∷ SegType+loadSegType = SegType 1++-- | Dynamic linking tables (@PT_DYNAMIC@).+dynSegType ∷ SegType+dynSegType = SegType 2++-- | Program interpreter path name (@PT_INTERP@).+interpSegType ∷ SegType+interpSegType = SegType 3++-- | Note sections (@PT_NOTE@).+noteSegType ∷ SegType+noteSegType = SegType 4++-- | A reserved segment type (@PT_SHLIB@).+shlibSegType ∷ SegType+shlibSegType = SegType 5++-- | Program header table (@PT_PHDR@).+phdrSegType ∷ SegType+phdrSegType = SegType 6++-- | First environment-specific segment type (@PT_LOOS@).+loOsSegType ∷ SegType+loOsSegType = SegType 0x60000000++-- | Last environment-specific segment type (@PT_HIOS@).+hiOsSegType ∷ SegType+hiOsSegType = SegType 0x6FFFFFFF++-- | First processor-specific segment type (@PT_LOPROC@).+loProcSegType ∷ SegType+loProcSegType = SegType 0x70000000++-- | Last processor-specific segment type (@PT_HIPROC@).+hiProcSegType ∷ SegType+hiProcSegType = SegType 0x7FFFFFFF++-- | Segment flags.+newtype SegFlags = SegFlags { unSegFlags ∷ Word32 }+                   deriving (Typeable, Data, Show, Read,+                             Eq, Flags, BoundedFlags)++-- | Execute permission (@PF_X@).+execSegFlag ∷ SegFlags+execSegFlag = SegFlags 1++-- | Write permission (@PF_W@).+writeSegFlag ∷ SegFlags+writeSegFlag = SegFlags 2++-- | Read permission (@PF_R@).+readSegFlag ∷ SegFlags+readSegFlag = SegFlags 4++-- | Environment-specific flags mask (@PF_MASKOS@).+osSegFlags ∷ SegFlags+osSegFlags = SegFlags 0x00FF0000++-- | Processor-specific flags mask (@PF_MASKPROC@).+procSegFlags ∷ SegFlags+procSegFlags = SegFlags 0xFF000000++-- | Program header table entry.+data ProgHdr c = ProgHdr { phType     ∷ SegType+                         , phFlags    ∷ SegFlags+                         , phOff      ∷ Off c+                         , phVirtAddr ∷ Addr c+                         , phPhysAddr ∷ Addr c+                         , phFileSize ∷ Off c+                         , phMemSize  ∷ Addr c+                         , phAlign    ∷ Addr c }+                 deriving Typeable++deriving instance (Data c, IsFileClass c) ⇒ Data (ProgHdr c)++-- | ELF32 program header table entry.+type ProgHdr32 = ProgHdr Elf32++-- | ELF64 program header table entry.+type ProgHdr64 = ProgHdr Elf64++-- | ELF32 program header table entry size.+progHdr32Size ∷ Int+progHdr32Size = 32++-- | ELF64 program header table entry size.+progHdr64Size ∷ Int+progHdr64Size = 56++-- | 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++-- | 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+    return $ ProgHdr { phType = segType+                     , phOff  = off+                     , phVirtAddr = virtAddr+                     , phPhysAddr = physAddr+                     , phFileSize = fileSize+                     , 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++-- | Section header entry index.+newtype SecIx = SecIx { unSecIx ∷ Word16 }+                deriving (Typeable, Data, Show, Read,+                          Eq, Ord, Bounded, Enum, Ix, Num, Bits, FiniteBits,+                          Integral, Real)++-- | Undefined section reference (@SHN_UNDEF@).+undefSecIx ∷ SecIx+undefSecIx = 0++-- | Last regular section index.+lastSecIx ∷ SecIx+lastSecIx = 0xFEFF++-- | First environment-specific section index (@SHN_LOOS@).+loOsSecIx ∷ SecIx+loOsSecIx = 0xFF20++-- | Last environment-specific section index (@SHN_HIOS@).+hiOsSecIx ∷ SecIx+hiOsSecIx = 0xFF3F++-- | First processor-specific section index (@SHN_LOPROC@).+loProcSecIx ∷ SecIx+loProcSecIx = 0xFF00++-- | Last processor-specific section index (@SHN_HIPROC@).+hiProcSecIx ∷ SecIx+hiProcSecIx = 0xFF1F++-- | Absolute value indicator (@SHN_ABS@).+absSecIx ∷ SecIx+absSecIx = 0xFFF1++-- | Common block indicator (@SHN_COMMON@).+commonSecIx ∷ SecIx+commonSecIx = 0xFFF2++-- | Escape value (@SHN_XINDEX@).+xIndexSecIx ∷ SecIx+xIndexSecIx = 0xFFFF++-- | Section type.+newtype SecType = SecType { unSecType ∷ Word32 }+                  deriving (Typeable, Data, Show, Read,+                            Eq, Ord, Bounded, Enum, Ix)++-- | Unused section (@SHT_NULL@).+unusedSecType ∷ SecType+unusedSecType = SecType 0++-- | Program information (@SHT_PROGBITS@).+progBitsSecType ∷ SecType+progBitsSecType = SecType 1++-- | Symbol table (@SHT_SYMTAB@).+symSecType ∷ SecType+symSecType = SecType 2++-- | String table (@SHT_STRTAB@).+strSecType ∷ SecType+strSecType = SecType 3++-- | Relocation entries (@SHT_RELA@).+relaSecType ∷ SecType+relaSecType = SecType 4++-- | Symbol hash table (@SHT_HASH@).+hashSecType ∷ SecType+hashSecType = SecType 5++-- | Dynamic linking table (@SHT_DYNAMIC@).+dynSecType ∷ SecType+dynSecType = SecType 6++-- | Note information (@SHT_NOTE@).+noteSecType ∷ SecType+noteSecType = SecType 7++-- | Uninitialized space (@SHT_NOBITS@).+noBitsSecType ∷ SecType+noBitsSecType = SecType 8++-- | Relocation entries (@SHT_REL@).+relSecType ∷ SecType+relSecType = SecType 9++-- | A reserved section type (@SHT_SHLIB@).+shlibSecType ∷ SecType+shlibSecType = SecType 10++-- | Dynamic loader symbol table (@SHT_DYNSYM@).+dynSymSecType ∷ SecType+dynSymSecType = SecType 11++-- | First environment-specific section type (@SHT_LOOS@).+loOsSecType ∷ SecType+loOsSecType = SecType 0x60000000++-- | Last environment-specific section type (@SHT_HIOS@).+hiOsSecType ∷ SecType+hiOsSecType = SecType 0x6FFFFFFF++-- | First processor-specific section type (@SHT_LOPROC@).+loProcSecType ∷ SecType+loProcSecType = SecType 0x70000000++-- | Last processor-specific section type (@SHT_HIPROC@).+hiProcSecType ∷ SecType+hiProcSecType = SecType 0x7FFFFFFF++-- | Section flags.+newtype SecFlags = SecFlags { unSecFlags ∷ Word32 }+                   deriving (Typeable, Data, Show, Read,+                             Eq, Flags, BoundedFlags)++-- | Writable data (@SHF_WRITE@).+writeSecFlag ∷ SecFlags+writeSecFlag = SecFlags 1++-- | Allocated data (@SHF_ALLOC@).+allocSecFlag ∷ SecFlags+allocSecFlag = SecFlags 2++-- | Executable instructions (@SHF_EXECINSTR@).+execSecFlag ∷ SecFlags+execSecFlag = SecFlags 4++-- | Mergeable data (@SHF_MERGE@).+mergeSecFlag ∷ SecFlags+mergeSecFlag = SecFlags 0x10++-- | Flag that indicates that 'shInfo' is a section header table index.+--   (@SHF_INFO_LINK@)+infoLinkSecFlag ∷ SecFlags+infoLinkSecFlag = SecFlags 0x40++-- | Environment-specific flags mask (@SHF_MASKOS@).+osSecFlags ∷ SecFlags+osSecFlags = SecFlags 0x0F000000++-- | Processor-specific flags mask (@SHF_MASKOS@).+procSecFlags ∷ SecFlags+procSecFlags = SecFlags 0xF0000000++-- | Section header table entry.+data SecHdr c = SecHdr { shName    ∷ StrIx+                       , shType    ∷ SecType+                       , shFlags   ∷ SecFlags+                       , shAddr    ∷ Addr c+                       , shOff     ∷ Off c+                       , shSize    ∷ Addr c+                       , shLink    ∷ Word32+                       , shInfo    ∷ Word32+                       , shAlign   ∷ Addr c+                       , shEntSize ∷ Addr c }+                deriving Typeable++deriving instance (Data c, IsFileClass c) ⇒ Data (SecHdr c)++-- | ELF32 section header table entry.+type SecHdr32 = SecHdr Elf32++-- | ELF64 section header table entry.+type SecHdr64 = SecHdr Elf64++-- | ELF32 section header table entry size.+secHdr32Size ∷ Int+secHdr32Size = 40++-- | ELF64 section header table entry size.+secHdr64Size ∷ Int+secHdr64Size = 64++-- | 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++-- | 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++-- | Section header filled with zeros.+zeroSecHdr ∷ IsFileClass c ⇒ SecHdr c+zeroSecHdr = SecHdr { shName    = 0+                    , shType    = unusedSecType+                    , shFlags   = noFlags+                    , shAddr    = 0+                    , shOff     = 0+                    , shSize    = 0+                    , shLink    = 0+                    , shInfo    = 0+                    , shAlign   = 0+                    , shEntSize = 0 }++-- | Symbol type.+newtype SymType = SymType { unSymType ∷ Word4 }+                  deriving (Typeable, Data, Show, Read,+                            Eq, Ord, Bounded, Enum, Ix)++-- | Undefined symbol type (@STT_NOTYPE@).+undefSymType ∷ SymType+undefSymType = SymType 0++-- | Object (@STT_OBJECT@).+objSymType ∷ SymType+objSymType = SymType 1++-- | Function (@STT_FUNC@).+funSymType ∷ SymType+funSymType = SymType 2++-- | Section (@STT_SECTION@).+secSymType ∷ SymType+secSymType = SymType 3++-- | Source file name (@STT_FILE@).+fileSymType ∷ SymType+fileSymType = SymType 4++-- | Common block label (@STT_COMMON@).+commonSymType ∷ SymType+commonSymType = SymType 5++-- | Thread-local storage (@STT_TLS@).+tlsSymType ∷ SymType+tlsSymType = SymType 6++-- | First environment-specific symbol type (@STT_LOOS@).+loOsSymType ∷ SymType+loOsSymType = SymType 10++-- | Last environment-specific symbol type (@STT_HIOS@).+hiOsSymType ∷ SymType+hiOsSymType = SymType 12++-- | First processor-specific symbol type (@STT_LOPROC@).+loProcSymType ∷ SymType+loProcSymType = SymType 13++-- | Last processor-specific symbol type (@STT_HIPROC@).+hiProcSymType ∷ SymType+hiProcSymType = SymType 15++-- | Symbol binding type.+newtype SymBind = SymBind { unSymBind ∷ Word4 }+                  deriving (Typeable, Data, Show, Read,+                            Eq, Ord, Bounded, Enum, Ix)++-- | Local symbol (@STB_LOCAL@).+localSymBind ∷ SymBind+localSymBind = SymBind 0++-- | Global symbol (@STB_GLOBAL@).+globalSymBind ∷ SymBind+globalSymBind = SymBind 1++-- | Lower precedence global symbol (@STB_WEAK@).+weakSymBind ∷ SymBind+weakSymBind = SymBind 2++-- | First environment-specific symbol binding type (@STB_LOOS@).+loOsSymBind ∷ SymBind+loOsSymBind = SymBind 10++-- | Last environment-specific symbol binding type (@STB_HIOS@).+hiOsSymBind ∷ SymBind+hiOsSymBind = SymBind 12++-- | First processor-specific symbol binding type (@STB_LOPROC@).+loProcSymBind ∷ SymBind+loProcSymBind = SymBind 13++-- | Last processor-specific symbol binding type (@STB_HIPROC@).+hiProcSymBind ∷ SymBind+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)++-- | Symbol visibility code.+unSymVisi ∷ SymVisi → Word2+unSymVisi DefSymVisi = 0+unSymVisi IntSymVisi = 1+unSymVisi HiddenSymVisi = 2+unSymVisi ProtSymVisi = 3++-- | Symbol table index.+newtype SymIx c = SymIx { unSymIx ∷ UnSymIx c }+                  deriving Typeable++deriving instance (Data c, IsFileClass c) ⇒ Data (SymIx c)+deriving instance IsFileClass c ⇒ Show (SymIx c)+deriving instance IsFileClass c ⇒ Read (SymIx c)+deriving instance IsFileClass c ⇒ Eq (SymIx c)+deriving instance IsFileClass c ⇒ Ord (SymIx c)+deriving instance IsFileClass c ⇒ Bounded (SymIx c)+deriving instance IsFileClass c ⇒ Enum (SymIx c)+deriving instance IsFileClass c ⇒ Ix (SymIx c)+deriving instance IsFileClass c ⇒ Num (SymIx c)+deriving instance IsFileClass c ⇒ Bits (SymIx c)+deriving instance IsFileClass c ⇒ FiniteBits (SymIx c)+deriving instance IsFileClass c ⇒ Integral (SymIx c)+deriving instance IsFileClass c ⇒ Real (SymIx c)++-- | Undefined symbol table index.+undefSymIx ∷ IsFileClass c ⇒ SymIx c+undefSymIx = SymIx 0++-- | Symbol table entry.+data SymEnt c = SymEnt { symName  ∷ StrIx+                       , symBind  ∷ SymBind+                       , symType  ∷ SymType+                       , symVisi  ∷ SymVisi+                       , symSecIx ∷ SecIx+                       , symAddr  ∷ Addr c+                       , symSize  ∷ Addr c }+                deriving Typeable++deriving instance (Data c, IsFileClass c) ⇒ Data (SymEnt c)++-- | ELF32 symbol table entry.+type SymEnt32 = SymEnt Elf32++-- | ELF64 symbol table entry.+type SymEnt64 = SymEnt Elf64++-- | ELF32 symbol table entry size.+symEnt32Size ∷ Int+symEnt32Size = 16++-- | ELF64 symbol table entry size.+symEnt64Size ∷ Int+symEnt64Size = 24++-- | 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++-- | 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++-- | Symbol table entry filled with zeros.+zeroSymEnt ∷ IsFileClass c ⇒ SymEnt c+zeroSymEnt = SymEnt { symName  = 0+                    , symBind  = localSymBind+                    , symType  = undefSymType+                    , symVisi  = DefSymVisi+                    , symSecIx = undefSecIx+                    , symAddr  = 0+                    , symSize  = 0 }++-- | Relocation type.+newtype RelType c = RelType { unRelType ∷ UnRelType c }+                    deriving Typeable++deriving instance (Data c, IsFileClass c) ⇒ Data (RelType c)+deriving instance IsFileClass c ⇒ Show (RelType c)+deriving instance IsFileClass c ⇒ Read (RelType c)+deriving instance IsFileClass c ⇒ Eq (RelType c)+deriving instance IsFileClass c ⇒ Ord (RelType c)+deriving instance IsFileClass c ⇒ Bounded (RelType c)+deriving instance IsFileClass c ⇒ Enum (RelType c)+deriving instance IsFileClass c ⇒ Ix (RelType c)++-- | ELF32 relocation type.+type RelType32 = RelType Elf32++-- | ELF64 relocation type.+type RelType64 = RelType Elf64++-- | Relocation table entry (REL).+data RelEnt c = RelEnt { relOff   ∷ Addr c+                       , relSymIx ∷ SymIx c+                       , relType  ∷ RelType c }+                deriving Typeable++deriving instance (Data c, IsFileClass c) ⇒ Data (RelEnt c)+deriving instance IsFileClass c ⇒ Show (RelEnt c)+deriving instance IsFileClass c ⇒ Read (RelEnt c)+deriving instance IsFileClass c ⇒ Eq (RelEnt c)++-- | ELF32 relocation table entry (REL).+type RelEnt32 = RelEnt Elf32++-- | ELF64 relocation table entry (REL).+type RelEnt64 = RelEnt Elf64++-- | Relocation table entry (RELA).+data RelaEnt c = RelaEnt { relaOff    ∷ Addr c+                         , relaSymIx  ∷ SymIx c+                         , relaType   ∷ RelType c+                         , relaAddend ∷ Addr c }+                 deriving Typeable++-- | ELF32 relocation table entry (RELA).+type RelaEnt32 = RelaEnt Elf32++-- | 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++-- | ELF64 relocation table entry (RELA) size.+relaEnt64Size ∷ Int+relaEnt64Size = 24++-- | 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++-- | 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