diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,15 @@
+1.3.0
+=====
+
+- Test with GHC 8.8.4, 8.10.7, 9.0.2, 9.2.7, 9.4.4, 9.6.1
+- Remove dependency on the `singletons` package
+- Move `getString` and `getSectionData` to `Headers.hs`
+- Fix docs
+- Support docs for the data generated by `Data.Elf.Constants.TH`
+- Remove default constructor name parameter in `Data.Elf.Constants.TH`
+- Few minor fixes
+- CI: Use github actions based on `haskell/actions/setup` (use cabal)
+
 1.2.0
 =====
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -7,12 +7,12 @@
 ## Parsing the header and table entries
 
 Module
-[`Data.Elf.Headers`](https://hackage.haskell.org/package/melf-1.2.0/docs/Data-Elf-Headers.html)
+[`Data.Elf.Headers`](https://hackage.haskell.org/package/melf-1.3.0/docs/Data-Elf-Headers.html)
 implements parsing and serialization of the ELF file header and the entries of section and segment tables.
 
 ELF files come in two flavors: 64-bit and 32-bit.
 To differentiate between them type
-[`ElfClass`](https://hackage.haskell.org/package/melf-1.2.0/docs/Data-Elf-Headers.html#t:ElfClass)
+[`ElfClass`](https://hackage.haskell.org/package/melf-1.3.0/docs/Data-Elf-Headers.html#t:ElfClass)
 is defined:
 
 ``` Haskell
@@ -22,17 +22,26 @@
     deriving (Eq, Show)
 ```
 
+[Singleton](https://blog.jle.im/entry/introduction-to-singletons-1.html)
+types for `ElfClass` are also defined:
+
+``` Haskell
+-- | Singletons for ElfClass
+data SingElfClass :: ElfClass -> Type where
+    SELFCLASS32 :: SingElfClass 'ELFCLASS32  -- ^ Singleton for `ELFCLASS32`
+    SELFCLASS64 :: SingElfClass 'ELFCLASS64  -- ^ Singleton for `ELFCLASS64`
+```
+
 Some fields of the header and table entries have different bitwidth for 64-bit and 32-bit files.
 So the type
-[`WordXX a`](https://hackage.haskell.org/package/melf-1.2.0/docs/Data-Elf-Headers.html#t:WordXX)
+[`WordXX a`](https://hackage.haskell.org/package/melf-1.3.0/docs/Data-Elf-Headers.html#t:WordXX)
 was borrowed from the `data-elf` package:
 
 ``` Haskell
--- | @IsElfClass a@ is defined for each constructor of `ElfClass`.
---   It defines @WordXX a@, which is `Word32` for `ELFCLASS32`
---   and `Word64` for `ELFCLASS64`.
-class ( SingI c
-      , Typeable c
+-- | @SingElfClassI a@ is defined for each constructor of `ElfClass`.
+--   It defines @WordXX a@, which is `Word32` for `ELFCLASS32` and `Word64` for `ELFCLASS64`.
+--   Also it defines singletons for each of the `ElfClass` type.
+class ( Typeable c
       , Typeable (WordXX c)
       , Data (WordXX c)
       , Show (WordXX c)
@@ -48,18 +57,21 @@
       , FiniteBits (WordXX c)
       , Binary (Be (WordXX c))
       , Binary (Le (WordXX c))
-      ) => IsElfClass c where
+      ) => SingElfClassI (c :: ElfClass) where
     type WordXX c = r | r -> c
+    singElfClass :: SingElfClass c
 
-instance IsElfClass 'ELFCLASS32 where
+instance SingElfClassI 'ELFCLASS32 where
     type WordXX 'ELFCLASS32 = Word32
+    singElfClass = SELFCLASS32
 
-instance IsElfClass 'ELFCLASS64 where
+instance SingElfClassI 'ELFCLASS64 where
     type WordXX 'ELFCLASS64 = Word64
+    singElfClass = SELFCLASS64
 ```
 
 The header of the ELF file is represented with the type
-[`HeaderXX a`](https://hackage.haskell.org/package/melf-1.2.0/docs/Data-Elf-Headers.html#t:HeaderXX):
+[`HeaderXX a`](https://hackage.haskell.org/package/melf-1.3.0/docs/Data-Elf-Headers.html#t:HeaderXX):
 
 ``` Haskell
 -- | Parsed ELF header
@@ -84,23 +96,18 @@
 
 So we have two types `HeaderXX 'ELFCLASS64` and `HeaderXX 'ELFCLASS32`.
 To be able to work with headers uniformly the type
-[`Header`](https://hackage.haskell.org/package/melf-1.2.0/docs/Data-Elf-Headers.html#t:Header)
+[`Header`](https://hackage.haskell.org/package/melf-1.3.0/docs/Data-Elf-Headers.html#t:Header)
 was introduced:
 
 ``` Haskell
--- | Sigma type where `ElfClass` defines the type of `HeaderXX`
-type Header = Sigma ElfClass (TyCon1 HeaderXX)
+-- | Header is a sigma type where the first entry defines the type of the second one
+data Header = forall a . Header (SingElfClass a) (HeaderXX a)
 ```
 
 `Header` is a pair.
-The first element is an object of the type `ElfClass` defining the width of the word.
+The first element is an object of the type `SingElfClass` defining the width of the word.
 The second element is `HeaderXX` parametrized with the first element (i. e. Σ-type from
 the languages with dependent types).
-To simulate Σ-types the library
-`singletons`
-([Hackage](https://hackage.haskell.org/package/singletons),
- ["Introduction to singletons"](https://blog.jle.im/entry/introduction-to-singletons-1.html))
-was used.
 
 `Header` is an instance of the
 [`Binary`](https://hackage.haskell.org/package/binary-0.10.0.0/docs/Data-Binary.html#t:Binary)
@@ -110,13 +117,12 @@
 that file with a function like this:
 
 ``` Haskell
-withHeader ::                     BSL.ByteString ->
-    (forall a . IsElfClass a => HeaderXX a -> b) -> Either String b
+withHeader ::                        BSL.ByteString ->
+    (forall a . SingElfClassI a => HeaderXX a -> b) -> Either String b
 withHeader bs f =
     case decodeOrFail bs of
         Left (_, _, err) -> Left err
-        Right (_, _, (classS :&: hxx) :: Header) ->
-            Right $ withElfClass classS f hxx
+        Right (_, _, (Header sing hxx)) -> Right $ withSingElfClassI sing f hxx
 ```
 
 The function
@@ -124,50 +130,51 @@
 is defined in the package
 [`binary`](https://hackage.haskell.org/package/binary).
 The function
-[`withElfClass`](https://hackage.haskell.org/package/melf-1.2.0/docs/Data-Elf-Headers.html#v:withElfClass)
+[`withSingElfClassI`](https://hackage.haskell.org/package/melf-1.3.0/docs/Data-Elf-Headers.html#v:withSingElfClassI)
 creates a context with an implicit word width available and looks like
 [`withSingI`](https://hackage.haskell.org/package/singletons-3.0.1/docs/Data-Singletons.html#v:withSingI):
 
 
 ``` Haskell
--- | Convenience function for creating a
--- context with an implicit ElfClass available.
-withElfClass :: Sing c -> (IsElfClass c => a) -> a
-withElfClass SELFCLASS64 x = x
-withElfClass SELFCLASS32 x = x
+-- | Convenience function for creating a context with an implicit singleton available.
+withSingElfClassI :: SingElfClass c -> (SingElfClassI c => r) -> r
+withSingElfClassI SELFCLASS64 x = x
+withSingElfClassI SELFCLASS32 x = x
 ```
 
 The module `Data.Elf.Headers` also defines the types
-[`SectionXX`](https://hackage.haskell.org/package/melf-1.2.0/docs/Data-Elf-Headers.html#t:SectionXX),
-[`SegmentXX`](https://hackage.haskell.org/package/melf-1.2.0/docs/Data-Elf-Headers.html#t:SegmentXX) and
-[`SymbolXX`](https://hackage.haskell.org/package/melf-1.2.0/docs/Data-Elf-Headers.html#t:SymbolXX)
+[`SectionXX`](https://hackage.haskell.org/package/melf-1.3.0/docs/Data-Elf-Headers.html#t:SectionXX),
+[`SegmentXX`](https://hackage.haskell.org/package/melf-1.3.0/docs/Data-Elf-Headers.html#t:SegmentXX) and
+[`SymbolXX`](https://hackage.haskell.org/package/melf-1.3.0/docs/Data-Elf-Headers.html#t:SymbolXX)
 for the elements of section, segment and symbol tables.
 
 ## Parsing the whole ELF file
 
 The module
-[`Data.Elf`](https://hackage.haskell.org/package/melf-1.2.0/docs/Data-Elf.html)
+[`Data.Elf`](https://hackage.haskell.org/package/melf-1.3.0/docs/Data-Elf.html)
 implements parsing and serialization of the whole ELF files.
 To parse ELF file it reads ELF header, section table and segment table and uses that data to create
 a list of type
-[`ElfListXX`](https://hackage.haskell.org/package/melf-1.2.0/docs/Data-Elf.html#t:ElfListXX)
+[`ElfListXX`](https://hackage.haskell.org/package/melf-1.3.0/docs/Data-Elf.html#t:ElfListXX)
 of elements of the type
-[`ElfXX`](https://hackage.haskell.org/package/melf-1.2.0/docs/Data-Elf.html#t:ElfXX)
+[`ElfXX`](https://hackage.haskell.org/package/melf-1.3.0/docs/Data-Elf.html#t:ElfXX)
 representing the recursive structure of the ELF file.
 It also restores section names from the the string table indexes.
 That results in creating an object of type
-[`Elf`](https://hackage.haskell.org/package/melf-1.2.0/docs/Data-Elf.html#t:Elf):
+[`Elf`](https://hackage.haskell.org/package/melf-1.3.0/docs/Data-Elf.html#t:Elf):
 
 ``` Haskell
 -- | `Elf` is a forrest of trees of type `ElfXX`.
 -- Trees are composed of `ElfXX` nodes, `ElfSegment` can contain subtrees
 data ElfNodeType = Header | SectionTable | SegmentTable | Section | Segment | RawData | RawAlign
+
+-- | List of ELF nodes.
 data ElfListXX c where
     ElfListCons :: ElfXX t c -> ElfListXX c -> ElfListXX c
     ElfListNull :: ElfListXX c
 
--- | Elf is a sigma type where `ElfClass` defines the type of `ElfList`
-type Elf = Sigma ElfClass (TyCon1 ElfListXX)
+-- | Elf is a sigma type where the first entry defines the type of the second one
+data Elf = forall a . Elf (SingElfClass a) (ElfListXX a)
 
 -- | Section data may contain a string table.
 -- If a section contains a string table with section names, the data
@@ -230,6 +237,9 @@
         , eaAlign  :: WordXX c -- ^ Align module
         } -> ElfXX 'RawAlign c
 
+infixr 9 ~:
+
+-- | Helper for `ElfListCons`
 (~:) :: ElfXX t a -> ElfListXX a -> ElfListXX a
 (~:) = ElfListCons
 ```
@@ -252,9 +262,9 @@
     node `ElfSegmentTable`.
 
 Correctly composed ELF object can be serialized with the function
-[`serializeElf`](https://hackage.haskell.org/package/melf-1.2.0/docs/Data-Elf.html#v:serializeElf)
+[`serializeElf`](https://hackage.haskell.org/package/melf-1.3.0/docs/Data-Elf.html#v:serializeElf)
 and parsed with the function
-[`parseElf`](https://hackage.haskell.org/package/melf-1.2.0/docs/Data-Elf.html#v:parseElf):
+[`parseElf`](https://hackage.haskell.org/package/melf-1.3.0/docs/Data-Elf.html#v:parseElf):
 
 ``` Haskell
 serializeElf :: MonadThrow m => Elf -> m ByteString
@@ -298,7 +308,7 @@
 Function `assemble` uses the `melf` library to generate an object file:
 
 ``` Haskell
-    return $ SELFCLASS64 :&:
+    return $ Elf SELFCLASS64 $
         ElfHeader
             { ehData       = ELFDATA2LSB
             , ehOSABI      = ELFOSABI_SYSV
@@ -417,9 +427,9 @@
 for example, it works with the code described above.
 
 Function `dummyLd` consumes an object of the type `Elf` and finds a section `.text`
-(using [`elfFindSectionByName`](https://hackage.haskell.org/package/melf-1.2.0/docs/Data-Elf.html#v:elfFindSectionByName))
+(using [`elfFindSectionByName`](https://hackage.haskell.org/package/melf-1.3.0/docs/Data-Elf.html#v:elfFindSectionByName))
 and header
-(using [`elfFindHeader`](https://hackage.haskell.org/package/melf-1.2.0/docs/Data-Elf.html#v:elfFindHeader))
+(using [`elfFindHeader`](https://hackage.haskell.org/package/melf-1.3.0/docs/Data-Elf.html#v:elfFindHeader))
 in it.
 Then the header type is changed to `ET_EXEC`, the address of the first executable instruction is specified and
 a loadable segment containing the header and the content of `.text` is formed:
@@ -432,12 +442,12 @@
                                 --   in physical memory (depends on max page size)
         }
 
-getMachineConfig :: (IsElfClass a, MonadThrow m) => ElfMachine -> m (MachineConfig a)
+getMachineConfig :: (SingElfClassI a, MonadThrow m) => ElfMachine -> m (MachineConfig a)
 getMachineConfig EM_AARCH64 = return $ MachineConfig 0x400000 0x10000
 getMachineConfig EM_X86_64  = return $ MachineConfig 0x400000 0x1000
 getMachineConfig _          = $chainedError "could not find machine config for this arch"
 
-dummyLd' :: forall a m . (MonadThrow m, IsElfClass a) => ElfListXX a -> m (ElfListXX a)
+dummyLd' :: forall a m . (MonadThrow m, SingElfClassI a) => ElfListXX a -> m (ElfListXX a)
 dummyLd' es = do
 
     section' <- elfFindSectionByName es ".text"
@@ -478,7 +488,7 @@
 -- into the loadable segment of the resulting ELF.
 -- This could work if there are no relocations or references to external symbols.
 dummyLd :: MonadThrow m => Elf -> m Elf
-dummyLd (c :&: l) = (c :&:) <$> withElfClass c dummyLd' l
+dummyLd (Elf c l) = Elf c <$> withSingElfClassI c dummyLd' l
 ```
 
 Try to use this code to produce executable file without GNU linker:
diff --git a/app/hObjDump.hs b/app/hObjDump.hs
--- a/app/hObjDump.hs
+++ b/app/hObjDump.hs
@@ -31,7 +31,6 @@
   <> header "hobjdump - dump ELF files"
   )
 
--- FIXME: use instance Binary Elf'
 printFile :: Bool -> String -> IO ()
 printFile full fileName = do
     bs <- fromStrict <$> BS.readFile fileName
diff --git a/examples/AsmAArch64.hs b/examples/AsmAArch64.hs
--- a/examples/AsmAArch64.hs
+++ b/examples/AsmAArch64.hs
@@ -9,16 +9,6 @@
 {-# LANGUAGE TypeApplications #-}
 {-# LANGUAGE TypeFamilies #-}
 
-{-# LANGUAGE CPP #-}
-
-#if defined(MIN_VERSION_GLASGOW_HASKELL)
-#if MIN_VERSION_GLASGOW_HASKELL(8,10,0,0)
-{-# LANGUAGE StandaloneKindSignatures #-}
-#endif
-#endif
-
-{-# OPTIONS_GHC -Wno-unused-top-binds #-}
-
 module AsmAArch64
     ( CodeState
     , Register
@@ -46,16 +36,28 @@
 import Data.ByteString.Lazy as BSL
 import Data.ByteString.Lazy.Char8 as BSLC
 import Data.Int
-import Data.Singletons.Sigma
-import Data.Singletons.TH
+import Data.Kind
 import Data.Word
 
 import Data.Elf
 import Data.Elf.Constants
 import Data.Elf.Headers
 
-$(singletons [d| data RegisterWidth = X | W |])
+data RegisterWidth = X | W
 
+data SingRegisterWidth :: RegisterWidth -> Type where
+    SX :: SingRegisterWidth 'X
+    SW :: SingRegisterWidth 'W
+
+class SingRegisterWidthI (c :: RegisterWidth) where
+    singRegisterWidth :: SingRegisterWidth c
+
+instance SingRegisterWidthI 'X where
+    singRegisterWidth = SX
+
+instance SingRegisterWidthI 'W where
+    singRegisterWidth = SW
+
 newtype Register (c :: RegisterWidth) = R Word32
 
 newtype CodeOffset  = CodeOffset  { getCodeOffset  :: Int64 }  deriving (Eq, Show, Ord, Num, Enum, Real, Integral, Bits, FiniteBits)
@@ -124,8 +126,8 @@
 builderRepeatZero :: Int -> Builder
 builderRepeatZero n = mconcat $ P.replicate n (word8 0)
 
-b64 :: forall w . SingI w => Register w -> Word32
-b64 _ = case sing @w of
+b64 :: forall w . SingRegisterWidthI w => Register w -> Word32
+b64 _ = case singRegisterWidth @w of
     SX -> 1
     SW -> 0
 
@@ -167,7 +169,7 @@
         return $ Instruction $  0x14000000 .|. imm26
 
 -- | C6.2.187 MOV (wide immediate)
-mov :: (MonadState CodeState m, SingI w) => Register w -> Word16 -> m ()
+mov :: (MonadState CodeState m, SingRegisterWidthI w) => Register w -> Word16 -> m ()
 mov r@(R n) imm = emit $ Instruction $ (b64 r `shift` 31)
                                     .|. 0x52800000
                                     .|. (fromIntegral imm `shift` 5)
@@ -186,7 +188,7 @@
 findOffset  poolOffset (PoolRef offsetInPool) = poolOffset + offsetInPool
 
 -- | C6.2.132 LDR (literal)
-ldr :: (MonadState CodeState m, SingI w) => Register w -> Label -> m ()
+ldr :: (MonadState CodeState m, SingRegisterWidthI w) => Register w -> Label -> m ()
 ldr r@(R n) rr = emit' f where
 
     offsetToImm19 :: CodeOffset -> Either String Word32
@@ -269,7 +271,7 @@
 
     (symbolTableData, stringTableData) <- serializeSymbolTable ELFDATA2LSB (zeroIndexStringItem : symbolTable)
 
-    return $ SELFCLASS64 :&:
+    return $ Elf SELFCLASS64 $
         ElfHeader
             { ehData       = ELFDATA2LSB
             , ehOSABI      = ELFOSABI_SYSV
diff --git a/examples/DummyLd.hs b/examples/DummyLd.hs
--- a/examples/DummyLd.hs
+++ b/examples/DummyLd.hs
@@ -10,8 +10,6 @@
 
 import Control.Monad.Catch
 import Data.Bits
-import Data.Singletons
-import Data.Singletons.Sigma
 
 import Data.Elf
 import Data.Elf.Constants
@@ -25,12 +23,12 @@
                                 --   in physical memory (depends on max page size)
         }
 
-getMachineConfig :: (IsElfClass a, MonadThrow m) => ElfMachine -> m (MachineConfig a)
+getMachineConfig :: (SingElfClassI a, MonadThrow m) => ElfMachine -> m (MachineConfig a)
 getMachineConfig EM_AARCH64 = return $ MachineConfig 0x400000 0x10000
 getMachineConfig EM_X86_64  = return $ MachineConfig 0x400000 0x1000
 getMachineConfig _          = $chainedError "could not find machine config for this arch"
 
-dummyLd' :: forall a m . (MonadThrow m, IsElfClass a) => ElfListXX a -> m (ElfListXX a)
+dummyLd' :: forall a m . (MonadThrow m, SingElfClassI a) => ElfListXX a -> m (ElfListXX a)
 dummyLd' es = do
 
     section' <- elfFindSectionByName es ".text"
@@ -62,7 +60,7 @@
                     , epData       =
                         ElfHeader
                             { ehType  = ET_EXEC
-                            , ehEntry = mcAddress + headerSize (fromSing $ sing @a)
+                            , ehEntry = mcAddress + headerSize (fromSingElfClass $ singElfClass @a)
                             , ..
                             }
                         ~: ElfRawData
@@ -77,4 +75,4 @@
 -- into the loadable segment of the resulting ELF.
 -- This could work if there are no relocations or references to external symbols.
 dummyLd :: MonadThrow m => Elf -> m Elf
-dummyLd (c :&: l) = (c :&:) <$> withElfClass c dummyLd' l
+dummyLd (Elf c l) = Elf c <$> withSingElfClassI c dummyLd' l
diff --git a/examples/Examples.hs b/examples/Examples.hs
--- a/examples/Examples.hs
+++ b/examples/Examples.hs
@@ -2,10 +2,10 @@
 
 import Control.Monad.Fix
 import Control.Monad.Catch
-import Data.Bits
 import Data.ByteString.Lazy as BSL
+import GHC.IO.Encoding (setLocaleEncoding)
 import System.FilePath
-import System.Posix.Files
+import System.IO
 import Test.Tasty
 import Test.Tasty.Golden
 import Test.Tasty.HUnit
@@ -18,11 +18,6 @@
 import HelloWorld
 import ForwardLabel
 
-makeFileExecutable :: String -> IO ()
-makeFileExecutable path = do
-    m <- fileMode <$> getFileStatus path
-    setFileMode path $ m .|. ownerExecuteMode
-
 helloWorldExe :: MonadCatch m => m Elf
 helloWorldExe = assemble helloWorld >>= dummyLd
 
@@ -42,7 +37,6 @@
 writeElf path elf = do
     e <- serializeElf elf
     BSL.writeFile path e
-    makeFileExecutable path
 
 testElf :: String -> IO Elf -> [ TestTree ]
 testElf elfFileName elf =
@@ -61,8 +55,10 @@
         l = t </> elfFileName <.> "layout"
 
 main :: IO ()
-main = defaultMain $ testGroup "examples"
-    (  testElf "helloWorldObj.o" helloWorldObj
-    ++ testElf "helloWorldExe"   helloWorldExe
-    ++ testElf "forwardLabelExe" forwardLabelExe
-    )
+main = do
+    setLocaleEncoding utf8
+    defaultMain $ testGroup "examples"
+        (  testElf "helloWorldObj.o" helloWorldObj
+        ++ testElf "helloWorldExe"   helloWorldExe
+        ++ testElf "forwardLabelExe" forwardLabelExe
+        )
diff --git a/examples/helloWorldObj.o.dump.golden b/examples/helloWorldObj.o.dump.golden
--- a/examples/helloWorldObj.o.dump.golden
+++ b/examples/helloWorldObj.o.dump.golden
@@ -40,7 +40,7 @@
         symbol "_start" {
             Bind:  STB_Global
             Type:  STT_NoType
-            ShNdx: SHN_EXT 1
+            ShNdx: ElfSectionIndex 1
             Value: 0x0000000000000000
             Size:  0x0000000000000000
         }
diff --git a/melf.cabal b/melf.cabal
--- a/melf.cabal
+++ b/melf.cabal
@@ -1,11 +1,11 @@
 cabal-version: 1.18
 
--- This file has been generated from package.yaml by hpack version 0.35.1.
+-- This file has been generated from package.yaml by hpack version 0.35.2.
 --
 -- see: https://github.com/sol/hpack
 
 name:           melf
-version:        1.2.0
+version:        1.3.0
 synopsis:       An Elf parser
 description:    Parser for ELF object format
 category:       Data
@@ -18,7 +18,7 @@
 license-file:   LICENSE
 build-type:     Simple
 tested-with:
-    GHC == 8.8.4, GHC == 8.10.7, GHC == 9.0.2, GHC == 9.2.4, GHC == 9.2.5, GHC == 9.4.4
+    GHC == 8.8.4, GHC == 8.10.7, GHC == 9.0.2, GHC == 9.2.7, GHC == 9.4.4, GHC == 9.6.1
 extra-doc-files:
     ChangeLog.md
     README.md
@@ -76,18 +76,10 @@
     , bytestring >=0.10.10 && <0.12
     , exceptions >=0.10.4 && <0.11
     , lens >=5.0.1 && <5.3
-    , mtl >=2.2.2 && <2.3
+    , mtl >=2.2.2 && <2.4
     , prettyprinter >=1.7.0 && <1.8
-    , template-haskell >=2.15 && <2.20
+    , template-haskell >=2.15 && <2.21
   default-language: Haskell2010
-  if impl(ghc >= 9.0)
-    build-depends:
-        singletons ==3.0.*
-      , singletons-base >=3.0 && <3.2
-      , singletons-th >=3.0 && <3.2
-  else
-    build-depends:
-        singletons >=2.6 && <2.8
 
 executable hobjdump
   main-is: hObjDump.hs
@@ -143,15 +135,7 @@
     , tasty
     , tasty-golden
     , tasty-hunit
-    , unix >=2.7.2.2 && <2.8
   default-language: Haskell2010
-  if impl(ghc >= 9.0)
-    build-depends:
-        singletons
-      , singletons-th
-  else
-    build-depends:
-        singletons
 
 test-suite exceptions
   type: exitcode-stdio-1.0
@@ -186,7 +170,6 @@
     , filepath >=1.4.2.1 && <1.5
     , melf
     , prettyprinter
-    , singletons
     , tasty >=1.4.1 && <1.5
     , tasty-golden >=2.3.4 && <2.4
     , tasty-hunit >=0.10.0.3 && <0.11
diff --git a/src/Data/Elf.hs b/src/Data/Elf.hs
--- a/src/Data/Elf.hs
+++ b/src/Data/Elf.hs
@@ -11,18 +11,16 @@
 
 module Data.Elf (
     -- * Elf
-      ElfNodeType (..)
-    , ElfListXX (..)
-    , Elf
+      ElfListXX (..)
+    , (~:)
+    , ElfNodeType (..)
     , ElfSectionData (..)
     , ElfXX (..)
-    , (~:)
+    , Elf (..)
     , parseElf
     , serializeElf
 
     -- * Misc
-    , getSectionData -- FIXME: Should be moved to Data.Elf.Headers (requires bumping major version)
-    , getString      -- FIXME: ...
     , elfFindSection
     , elfFindSectionByName
     , elfFindHeader
diff --git a/src/Data/Elf/Constants.hs b/src/Data/Elf/Constants.hs
--- a/src/Data/Elf/Constants.hs
+++ b/src/Data/Elf/Constants.hs
@@ -12,7 +12,6 @@
 -- https://stackoverflow.com/questions/10672981/export-template-haskell-generated-definitions
 
 module Data.Elf.Constants (
-    -- $docs
     module Data.Elf.Constants.Data
     ) where
 import Data.Elf.Constants.Data
diff --git a/src/Data/Elf/Constants/Data.hs b/src/Data/Elf/Constants/Data.hs
--- a/src/Data/Elf/Constants/Data.hs
+++ b/src/Data/Elf/Constants/Data.hs
@@ -15,16 +15,17 @@
 
 {- $docs
 
-Constants defined here are declared using Template Haskell so there are no docs.
-See the sources or the documents describing ELF file format.
+Constants defined here are declared using Template Haskell,
+so the full documentation is supported only starting from GHC 2.4.x.
+For the older versions see the sources or the documents describing ELF file format.
 
 Data types, patterns and instances are generated by @mkDeclarations@ TH macros.
 Below is an example of how it works.  The code
 
 @
-$(mkDeclarations BaseWord16 \"TypeName\" \"ValuePrefix\" \"DefaultConstructorName\"
-    [ (\"_A\", 0)
-    , (\"_B\", 1)
+$(mkDeclarations BaseWord16 \"TypeName\" \"ValuePrefix\"
+    [ (\"_A\", 0, "Doc strig for ValuePrefix_A")
+    , (\"_B\", 1, "Doc strig for ValuePrefix_B")
     ])
 @
 
@@ -36,7 +37,7 @@
     instance Show TypeName where
         show (TypeName 0) = (\"ValuePrefix\" ++ "_A")
         show (TypeName 1) = (\"ValuePrefix\" ++ "_B")
-        show (TypeName n_a5QI) = (\"DefaultConstructorName\" ++ (\" \" ++ show n_a5QI))
+        show (TypeName n_a5QI) = (\"TypeName\" ++ (\" \" ++ show n_a5QI))
 
     pattern ValuePrefix_A :: TypeName
     pattern ValuePrefix_A = TypeName 0
@@ -44,9 +45,6 @@
     pattern ValuePrefix_B :: TypeName
     pattern ValuePrefix_B = TypeName 1
 
-    pattern DefaultConstructorName :: Word16 -> TypeName
-    pattern DefaultConstructorName n_a5QJ = TypeName n_a5QJ
-
     instance Binary (Le TypeName) where
         get = (Le \<$\> (TypeName \<$\> getWord16le))
         put (Le (TypeName n_a5QK)) = putWord16le n_a5QK
@@ -58,376 +56,376 @@
 -}
 
 -- | Operating system and ABI for which the object is prepared
-$(mkDeclarations BaseWord8 "ElfOSABI" "ELFOSABI" "ELFOSABI_EXT"
-    [ ("_SYSV",         0) -- No extensions or unspecified
-    , ("_HPUX",         1) -- Hewlett-Packard HP-UX
-    , ("_NETBSD",       2) -- NetBSD
-    , ("_LINUX",        3) -- Linux
-    , ("_SOLARIS",      6) -- Sun Solaris
-    , ("_AIX",          7) -- AIX
-    , ("_IRIX",         8) -- IRIX
-    , ("_FREEBSD",      9) -- FreeBSD
-    , ("_TRU64",       10) -- Compaq TRU64 UNIX
-    , ("_MODESTO",     11) -- Novell Modesto
-    , ("_OPENBSD",     12) -- Open BSD
-    , ("_OPENVMS",     13) -- Open VMS
-    , ("_NSK",         14) -- Hewlett-Packard Non-Stop Kernel
-    , ("_AROS",        15) -- Amiga Research OS
-    , ("_ARM",         97) -- ARM
-    , ("_STANDALONE", 255) -- Standalone (embedded) application
+$(mkDeclarations BaseWord8 "ElfOSABI" "ELFOSABI"
+    [ ("_SYSV",         0, "No extensions or unspecified")
+    , ("_HPUX",         1, "Hewlett-Packard HP-UX")
+    , ("_NETBSD",       2, "NetBSD")
+    , ("_LINUX",        3, "Linux")
+    , ("_SOLARIS",      6, "Sun Solaris")
+    , ("_AIX",          7, "AIX")
+    , ("_IRIX",         8, "IRIX")
+    , ("_FREEBSD",      9, "FreeBSD")
+    , ("_TRU64",       10, "Compaq TRU64 UNIX")
+    , ("_MODESTO",     11, "Novell Modesto")
+    , ("_OPENBSD",     12, "Open BSD")
+    , ("_OPENVMS",     13, "Open VMS")
+    , ("_NSK",         14, "Hewlett-Packard Non-Stop Kernel")
+    , ("_AROS",        15, "Amiga Research OS")
+    , ("_ARM",         97, "ARM")
+    , ("_STANDALONE", 255, "Standalone (embedded) application")
     ])
 
 -- | Object file type
-$(mkDeclarations BaseWord16 "ElfType" "ET" "ET_EXT"
-    [ ("_NONE", 0) -- Unspecified type
-    , ("_REL",  1) -- Relocatable object file
-    , ("_EXEC", 2) -- Executable object file
-    , ("_DYN",  3) -- Shared object file
-    , ("_CORE", 4) -- Core dump object file
+$(mkDeclarations BaseWord16 "ElfType" "ET"
+    [ ("_NONE", 0, "Unspecified type")
+    , ("_REL",  1, "Relocatable object file")
+    , ("_EXEC", 2, "Executable object file")
+    , ("_DYN",  3, "Shared object file")
+    , ("_CORE", 4, "Core dump object file")
     ])
 
 -- | Target architecture
-$(mkDeclarations BaseWord16 "ElfMachine" "EM" "EM_EXT"
-    [ ("_NONE",         0) -- No machine
-    , ("_M32",          1) -- AT&T WE 32100
-    , ("_SPARC",        2) -- SPARC
-    , ("_386",          3) -- Intel 80386
-    , ("_68K",          4) -- Motorola 68000
-    , ("_88K",          5) -- Motorola 88000
-    , ("_486",          6) -- Intel i486 (DO NOT USE THIS ONE)
-    , ("_860",          7) -- Intel 80860
-    , ("_MIPS",         8) -- MIPS I Architecture
-    , ("_S370",         9) -- IBM System/370 Processor
-    , ("_MIPS_RS3_LE", 10) -- MIPS RS3000 Little-endian
-    , ("_SPARC64",     11) -- SPARC 64-bit
-    , ("_PARISC",      15) -- Hewlett-Packard PA-RISC
-    , ("_VPP500",      17) -- Fujitsu VPP500
-    , ("_SPARC32PLUS", 18) -- Enhanced instruction set SPARC
-    , ("_960",         19) -- Intel 80960
-    , ("_PPC",         20) -- PowerPC
-    , ("_PPC64",       21) -- 64-bit PowerPC
-    , ("_S390",        22) -- IBM System/390 Processor
-    , ("_SPU",         23) -- Cell SPU
-    , ("_V800",        36) -- NEC V800
-    , ("_FR20",        37) -- Fujitsu FR20
-    , ("_RH32",        38) -- TRW RH-32
-    , ("_RCE",         39) -- Motorola RCE
-    , ("_ARM",         40) -- Advanced RISC Machines ARM
-    , ("_ALPHA",       41) -- Digital Alpha
-    , ("_SH",          42) -- Hitachi SH
-    , ("_SPARCV9",     43) -- SPARC Version 9
-    , ("_TRICORE",     44) -- Siemens TriCore embedded processor
-    , ("_ARC",         45) -- Argonaut RISC Core, Argonaut Technologies Inc.
-    , ("_H8_300",      46) -- Hitachi H8/300
-    , ("_H8_300H",     47) -- Hitachi H8/300H
-    , ("_H8S",         48) -- Hitachi H8S
-    , ("_H8_500",      49) -- Hitachi H8/500
-    , ("_IA_64",       50) -- Intel IA-64 processor architecture
-    , ("_MIPS_X",      51) -- Stanford MIPS-X
-    , ("_COLDFIRE",    52) -- Motorola ColdFire
-    , ("_68HC12",      53) -- Motorola M68HC12
-    , ("_MMA",         54) -- Fujitsu MMA Multimedia Accelerator
-    , ("_PCP",         55) -- Siemens PCP
-    , ("_NCPU",        56) -- Sony nCPU embedded RISC processor
-    , ("_NDR1",        57) -- Denso NDR1 microprocessor
-    , ("_STARCORE",    58) -- Motorola Star*Core processor
-    , ("_ME16",        59) -- Toyota ME16 processor
-    , ("_ST100",       60) -- STMicroelectronics ST100 processor
-    , ("_TINYJ",       61) -- Advanced Logic Corp. TinyJ embedded processor family
-    , ("_X86_64",      62) -- AMD x86-64 architecture
-    , ("_PDSP",        63) -- Sony DSP Processor
-    , ("_FX66",        66) -- Siemens FX66 microcontroller
-    , ("_ST9PLUS",     67) -- STMicroelectronics ST9+ 8/16 bit microcontroller
-    , ("_ST7",         68) -- STMicroelectronics ST7 8-bit microcontroller
-    , ("_68HC16",      69) -- Motorola MC68HC16 Microcontroller
-    , ("_68HC11",      70) -- Motorola MC68HC11 Microcontroller
-    , ("_68HC08",      71) -- Motorola MC68HC08 Microcontroller
-    , ("_68HC05",      72) -- Motorola MC68HC05 Microcontroller
-    , ("_SVX",         73) -- Silicon Graphics SVx
-    , ("_ST19",        74) -- STMicroelectronics ST19 8-bit microcontroller
-    , ("_VAX",         75) -- Digital VAX
-    , ("_CRIS",        76) -- Axis Communications 32-bit embedded processor
-    , ("_JAVELIN",     77) -- Infineon Technologies 32-bit embedded processor
-    , ("_FIREPATH",    78) -- Element 14 64-bit DSP Processor
-    , ("_ZSP",         79) -- LSI Logic 16-bit DSP Processor
-    , ("_MMIX",        80) -- Donald Knuth's educational 64-bit processor
-    , ("_HUANY",       81) -- Harvard University machine-independent object files
-    , ("_PRISM",       82) -- SiTera Prism
-    , ("_AVR",         83) -- Atmel AVR 8-bit microcontroller
-    , ("_FR30",        84) -- Fujitsu FR30
-    , ("_D10V",        85) -- Mitsubishi D10V
-    , ("_D30V",        86) -- Mitsubishi D30V
-    , ("_V850",        87) -- NEC v850
-    , ("_M32R",        88) -- Mitsubishi M32R
-    , ("_MN10300",     89) -- Matsushita MN10300
-    , ("_MN10200",     90) -- Matsushita MN10200
-    , ("_PJ",          91) -- picoJava
-    , ("_OPENRISC",    92) -- OpenRISC 32-bit embedded processor
-    , ("_ARC_A5",      93) -- ARC Cores Tangent-A5
-    , ("_XTENSA",      94) -- Tensilica Xtensa Architecture
-    , ("_VIDEOCORE",   95) -- Alphamosaic VideoCore processor
-    , ("_TMM_GPP",     96) -- Thompson Multimedia General Purpose Processor
-    , ("_NS32K",       97) -- National Semiconductor 32000 series
-    , ("_TPC",         98) -- Tenor Network TPC processor
-    , ("_SNP1K",       99) -- Trebia SNP 1000 processor
-    , ("_ST200",      100) -- STMicroelectronics (www.st.com) ST200 microcontroller
-    , ("_IP2K",       101) -- Ubicom IP2xxx microcontroller family
-    , ("_MAX",        102) -- MAX Processor
-    , ("_CR",         103) -- National Semiconductor CompactRISC microprocessor
-    , ("_F2MC16",     104) -- Fujitsu F2MC16
-    , ("_MSP430",     105) -- Texas Instruments embedded microcontroller msp430
-    , ("_BLACKFIN",   106) -- Analog Devices Blackfin (DSP) processor
-    , ("_SE_C33",     107) -- S1C33 Family of Seiko Epson processors
-    , ("_SEP",        108) -- Sharp embedded microprocessor
-    , ("_ARCA",       109) -- Arca RISC Microprocessor
-    , ("_UNICORE",    110) -- Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University
-    , ("_AARCH64",    183) -- ELF for the Arm 64-bit Architecture (AArch64)
+$(mkDeclarations BaseWord16 "ElfMachine" "EM"
+    [ ("_NONE",         0, "No machine")
+    , ("_M32",          1, "AT&T WE 32100")
+    , ("_SPARC",        2, "SPARC")
+    , ("_386",          3, "Intel 80386")
+    , ("_68K",          4, "Motorola 68000")
+    , ("_88K",          5, "Motorola 88000")
+    , ("_486",          6, "Intel i486 (DO NOT USE THIS ONE)")
+    , ("_860",          7, "Intel 80860")
+    , ("_MIPS",         8, "MIPS I Architecture")
+    , ("_S370",         9, "IBM System/370 Processor")
+    , ("_MIPS_RS3_LE", 10, "MIPS RS3000 Little-endian")
+    , ("_SPARC64",     11, "SPARC 64-bit")
+    , ("_PARISC",      15, "Hewlett-Packard PA-RISC")
+    , ("_VPP500",      17, "Fujitsu VPP500")
+    , ("_SPARC32PLUS", 18, "Enhanced instruction set SPARC")
+    , ("_960",         19, "Intel 80960")
+    , ("_PPC",         20, "PowerPC")
+    , ("_PPC64",       21, "64-bit PowerPC")
+    , ("_S390",        22, "IBM System/390 Processor")
+    , ("_SPU",         23, "Cell SPU")
+    , ("_V800",        36, "NEC V800")
+    , ("_FR20",        37, "Fujitsu FR20")
+    , ("_RH32",        38, "TRW RH-32")
+    , ("_RCE",         39, "Motorola RCE")
+    , ("_ARM",         40, "Advanced RISC Machines ARM")
+    , ("_ALPHA",       41, "Digital Alpha")
+    , ("_SH",          42, "Hitachi SH")
+    , ("_SPARCV9",     43, "SPARC Version 9")
+    , ("_TRICORE",     44, "Siemens TriCore embedded processor")
+    , ("_ARC",         45, "Argonaut RISC Core, Argonaut Technologies Inc.")
+    , ("_H8_300",      46, "Hitachi H8/300")
+    , ("_H8_300H",     47, "Hitachi H8/300H")
+    , ("_H8S",         48, "Hitachi H8S")
+    , ("_H8_500",      49, "Hitachi H8/500")
+    , ("_IA_64",       50, "Intel IA-64 processor architecture")
+    , ("_MIPS_X",      51, "Stanford MIPS-X")
+    , ("_COLDFIRE",    52, "Motorola ColdFire")
+    , ("_68HC12",      53, "Motorola M68HC12")
+    , ("_MMA",         54, "Fujitsu MMA Multimedia Accelerator")
+    , ("_PCP",         55, "Siemens PCP")
+    , ("_NCPU",        56, "Sony nCPU embedded RISC processor")
+    , ("_NDR1",        57, "Denso NDR1 microprocessor")
+    , ("_STARCORE",    58, "Motorola Star*Core processor")
+    , ("_ME16",        59, "Toyota ME16 processor")
+    , ("_ST100",       60, "STMicroelectronics ST100 processor")
+    , ("_TINYJ",       61, "Advanced Logic Corp. TinyJ embedded processor family")
+    , ("_X86_64",      62, "AMD x86-64 architecture")
+    , ("_PDSP",        63, "Sony DSP Processor")
+    , ("_FX66",        66, "Siemens FX66 microcontroller")
+    , ("_ST9PLUS",     67, "STMicroelectronics ST9+ 8/16 bit microcontroller")
+    , ("_ST7",         68, "STMicroelectronics ST7 8-bit microcontroller")
+    , ("_68HC16",      69, "Motorola MC68HC16 Microcontroller")
+    , ("_68HC11",      70, "Motorola MC68HC11 Microcontroller")
+    , ("_68HC08",      71, "Motorola MC68HC08 Microcontroller")
+    , ("_68HC05",      72, "Motorola MC68HC05 Microcontroller")
+    , ("_SVX",         73, "Silicon Graphics SVx")
+    , ("_ST19",        74, "STMicroelectronics ST19 8-bit microcontroller")
+    , ("_VAX",         75, "Digital VAX")
+    , ("_CRIS",        76, "Axis Communications 32-bit embedded processor")
+    , ("_JAVELIN",     77, "Infineon Technologies 32-bit embedded processor")
+    , ("_FIREPATH",    78, "Element 14 64-bit DSP Processor")
+    , ("_ZSP",         79, "LSI Logic 16-bit DSP Processor")
+    , ("_MMIX",        80, "Donald Knuth's educational 64-bit processor")
+    , ("_HUANY",       81, "Harvard University machine-independent object files")
+    , ("_PRISM",       82, "SiTera Prism")
+    , ("_AVR",         83, "Atmel AVR 8-bit microcontroller")
+    , ("_FR30",        84, "Fujitsu FR30")
+    , ("_D10V",        85, "Mitsubishi D10V")
+    , ("_D30V",        86, "Mitsubishi D30V")
+    , ("_V850",        87, "NEC v850")
+    , ("_M32R",        88, "Mitsubishi M32R")
+    , ("_MN10300",     89, "Matsushita MN10300")
+    , ("_MN10200",     90, "Matsushita MN10200")
+    , ("_PJ",          91, "picoJava")
+    , ("_OPENRISC",    92, "OpenRISC 32-bit embedded processor")
+    , ("_ARC_A5",      93, "ARC Cores Tangent-A5")
+    , ("_XTENSA",      94, "Tensilica Xtensa Architecture")
+    , ("_VIDEOCORE",   95, "Alphamosaic VideoCore processor")
+    , ("_TMM_GPP",     96, "Thompson Multimedia General Purpose Processor")
+    , ("_NS32K",       97, "National Semiconductor 32000 series")
+    , ("_TPC",         98, "Tenor Network TPC processor")
+    , ("_SNP1K",       99, "Trebia SNP 1000 processor")
+    , ("_ST200",      100, "STMicroelectronics (www.st.com) ST200 microcontroller")
+    , ("_IP2K",       101, "Ubicom IP2xxx microcontroller family")
+    , ("_MAX",        102, "MAX Processor")
+    , ("_CR",         103, "National Semiconductor CompactRISC microprocessor")
+    , ("_F2MC16",     104, "Fujitsu F2MC16")
+    , ("_MSP430",     105, "Texas Instruments embedded microcontroller msp430")
+    , ("_BLACKFIN",   106, "Analog Devices Blackfin (DSP) processor")
+    , ("_SE_C33",     107, "S1C33 Family of Seiko Epson processors")
+    , ("_SEP",        108, "Sharp embedded microprocessor")
+    , ("_ARCA",       109, "Arca RISC Microprocessor")
+    , ("_UNICORE",    110, "Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University")
+    , ("_AARCH64",    183, "ELF for the Arm 64-bit Architecture (AArch64)")
     ])
 
 -- | Section type
-$(mkDeclarations BaseWord32 "ElfSectionType" "SHT" "SHT_EXT"
-    [ ("_NULL",     0) -- Identifies an empty section header.
-    , ("_PROGBITS", 1) -- Contains information defined by the program
-    , ("_SYMTAB",   2) -- Contains a linker symbol table
-    , ("_STRTAB",   3) -- Contains a string table
-    , ("_RELA",     4) -- Contains "Rela" type relocation entries
-    , ("_HASH",     5) -- Contains a symbol hash table
-    , ("_DYNAMIC",  6) -- Contains dynamic linking tables
-    , ("_NOTE",     7) -- Contains note information
-    , ("_NOBITS",   8) -- Contains uninitialized space; does not occupy any space in the file
-    , ("_REL",      9) -- Contains "Rel" type relocation entries
-    , ("_SHLIB",   10) -- Reserved
-    , ("_DYNSYM",  11) -- Contains a dynamic loader symbol table
+$(mkDeclarations BaseWord32 "ElfSectionType" "SHT"
+    [ ("_NULL",     0, "Identifies an empty section header.")
+    , ("_PROGBITS", 1, "Contains information defined by the program")
+    , ("_SYMTAB",   2, "Contains a linker symbol table")
+    , ("_STRTAB",   3, "Contains a string table")
+    , ("_RELA",     4, "Contains \"Rela\" type relocation entries")
+    , ("_HASH",     5, "Contains a symbol hash table")
+    , ("_DYNAMIC",  6, "Contains dynamic linking tables")
+    , ("_NOTE",     7, "Contains note information")
+    , ("_NOBITS",   8, "Contains uninitialized space; does not occupy any space in the file")
+    , ("_REL",      9, "Contains \"Rel\" type relocation entries")
+    , ("_SHLIB",   10, "Reserved")
+    , ("_DYNSYM",  11, "Contains a dynamic loader symbol table")
     ])
 
 -- | Segment type
-$(mkDeclarations BaseWord32 "ElfSegmentType" "PT" "PT_EXT"
-    [ ("_NULL",    0) -- Unused entry
-    , ("_LOAD",    1) -- Loadable segment
-    , ("_DYNAMIC", 2) -- Dynamic linking tables
-    , ("_INTERP",  3) -- Program interpreter path name
-    , ("_NOTE",    4) -- Note section
-    , ("_SHLIB",   5) -- Reserved
-    , ("_PHDR",    6) -- Program header table
+$(mkDeclarations BaseWord32 "ElfSegmentType" "PT"
+    [ ("_NULL",    0, "Unused entry")
+    , ("_LOAD",    1, "Loadable segment")
+    , ("_DYNAMIC", 2, "Dynamic linking tables")
+    , ("_INTERP",  3, "Program interpreter path name")
+    , ("_NOTE",    4, "Note section")
+    , ("_SHLIB",   5, "Reserved")
+    , ("_PHDR",    6, "Program header table")
     ])
 
 -- | Attributes of the section
-$(mkDeclarations BaseWord64 "ElfSectionFlag" "SHF" "SHF_EXT"
-    [ ("_WRITE",     1 `shiftL` 0) -- Section contains writable data
-    , ("_ALLOC",     1 `shiftL` 1) -- Section is allocated in memory image of program
-    , ("_EXECINSTR", 1 `shiftL` 2) -- Section contains executable instructions
+$(mkDeclarations BaseWord64 "ElfSectionFlag" "SHF"
+    [ ("_WRITE",     1 `shiftL` 0, "Section contains writable data")
+    , ("_ALLOC",     1 `shiftL` 1, "Section is allocated in memory image of program")
+    , ("_EXECINSTR", 1 `shiftL` 2, "Section contains executable instructions")
     ])
 
 -- | Attributes of the segment
-$(mkDeclarations BaseWord32 "ElfSegmentFlag" "PF" "PF_EXT"
-    [ ("_X", 1 `shiftL` 0) -- Execute permission
-    , ("_W", 1 `shiftL` 1) -- Write permission
-    , ("_R", 1 `shiftL` 2) -- Read permission
+$(mkDeclarations BaseWord32 "ElfSegmentFlag" "PF"
+    [ ("_X", 1 `shiftL` 0, "Execute permission")
+    , ("_W", 1 `shiftL` 1, "Write permission")
+    , ("_R", 1 `shiftL` 2, "Read permission")
     ])
 
 -- | Symbol type
-$(mkDeclarations BaseWord8 "ElfSymbolType" "STT" "STT_EXT"
-    [ ("_NoType",  0)
-    , ("_Object",  1)
-    , ("_Func",    2)
-    , ("_Section", 3)
-    , ("_File",    4)
-    , ("_Common",  5)
-    , ("_TLS",     6)
-    , ("_LoOS",   10)
-    , ("_HiOS",   12)
-    , ("_LoProc", 13)
-    , ("_HiProc", 15)
+$(mkDeclarations BaseWord8 "ElfSymbolType" "STT"
+    [ ("_NoType",  0, "NoType")
+    , ("_Object",  1, "Object")
+    , ("_Func",    2, "Func")
+    , ("_Section", 3, "Section")
+    , ("_File",    4, "File")
+    , ("_Common",  5, "Common")
+    , ("_TLS",     6, "TLS")
+    , ("_LoOS",   10, "LoOS")
+    , ("_HiOS",   12, "HiOS")
+    , ("_LoProc", 13, "LoProc")
+    , ("_HiProc", 15, "HiProc")
     ])
 
 -- | Symbol binding
-$(mkDeclarations BaseWord8 "ElfSymbolBinding" "STB" "STB_EXT"
-    [ ("_Local",   0)
-    , ("_Global",  1)
-    , ("_Weak",    2)
-    , ("_LoOS",   10)
-    , ("_HiOS",   12)
-    , ("_LoProc", 13)
-    , ("_HiProc", 15)
+$(mkDeclarations BaseWord8 "ElfSymbolBinding" "STB"
+    [ ("_Local",   0, "")
+    , ("_Global",  1, "")
+    , ("_Weak",    2, "")
+    , ("_LoOS",   10, "")
+    , ("_HiOS",   12, "")
+    , ("_LoProc", 13, "")
+    , ("_HiProc", 15, "")
     ])
 
 -- | Section index
-$(mkDeclarations BaseWord16 "ElfSectionIndex" "SHN" "SHN_EXT"
-    [ ("_Undef",       0)
-    , ("_LoProc", 0xFF00)
-    , ("_HiProc", 0xFF1F)
-    , ("_LoOS",   0xFF20)
-    , ("_HiOS",   0xFF3F)
-    , ("_Abs",    0xFFF1)
-    , ("_Common", 0xFFF2)
+$(mkDeclarations BaseWord16 "ElfSectionIndex" "SHN"
+    [ ("_Undef",       0, "")
+    , ("_LoProc", 0xFF00, "")
+    , ("_HiProc", 0xFF1F, "")
+    , ("_LoOS",   0xFF20, "")
+    , ("_HiOS",   0xFF3F, "")
+    , ("_Abs",    0xFFF1, "")
+    , ("_Common", 0xFFF2, "")
     ])
 
 -- | AARCH64 relocation type
-$(mkDeclarations BaseWord32 "ElfRelocationType_AARCH64" "R_AARCH64" "R_AARCH64_EXT"
+$(mkDeclarations BaseWord32 "ElfRelocationType_AARCH64" "R_AARCH64"
 
     -- Null relocation codes
 
-    [ ("_NONE",  0  ) -- None
-    , ("_NONE_", 256) -- None
+    [ ("_NONE",  0,   "None")
+    , ("_NONE_", 256, "None")
 
     -- Data relocations
 
-    , ("_ABS64",  257) -- S + A     | No overflow check
-    , ("_ABS32",  258) -- S + A     | Check that -2^31 <= X < 2^32
-    , ("_ABS16",  259) -- S + A     | Check that -2^15 <= X < 2^16
-    , ("_PREL64", 260) -- S + A - P | No overflow check
-    , ("_PREL32", 261) -- S + A - P | Check that -2^31 <= X < 2^32
-    , ("_PREL16", 262) -- S + A - P | Check that -2^15 <= X < 2^16
-    , ("_PLT32",  314) -- S + A - P | Check that -2^31 <= X < 2^31 see call and jump relocations
+    , ("_ABS64",  257, "S + A     | No overflow check")
+    , ("_ABS32",  258, "S + A     | Check that -2^31 <= X < 2^32")
+    , ("_ABS16",  259, "S + A     | Check that -2^15 <= X < 2^16")
+    , ("_PREL64", 260, "S + A - P | No overflow check")
+    , ("_PREL32", 261, "S + A - P | Check that -2^31 <= X < 2^32")
+    , ("_PREL16", 262, "S + A - P | Check that -2^15 <= X < 2^16")
+    , ("_PLT32",  314, "S + A - P | Check that -2^31 <= X < 2^31 see call and jump relocations")
 
     -- Group relocations to create a 16-, 32-, 48-, or 64-bit unsigned data value or address inline
 
-    , ("_MOVW_UABS_G0",    263) -- S + A | Set a MOV[KZ] immediate field to bits [15: 0] of X; check that 0 <= X < 2^16
-    , ("_MOVW_UABS_G0_NC", 264) -- S + A | Set a MOV[KZ] immediate field to bits [15: 0] of X. No overflow check
-    , ("_MOVW_UABS_G1",    265) -- S + A | Set a MOV[KZ] immediate field to bits [31:16] of X; check that 0 <= X < 2^32
-    , ("_MOVW_UABS_G1_NC", 266) -- S + A | Set a MOV[KZ] immediate field to bits [31:16] of X. No overflow check
-    , ("_MOVW_UABS_G2",    267) -- S + A | Set a MOV[KZ] immediate field to bits [47:32] of X; check that 0 <= X < 2^48
-    , ("_MOVW_UABS_G2_NC", 268) -- S + A | Set a MOV[KZ] immediate field to bits [47:32] of X. No overflow check
-    , ("_MOVW_UABS_G3",    269) -- S + A | Set a MOV[KZ] immediate field to bits [63:48] of X (no overflow check needed)
+    , ("_MOVW_UABS_G0",    263, "S + A | Set a MOV[KZ] immediate field to bits [15: 0] of X; check that 0 <= X < 2^16")
+    , ("_MOVW_UABS_G0_NC", 264, "S + A | Set a MOV[KZ] immediate field to bits [15: 0] of X. No overflow check")
+    , ("_MOVW_UABS_G1",    265, "S + A | Set a MOV[KZ] immediate field to bits [31:16] of X; check that 0 <= X < 2^32")
+    , ("_MOVW_UABS_G1_NC", 266, "S + A | Set a MOV[KZ] immediate field to bits [31:16] of X. No overflow check")
+    , ("_MOVW_UABS_G2",    267, "S + A | Set a MOV[KZ] immediate field to bits [47:32] of X; check that 0 <= X < 2^48")
+    , ("_MOVW_UABS_G2_NC", 268, "S + A | Set a MOV[KZ] immediate field to bits [47:32] of X. No overflow check")
+    , ("_MOVW_UABS_G3",    269, "S + A | Set a MOV[KZ] immediate field to bits [63:48] of X (no overflow check needed)")
 
     -- Group relocations to create a 16, 32, 48, or 64 bit signed data or offset value inline
 
-    , ("_MOVW_SABS_G0", 270) --  S + A | Set a MOV[NZ] immediate field using bits [15: 0] of X; check -2^16 <= X < 2^16
-    , ("_MOVW_SABS_G1", 271) --  S + A | Set a MOV[NZ] immediate field using bits [31:16] of X; check -2^32 <= X < 2^32
-    , ("_MOVW_SABS_G2", 272) --  S + A | Set a MOV[NZ] immediate field using bits [47:32] of X; check -2^48 <= X < 2^48
+    , ("_MOVW_SABS_G0", 270, "S + A | Set a MOV[NZ] immediate field using bits [15: 0] of X; check -2^16 <= X < 2^16")
+    , ("_MOVW_SABS_G1", 271, "S + A | Set a MOV[NZ] immediate field using bits [31:16] of X; check -2^32 <= X < 2^32")
+    , ("_MOVW_SABS_G2", 272, "S + A | Set a MOV[NZ] immediate field using bits [47:32] of X; check -2^48 <= X < 2^48")
 
     -- Relocations to generate 19, 21 and 33 bit PC-relative addresses
 
-    , ("_LD_PREL_LO19",        273) -- S + A - P             | Set a load-literal immediate value to bits [20:2] of X; check that -2^20 <= X < 2^20
-    , ("_ADR_PREL_LO21",       274) -- S + A - P             | Set an ADR immediate value to bits [20:0] of X; check that -2^20 <= X < 2^20
-    , ("_ADR_PREL_PG_HI21",    275) -- Page(S + A) - Page(P) | Set an ADRP immediate value to bits [32:12] of the X; check that -2^32 <= X < 2^32
-    , ("_ADR_PREL_PG_HI21_NC", 276) -- Page(S + A) - Page(P) | Set an ADRP immediate value to bits [32:12] of the X. No overflow check
-    , ("_ADD_ABS_LO12_NC",     277) -- S + A                 | Set an ADD immediate value to bits [11:0] of X. No overflow check. Used with relocations ADR_PREL_PG_HI21 and ADR_PREL_PG_HI21_NC
-    , ("_LDST8_ABS_LO12_NC",   278) -- S + A                 | Set an LD/ST immediate value to bits [11:0] of X. No overflow check. Used with relocations ADR_PREL_PG_HI21 and ADR_PREL_PG_HI21_NC
-    , ("_LDST16_ABS_LO12_NC",  284) -- S + A                 | Set an LD/ST immediate value to bits [11:1] of X. No overflow check
-    , ("_LDST32_ABS_LO12_NC",  285) -- S + A                 | Set the LD/ST immediate value to bits [11:2] of X. No overflow check
-    , ("_LDST64_ABS_LO12_NC",  286) -- S + A                 | Set the LD/ST immediate value to bits [11:3] of X. No overflow check
-    , ("_LDST128_ABS_LO12_NC", 299) -- S + A                 | Set the LD/ST immediate value to bits [11:4] of X. No overflow check
+    , ("_LD_PREL_LO19",        273, "S + A - P             | Set a load-literal immediate value to bits [20:2] of X; check that -2^20 <= X < 2^20")
+    , ("_ADR_PREL_LO21",       274, "S + A - P             | Set an ADR immediate value to bits [20:0] of X; check that -2^20 <= X < 2^20")
+    , ("_ADR_PREL_PG_HI21",    275, "Page(S + A) - Page(P) | Set an ADRP immediate value to bits [32:12] of the X; check that -2^32 <= X < 2^32")
+    , ("_ADR_PREL_PG_HI21_NC", 276, "Page(S + A) - Page(P) | Set an ADRP immediate value to bits [32:12] of the X. No overflow check")
+    , ("_ADD_ABS_LO12_NC",     277, "S + A                 | Set an ADD immediate value to bits [11:0] of X. No overflow check. Used with relocations ADR_PREL_PG_HI21 and ADR_PREL_PG_HI21_NC")
+    , ("_LDST8_ABS_LO12_NC",   278, "S + A                 | Set an LD/ST immediate value to bits [11:0] of X. No overflow check. Used with relocations ADR_PREL_PG_HI21 and ADR_PREL_PG_HI21_NC")
+    , ("_LDST16_ABS_LO12_NC",  284, "S + A                 | Set an LD/ST immediate value to bits [11:1] of X. No overflow check")
+    , ("_LDST32_ABS_LO12_NC",  285, "S + A                 | Set the LD/ST immediate value to bits [11:2] of X. No overflow check")
+    , ("_LDST64_ABS_LO12_NC",  286, "S + A                 | Set the LD/ST immediate value to bits [11:3] of X. No overflow check")
+    , ("_LDST128_ABS_LO12_NC", 299, "S + A                 | Set the LD/ST immediate value to bits [11:4] of X. No overflow check")
 
     -- Relocations for control-flow instructions - all offsets are a multiple of 4
 
-    , ("_TSTBR14",  279) -- S + A - P | Set the immediate field of a TBZ/TBNZ instruction to bits [15:2] of X; check -2^15 <= X < 2^15
-    , ("_CONDBR19", 280) -- S + A - P | Set the immediate field of a conditional branch instruction to bits [20:2] of X; check -2^20 <= X< 2^20
-    , ("_JUMP26",   282) -- S + A - P | Set a B immediate field to bits [27:2] of X; check that -2^27 <= X < 2^27
-    , ("_CALL26",   283) -- S + A - P | Set a CALL immediate field to bits [27:2] of X; check that -2^27 <= X < 2^27
+    , ("_TSTBR14",  279, "S + A - P | Set the immediate field of a TBZ/TBNZ instruction to bits [15:2] of X; check -2^15 <= X < 2^15")
+    , ("_CONDBR19", 280, "S + A - P | Set the immediate field of a conditional branch instruction to bits [20:2] of X; check -2^20 <= X< 2^20")
+    , ("_JUMP26",   282, "S + A - P | Set a B immediate field to bits [27:2] of X; check that -2^27 <= X < 2^27")
+    , ("_CALL26",   283, "S + A - P | Set a CALL immediate field to bits [27:2] of X; check that -2^27 <= X < 2^27")
 
     -- Group relocations to create a 16, 32, 48, or 64 bit PC-relative offset inline
 
-    , ("_MOVW_PREL_G0",    287) -- S + A - P | Set a MOV[NZ]immediate field to bits [15:0] of X
-    , ("_MOVW_PREL_G0_NC", 288) -- S + A - P | Set a MOVK immediate field to bits [15:0] of X. No overflow check
-    , ("_MOVW_PREL_G1",    289) -- S + A - P | Set a MOV[NZ]immediate field to bits [31:16] of X
-    , ("_MOVW_PREL_G1_NC", 290) -- S + A - P | Set a MOVK immediate field to bits [31:16] of X. No overflow check
-    , ("_MOVW_PREL_G2",    291) -- S + A - P | Set a MOV[NZ]immediate value to bits [47:32] of X
-    , ("_MOVW_PREL_G2_NC", 292) -- S + A - P | Set a MOVK immediate field to bits [47:32] of X. No overflow check
-    , ("_MOVW_PREL_G3",    293) -- S + A - P | Set a MOV[NZ]immediate value to bits [63:48] of X
+    , ("_MOVW_PREL_G0",    287, "S + A - P | Set a MOV[NZ]immediate field to bits [15:0] of X")
+    , ("_MOVW_PREL_G0_NC", 288, "S + A - P | Set a MOVK immediate field to bits [15:0] of X. No overflow check")
+    , ("_MOVW_PREL_G1",    289, "S + A - P | Set a MOV[NZ]immediate field to bits [31:16] of X")
+    , ("_MOVW_PREL_G1_NC", 290, "S + A - P | Set a MOVK immediate field to bits [31:16] of X. No overflow check")
+    , ("_MOVW_PREL_G2",    291, "S + A - P | Set a MOV[NZ]immediate value to bits [47:32] of X")
+    , ("_MOVW_PREL_G2_NC", 292, "S + A - P | Set a MOVK immediate field to bits [47:32] of X. No overflow check")
+    , ("_MOVW_PREL_G3",    293, "S + A - P | Set a MOV[NZ]immediate value to bits [63:48] of X")
 
     -- Group relocations to create a 16, 32, 48, or 64 bit GOT-relative offsets inline
 
-    , ("_MOVW_GOTOFF_G0",    300) -- G(GDAT(S + A)) - GOT | Set a MOV[NZ] immediate field to bits [15:0] of X
-    , ("_MOVW_GOTOFF_G0_NC", 301) -- G(GDAT(S + A)) - GOT | Set a MOVK immediate field to bits [15:0] of X. No overflow check
-    , ("_MOVW_GOTOFF_G1",    302) -- G(GDAT(S + A)) - GOT | Set a MOV[NZ] immediate value to bits [31:16] of X
-    , ("_MOVW_GOTOFF_G1_NC", 303) -- G(GDAT(S + A)) - GOT | Set a MOVK immediate value to bits [31:16] of X. No overflow check
-    , ("_MOVW_GOTOFF_G2",    304) -- G(GDAT(S + A)) - GOT | Set a MOV[NZ] immediate value to bits [47:32] of X
-    , ("_MOVW_GOTOFF_G2_NC", 305) -- G(GDAT(S + A)) - GOT | Set a MOVK immediate value to bits [47:32] of X. No overflow check
-    , ("_MOVW_GOTOFF_G3",    306) -- G(GDAT(S + A)) - GOT | Set a MOV[NZ] immediate value to bits [63:48] of X
+    , ("_MOVW_GOTOFF_G0",    300, "G(GDAT(S + A)) - GOT | Set a MOV[NZ] immediate field to bits [15:0] of X")
+    , ("_MOVW_GOTOFF_G0_NC", 301, "G(GDAT(S + A)) - GOT | Set a MOVK immediate field to bits [15:0] of X. No overflow check")
+    , ("_MOVW_GOTOFF_G1",    302, "G(GDAT(S + A)) - GOT | Set a MOV[NZ] immediate value to bits [31:16] of X")
+    , ("_MOVW_GOTOFF_G1_NC", 303, "G(GDAT(S + A)) - GOT | Set a MOVK immediate value to bits [31:16] of X. No overflow check")
+    , ("_MOVW_GOTOFF_G2",    304, "G(GDAT(S + A)) - GOT | Set a MOV[NZ] immediate value to bits [47:32] of X")
+    , ("_MOVW_GOTOFF_G2_NC", 305, "G(GDAT(S + A)) - GOT | Set a MOVK immediate value to bits [47:32] of X. No overflow check")
+    , ("_MOVW_GOTOFF_G3",    306, "G(GDAT(S + A)) - GOT | Set a MOV[NZ] immediate value to bits [63:48] of X")
 
     -- GOT-relative data relocations
 
-    , ("_GOTREL64", 307) -- S + A - GOT | Set the data to a 64-bit offset relative to the GOT.
-    , ("_GOTREL32", 308) -- S + A - GOT | Set the data to a 32-bit offset relative to GOT, treated as signed; check that -2^31 <= X < 2^31
+    , ("_GOTREL64", 307, "S + A - GOT | Set the data to a 64-bit offset relative to the GOT")
+    , ("_GOTREL32", 308, "S + A - GOT | Set the data to a 32-bit offset relative to GOT, treated as signed; check that -2^31 <= X < 2^31")
 
     -- GOT-relative instruction relocations
 
-    , ("_GOT_LD_PREL19",     309) -- G(GDAT(S + A))- P             | Set a load-literal immediate field to bits [20:2] of X; check –2^20 <= X < 2^20
-    , ("_LD64_GOTOFF_LO15",  310) -- G(GDAT(S + A))- GOT           | Set a LD/ST immediate field to bits [14:3] of X; check that 0 <= X < 2^15 , X&7 = 0
-    , ("_ADR_GOT_PAGE",      311) -- Page(G(GDAT(S + A)))- Page(P) | Set the immediate value of an ADRP to bits [32:12] of X; check that –2^32 <= X < 2^32
-    , ("_LD64_GOT_LO12_NC",  312) -- G(GDAT(S + A))                | Set the LD/ST immediate field to bits [11:3] of X. No overflow check; check that X&7 = 0
-    , ("_LD64_GOTPAGE_LO15", 313) -- G(GDAT(S + A))- Page(GOT)     | Set the LD/ST immediate field to bits [14:3] of X; check that 0 <= X < 2^15, X&7 = 0
+    , ("_GOT_LD_PREL19",     309, "G(GDAT(S + A))- P             | Set a load-literal immediate field to bits [20:2] of X; check –2^20 <= X < 2^20")
+    , ("_LD64_GOTOFF_LO15",  310, "G(GDAT(S + A))- GOT           | Set a LD/ST immediate field to bits [14:3] of X; check that 0 <= X < 2^15 , X&7 = 0")
+    , ("_ADR_GOT_PAGE",      311, "Page(G(GDAT(S + A)))- Page(P) | Set the immediate value of an ADRP to bits [32:12] of X; check that –2^32 <= X < 2^32")
+    , ("_LD64_GOT_LO12_NC",  312, "G(GDAT(S + A))                | Set the LD/ST immediate field to bits [11:3] of X. No overflow check; check that X&7 = 0")
+    , ("_LD64_GOTPAGE_LO15", 313, "G(GDAT(S + A))- Page(GOT)     | Set the LD/ST immediate field to bits [14:3] of X; check that 0 <= X < 2^15, X&7 = 0")
 
     -- Local Dynamic TLS relocations
 
-    , ("_TLSLD_ADR_PREL21",             517) -- G(GLDM(S))) - P            | Set an ADR immediate field to  bits [20:0] of X; check –2^20 <= X < 2^20
-    , ("_TLSLD_ADR_PAGE21",             518) -- Page(G(GLDM(S))) - Page(P) | Set an ADRP immediate field to bits [32:12] of X; check –2^32 <= X < 2^32
-    , ("_TLSLD_ADD_LO12_NC",            519) -- G(GLDM(S))                 | Set an ADD immediate field to bits [11:0] of X. No overflow check
-    , ("_TLSLD_MOVW_G1",                520) -- G(GLDM(S)) - GOT           | Set a MOV[NZ] immediate field to bits [31:16] of X
-    , ("_TLSLD_MOVW_G0_NC",             521) -- G(GLDM(S)) - GOT           | Set a MOVK immediate field to bits [15:0] of X. No overflow check
-    , ("_TLSLD_LD_PREL19",              522) -- G(GLDM(S)) - P             | Set a load-literal immediate field to bits [20:2] of X; check –2^20 <= X < 2^20
-    , ("_TLSLD_MOVW_DTPREL_G2",         523) -- DTPREL(S+A)                | Set a MOV[NZ] immediate field to bits [47:32] of X
-    , ("_TLSLD_MOVW_DTPREL_G1",         524) -- DTPREL(S+A)                | Set a MOV[NZ] immediate field to bits [31:16] of X
-    , ("_TLSLD_MOVW_DTPREL_G1_NC",      525) -- DTPREL(S+A)                | Set a MOVK immediate field to bits [31:16] of X. No overflow check
-    , ("_TLSLD_MOVW_DTPREL_G0",         526) -- DTPREL(S+A)                | Set a MOV[NZ] immediate field to bits [15:0] of X
-    , ("_TLSLD_MOVW_DTPREL_G0_NC",      527) -- DTPREL(S+A)                | Set a MOVK immediate field to bits [15:0] of X. No overflow check
-    , ("_TLSLD_ADD_DTPREL_HI12",        528) -- DTPREL(S+A)                | Set an ADD immediate field to bits [23:12] of X; check 0 <= X < 2^24
-    , ("_TLSLD_ADD_DTPREL_LO12",        529) -- DTPREL(S+A)                | Set an ADD immediate field to bits [11:0] of X; check 0 <= X < 2^12
-    , ("_TLSLD_ADD_DTPREL_LO12_NC",     530) -- DTPREL(S+A)                | Set an ADD immediate field to bits [11:0] of X. No overflow check
-    , ("_TLSLD_LDST8_DTPREL_LO12",      531) -- DTPREL(S+A)                | Set a LD/ST offset field to bits [11:0] of X; check 0 <= X < 2^12
-    , ("_TLSLD_LDST8_DTPREL_LO12_NC",   532) -- DTPREL(S+A)                | Set a LD/ST offset field to bits [11:0] of X. No overflow check
-    , ("_TLSLD_LDST16_DTPREL_LO12",     533) -- DTPREL(S+A)                | Set a LD/ST offset field to bits [11:1] of X; check 0 <= X < 2^12
-    , ("_TLSLD_LDST16_DTPREL_LO12_NC",  534) -- DTPREL(S+A)                | Set a LD/ST offset field to bits [11:1] of X. No overflow check
-    , ("_TLSLD_LDST32_DTPREL_LO12",     535) -- DTPREL(S+A)                | Set a LD/ST offset field to bits [11:2] of X; check 0 <= X < 2^12
-    , ("_TLSLD_LDST32_DTPREL_LO12_NC",  536) -- DTPREL(S+A)                | Set a LD/ST offset field to bits [11:2] of X. No overflow check
-    , ("_TLSLD_LDST64_DTPREL_LO12",     537) -- DTPREL(S+A)                | Set a LD/ST offset field to bits [11:3] of X; check 0 <= X < 2^12
-    , ("_TLSLD_LDST64_DTPREL_LO12_NC",  538) -- DTPREL(S+A)                | Set a LD/ST offset field to bits [11:3] of X. No overflow check
-    , ("_TLSLD_LDST128_DTPREL_LO12",    572) -- DTPREL(S+A)                | Set a LD/ST offset field to bits [11:4] of X; check 0 <= X < 2^12
-    , ("_TLSLD_LDST128_DTPREL_LO12_NC", 573) -- DTPREL(S+A)                | Set a LD/ST offset field to bits [11:4] of X. No overflow check
+    , ("_TLSLD_ADR_PREL21",             517, "G(GLDM(S))) - P            | Set an ADR immediate field to  bits [20:0] of X; check –2^20 <= X < 2^20")
+    , ("_TLSLD_ADR_PAGE21",             518, "Page(G(GLDM(S))) - Page(P) | Set an ADRP immediate field to bits [32:12] of X; check –2^32 <= X < 2^32")
+    , ("_TLSLD_ADD_LO12_NC",            519, "G(GLDM(S))                 | Set an ADD immediate field to bits [11:0] of X. No overflow check")
+    , ("_TLSLD_MOVW_G1",                520, "G(GLDM(S)) - GOT           | Set a MOV[NZ] immediate field to bits [31:16] of X")
+    , ("_TLSLD_MOVW_G0_NC",             521, "G(GLDM(S)) - GOT           | Set a MOVK immediate field to bits [15:0] of X. No overflow check")
+    , ("_TLSLD_LD_PREL19",              522, "G(GLDM(S)) - P             | Set a load-literal immediate field to bits [20:2] of X; check –2^20 <= X < 2^20")
+    , ("_TLSLD_MOVW_DTPREL_G2",         523, "DTPREL(S+A)                | Set a MOV[NZ] immediate field to bits [47:32] of X")
+    , ("_TLSLD_MOVW_DTPREL_G1",         524, "DTPREL(S+A)                | Set a MOV[NZ] immediate field to bits [31:16] of X")
+    , ("_TLSLD_MOVW_DTPREL_G1_NC",      525, "DTPREL(S+A)                | Set a MOVK immediate field to bits [31:16] of X. No overflow check")
+    , ("_TLSLD_MOVW_DTPREL_G0",         526, "DTPREL(S+A)                | Set a MOV[NZ] immediate field to bits [15:0] of X")
+    , ("_TLSLD_MOVW_DTPREL_G0_NC",      527, "DTPREL(S+A)                | Set a MOVK immediate field to bits [15:0] of X. No overflow check")
+    , ("_TLSLD_ADD_DTPREL_HI12",        528, "DTPREL(S+A)                | Set an ADD immediate field to bits [23:12] of X; check 0 <= X < 2^24")
+    , ("_TLSLD_ADD_DTPREL_LO12",        529, "DTPREL(S+A)                | Set an ADD immediate field to bits [11:0] of X; check 0 <= X < 2^12")
+    , ("_TLSLD_ADD_DTPREL_LO12_NC",     530, "DTPREL(S+A)                | Set an ADD immediate field to bits [11:0] of X. No overflow check")
+    , ("_TLSLD_LDST8_DTPREL_LO12",      531, "DTPREL(S+A)                | Set a LD/ST offset field to bits [11:0] of X; check 0 <= X < 2^12")
+    , ("_TLSLD_LDST8_DTPREL_LO12_NC",   532, "DTPREL(S+A)                | Set a LD/ST offset field to bits [11:0] of X. No overflow check")
+    , ("_TLSLD_LDST16_DTPREL_LO12",     533, "DTPREL(S+A)                | Set a LD/ST offset field to bits [11:1] of X; check 0 <= X < 2^12")
+    , ("_TLSLD_LDST16_DTPREL_LO12_NC",  534, "DTPREL(S+A)                | Set a LD/ST offset field to bits [11:1] of X. No overflow check")
+    , ("_TLSLD_LDST32_DTPREL_LO12",     535, "DTPREL(S+A)                | Set a LD/ST offset field to bits [11:2] of X; check 0 <= X < 2^12")
+    , ("_TLSLD_LDST32_DTPREL_LO12_NC",  536, "DTPREL(S+A)                | Set a LD/ST offset field to bits [11:2] of X. No overflow check")
+    , ("_TLSLD_LDST64_DTPREL_LO12",     537, "DTPREL(S+A)                | Set a LD/ST offset field to bits [11:3] of X; check 0 <= X < 2^12")
+    , ("_TLSLD_LDST64_DTPREL_LO12_NC",  538, "DTPREL(S+A)                | Set a LD/ST offset field to bits [11:3] of X. No overflow check")
+    , ("_TLSLD_LDST128_DTPREL_LO12",    572, "DTPREL(S+A)                | Set a LD/ST offset field to bits [11:4] of X; check 0 <= X < 2^12")
+    , ("_TLSLD_LDST128_DTPREL_LO12_NC", 573, "DTPREL(S+A)                | Set a LD/ST offset field to bits [11:4] of X. No overflow check")
 
     -- Initial Exec TLS relocations
 
-    , ("_TLSIE_MOVW_GOTTPREL_G1",      539) -- G(GTPREL(S+A)) -               | GOT Set a MOV[NZ] immediate field to bits [31:16] of X
-    , ("_TLSIE_MOVW_GOTTPREL_G0_NC",   540) -- G(GTPREL(S+A)) -               | GOT Set MOVK immediate to bits [15:0] of X. No overflow check
-    , ("_TLSIE_ADR_GOTTPREL_PAGE21",   541) -- Page(G(GTPREL(S+A))) - Page(P) | Set an ADRP immediate field to bits [32:12] of X; check –2^32 <= X < 2^32
-    , ("_TLSIE_LD64_GOTTPREL_LO12_NC", 542) -- G(GTPREL(S+A))                 | Set an LD offset field to bits [11:3] of X. No overflow check; check that X&7=0
-    , ("_TLSIE_LD_GOTTPREL_PREL19",    543) -- G(GTPREL(S+A)) - P             | Set a load-literal immediate to bits [20:2] of X; check –2^20 <= X < 2^20
+    , ("_TLSIE_MOVW_GOTTPREL_G1",      539, "G(GTPREL(S+A)) -               | GOT Set a MOV[NZ] immediate field to bits [31:16] of X")
+    , ("_TLSIE_MOVW_GOTTPREL_G0_NC",   540, "G(GTPREL(S+A)) -               | GOT Set MOVK immediate to bits [15:0] of X. No overflow check")
+    , ("_TLSIE_ADR_GOTTPREL_PAGE21",   541, "Page(G(GTPREL(S+A))) - Page(P) | Set an ADRP immediate field to bits [32:12] of X; check –2^32 <= X < 2^32")
+    , ("_TLSIE_LD64_GOTTPREL_LO12_NC", 542, "G(GTPREL(S+A))                 | Set an LD offset field to bits [11:3] of X. No overflow check; check that X&7=0")
+    , ("_TLSIE_LD_GOTTPREL_PREL19",    543, "G(GTPREL(S+A)) - P             | Set a load-literal immediate to bits [20:2] of X; check –2^20 <= X < 2^20")
 
     -- Local Exec TLS relocations
 
-    , ("_TLSLE_MOVW_TPREL_G2",         544) -- TPREL(S+A) | Set a MOV[NZ] immediate field to bits [47:32] of X
-    , ("_TLSLE_MOVW_TPREL_G1",         545) -- TPREL(S+A) | Set a MOV[NZ] immediate field to bits [31:16] of X
-    , ("_TLSLE_MOVW_TPREL_G1_NC",      546) -- TPREL(S+A) | Set a MOVK immediate field to bits [31:16] of X. No overflow check
-    , ("_TLSLE_MOVW_TPREL_G0",         547) -- TPREL(S+A) | Set a MOV[NZ] immediate field to bits [15:0] of X
-    , ("_TLSLE_MOVW_TPREL_G0_NC",      548) -- TPREL(S+A) | Set a MOVK immediate field to bits [15:0] of X. No overflow check
-    , ("_TLSLE_ADD_TPREL_HI12",        549) -- TPREL(S+A) | Set an ADD immediate field to bits [23:12] of X; check 0 <= X < 2^24
-    , ("_TLSLE_ADD_TPREL_LO12",        550) -- TPREL(S+A) | Set an ADD immediate field to bits [11:0] of X; check 0 <= X < 2^12
-    , ("_TLSLE_ADD_TPREL_LO12_NC",     551) -- TPREL(S+A) | Set an ADD immediate field to bits [11:0] of X. No overflow check
-    , ("_TLSLE_LDST8_TPREL_LO12",      552) -- TPREL(S+A) | Set a LD/ST offset field to bits [11:0] of X; check 0 <= X < 2^12
-    , ("_TLSLE_LDST8_TPREL_LO12_NC",   553) -- TPREL(S+A) | Set a LD/ST offset field to bits [11:0] of X. No overflow check
-    , ("_TLSLE_LDST16_TPREL_LO12",     554) -- TPREL(S+A) | Set a LD/ST offset field to bits [11:1] of X; check 0 <= X < 2^12
-    , ("_TLSLE_LDST16_TPREL_LO12_NC",  555) -- TPREL(S+A) | Set a LD/ST offset field to bits [11:1] of X. No overflow check
-    , ("_TLSLE_LDST32_TPREL_LO12",     556) -- TPREL(S+A) | Set a LD/ST offset field to bits [11:2] of X; check 0 <= X < 2^12
-    , ("_TLSLE_LDST32_TPREL_LO12_NC",  557) -- TPREL(S+A) | Set a LD/ST offset field to bits [11:2] of X. No overflow check
-    , ("_TLSLE_LDST64_TPREL_LO12",     558) -- TPREL(S+A) | Set a LD/ST offset field to bits [11:3] of X; check 0 <= X < 2^12
-    , ("_TLSLE_LDST64_TPREL_LO12_NC",  559) -- TPREL(S+A) | Set a LD/ST offset field to bits [11:3] of X. No overflow check
-    , ("_TLSLE_LDST128_TPREL_LO12",    570) -- TPREL(S+A) | Set a LD/ST offset field to bits [11:4] of X; check 0 <= X < 2^12
-    , ("_TLSLE_LDST128_TPREL_LO12_NC", 571) -- TPREL(S+A) | Set a LD/ST offset field to bits [11:4] of X. No overflow check
+    , ("_TLSLE_MOVW_TPREL_G2",         544, "TPREL(S+A) | Set a MOV[NZ] immediate field to bits [47:32] of X")
+    , ("_TLSLE_MOVW_TPREL_G1",         545, "TPREL(S+A) | Set a MOV[NZ] immediate field to bits [31:16] of X")
+    , ("_TLSLE_MOVW_TPREL_G1_NC",      546, "TPREL(S+A) | Set a MOVK immediate field to bits [31:16] of X. No overflow check")
+    , ("_TLSLE_MOVW_TPREL_G0",         547, "TPREL(S+A) | Set a MOV[NZ] immediate field to bits [15:0] of X")
+    , ("_TLSLE_MOVW_TPREL_G0_NC",      548, "TPREL(S+A) | Set a MOVK immediate field to bits [15:0] of X. No overflow check")
+    , ("_TLSLE_ADD_TPREL_HI12",        549, "TPREL(S+A) | Set an ADD immediate field to bits [23:12] of X; check 0 <= X < 2^24")
+    , ("_TLSLE_ADD_TPREL_LO12",        550, "TPREL(S+A) | Set an ADD immediate field to bits [11:0] of X; check 0 <= X < 2^12")
+    , ("_TLSLE_ADD_TPREL_LO12_NC",     551, "TPREL(S+A) | Set an ADD immediate field to bits [11:0] of X. No overflow check")
+    , ("_TLSLE_LDST8_TPREL_LO12",      552, "TPREL(S+A) | Set a LD/ST offset field to bits [11:0] of X; check 0 <= X < 2^12")
+    , ("_TLSLE_LDST8_TPREL_LO12_NC",   553, "TPREL(S+A) | Set a LD/ST offset field to bits [11:0] of X. No overflow check")
+    , ("_TLSLE_LDST16_TPREL_LO12",     554, "TPREL(S+A) | Set a LD/ST offset field to bits [11:1] of X; check 0 <= X < 2^12")
+    , ("_TLSLE_LDST16_TPREL_LO12_NC",  555, "TPREL(S+A) | Set a LD/ST offset field to bits [11:1] of X. No overflow check")
+    , ("_TLSLE_LDST32_TPREL_LO12",     556, "TPREL(S+A) | Set a LD/ST offset field to bits [11:2] of X; check 0 <= X < 2^12")
+    , ("_TLSLE_LDST32_TPREL_LO12_NC",  557, "TPREL(S+A) | Set a LD/ST offset field to bits [11:2] of X. No overflow check")
+    , ("_TLSLE_LDST64_TPREL_LO12",     558, "TPREL(S+A) | Set a LD/ST offset field to bits [11:3] of X; check 0 <= X < 2^12")
+    , ("_TLSLE_LDST64_TPREL_LO12_NC",  559, "TPREL(S+A) | Set a LD/ST offset field to bits [11:3] of X. No overflow check")
+    , ("_TLSLE_LDST128_TPREL_LO12",    570, "TPREL(S+A) | Set a LD/ST offset field to bits [11:4] of X; check 0 <= X < 2^12")
+    , ("_TLSLE_LDST128_TPREL_LO12_NC", 571, "TPREL(S+A) | Set a LD/ST offset field to bits [11:4] of X. No overflow check")
 
     -- TLS descriptor relocations
 
-    , ("_TLSDESC_LD_PREL19",  560) -- G(GTLSDESC(S+A)) - P             | Set a load-literal immediate to bits [20:2]; check -2^20 <= X < 2^20 ; check X & 3 = 0
-    , ("_TLSDESC_ADR_PREL21", 561) -- G(GTLSDESC(S+A)) - P             | Set an ADR immediate field to bits [20:0]; check -2^20 <= X < 2^20
-    , ("_TLSDESC_ADR_PAGE21", 562) -- Page(G(GTLSDESC(S+A))) - Page(P) | Set an ADRP immediate field to bits [32:12] of X; check -2^32 <= X < 2^32
-    , ("_TLSDESC_LD64_LO12",  563) -- G(GTLSDESC(S+A))                 | Set an LD offset field to bits [11:3] of X. No overflow check; check X & 7 = 0.
-    , ("_TLSDESC_ADD_LO12",   564) -- G(GTLSDESC(S+A))                 | Set an ADD immediate field to bits [11:0] of X. No overflow check.
-    , ("_TLSDESC_OFF_G1",     565) -- G(GTLSDESC(S+A)) - GOT           | Set a MOV[NZ] immediate field to bits [31:16] of X; check -2^32 <= X < 2^32.
-    , ("_TLSDESC_OFF_G0_NC",  566) -- G(GTLSDESC(S+A)) - GOT           | Set a MOVK immediate field to bits [15:0] of X. No overflow check.
-    , ("_TLSDESC_LDR",        567) -- None                             | For relaxation only. Must be used to identify an LDR instruction which loads the TLS descriptor function pointer for S + A if it has no other relocation.
-    , ("_TLSDESC_ADD",        568) -- None                             | For relaxation only. Must be used to identify an ADD instruction which computes the address of the TLS Descriptor for S + A if it has no other relocation.
-    , ("_TLSDESC_CALL",       569) -- None                             | For relaxation only. Must be used to identify a BLR instruction which performs an indirect call to the TLS descriptor function for S + A.
+    , ("_TLSDESC_LD_PREL19",  560, "G(GTLSDESC(S+A)) - P             | Set a load-literal immediate to bits [20:2]; check -2^20 <= X < 2^20 ; check X & 3 = 0")
+    , ("_TLSDESC_ADR_PREL21", 561, "G(GTLSDESC(S+A)) - P             | Set an ADR immediate field to bits [20:0]; check -2^20 <= X < 2^20")
+    , ("_TLSDESC_ADR_PAGE21", 562, "Page(G(GTLSDESC(S+A))) - Page(P) | Set an ADRP immediate field to bits [32:12] of X; check -2^32 <= X < 2^32")
+    , ("_TLSDESC_LD64_LO12",  563, "G(GTLSDESC(S+A))                 | Set an LD offset field to bits [11:3] of X. No overflow check; check X & 7 = 0")
+    , ("_TLSDESC_ADD_LO12",   564, "G(GTLSDESC(S+A))                 | Set an ADD immediate field to bits [11:0] of X. No overflow check")
+    , ("_TLSDESC_OFF_G1",     565, "G(GTLSDESC(S+A)) - GOT           | Set a MOV[NZ] immediate field to bits [31:16] of X; check -2^32 <= X < 2^32")
+    , ("_TLSDESC_OFF_G0_NC",  566, "G(GTLSDESC(S+A)) - GOT           | Set a MOVK immediate field to bits [15:0] of X. No overflow check")
+    , ("_TLSDESC_LDR",        567, "None                             | For relaxation only. Must be used to identify an LDR instruction which loads the TLS descriptor function pointer for S + A if it has no other relocation")
+    , ("_TLSDESC_ADD",        568, "None                             | For relaxation only. Must be used to identify an ADD instruction which computes the address of the TLS Descriptor for S + A if it has no other relocation")
+    , ("_TLSDESC_CALL",       569, "None                             | For relaxation only. Must be used to identify a BLR instruction which performs an indirect call to the TLS descriptor function for S + A")
 
     -- Dynamic relocations
 
-    , ("_COPY",       1024) --
-    , ("_GLOB_DAT",   1025) -- S + A
-    , ("_JUMP_SLOT",  1026) -- S + A
-    , ("_RELATIVE",   1027) -- Delta(S + A)
-    , ("_TLS_DTPMOD", 1028) -- DTPREL(S + A)
-    , ("_TLS_DTPREL", 1029) -- LDM(S)
-    , ("_TLS_TPREL",  1030) -- TPREL(S + A)
-    , ("_TLSDESC",    1031) -- TLSDESC(S + A)
-    , ("_IRELATIVE",  1032) -- Indirect(Delta(S) + A)
+    , ("_COPY",       1024,  "")
+    , ("_GLOB_DAT",   1025,  "S + A")
+    , ("_JUMP_SLOT",  1026,  "S + A")
+    , ("_RELATIVE",   1027,  "Delta(S + A)")
+    , ("_TLS_DTPMOD", 1028,  "DTPREL(S + A)")
+    , ("_TLS_DTPREL", 1029,  "LDM(S)")
+    , ("_TLS_TPREL",  1030,  "TPREL(S + A)")
+    , ("_TLSDESC",    1031,  "TLSDESC(S + A)")
+    , ("_IRELATIVE",  1032,  "Indirect(Delta(S) + A)")
 
     ])
diff --git a/src/Data/Elf/Constants/TH.hs b/src/Data/Elf/Constants/TH.hs
--- a/src/Data/Elf/Constants/TH.hs
+++ b/src/Data/Elf/Constants/TH.hs
@@ -1,4 +1,4 @@
-{-# OPTIONS_GHC -Wall -fwarn-tabs #-}
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE TemplateHaskell #-}
 
 module Data.Elf.Constants.TH ( mkDeclarations
@@ -7,6 +7,9 @@
 
 import Control.Monad
 import Language.Haskell.TH
+#if MIN_VERSION_template_haskell(2,18,0)
+import Language.Haskell.TH.Syntax
+#endif
 
 data BaseWord = BaseWord8 | BaseWord16 | BaseWord32 | BaseWord64
 
@@ -15,12 +18,11 @@
     n <- newName s
     return (varP n, varE n)
 
-mkDeclarations :: BaseWord -> String -> String -> String -> [(String, Integer)] -> Q [Dec]
-mkDeclarations baseType typeNameString patternPrefixString defaultPatternNameString enums = do
+mkDeclarations :: BaseWord -> String -> String -> [(String, Integer, String)] -> Q [Dec]
+mkDeclarations baseType typeNameString patternPrefixString enums = do
 
     let typeName = mkName typeNameString
     let patternName s = mkName (patternPrefixString ++ s)
-    let defaultPatternName = mkName defaultPatternNameString
     let
         baseTypeT :: Q Type
         baseTypeT =
@@ -50,7 +52,7 @@
                 ]
 
     let
-        mkShowClause (s, n) =
+        mkShowClause (s, n, _) =
             clause
                 [ conP typeName [litP $ IntegerL n] ]
                 (normalB [| patternPrefixString ++ s |])
@@ -65,7 +67,7 @@
         defaultShowClause =
             clause
                 [ conP typeName [nP] ]
-                (normalB [| defaultPatternNameString ++ " " ++ show $(nE) |])
+                (normalB [| typeNameString ++ " " ++ show $(nE) |])
                 []
 
     let showInstanceFunctions = funD (mkName "show") (showClauses ++ [ defaultShowClause ])
@@ -132,7 +134,7 @@
                 BaseWord64 -> binaryInstancesXe [| putWord64le |] [| getWord64le |] [| putWord64be |] [| getWord64be |]
 
     let
-        mkPatterns (s, n) =
+        mkPatterns (s, n, _) =
             [ patSynSigD
                 (patternName s)
                 (conT typeName)
@@ -143,23 +145,12 @@
                 (conP typeName [litP $ IntegerL n])
             ]
 
-    let
-        defaultPatternSig =
-            patSynSigD
-                defaultPatternName
-                (appT (appT arrowT baseTypeT) (conT typeName))
-
-    localName3 <- newName "n"
+    let patterns = join (map mkPatterns enums)
 
-    let
-        defaultPatternDef :: Q Dec
-        defaultPatternDef =
-            patSynD
-                defaultPatternName
-                (prefixPatSyn [localName3])
-                implBidir
-                (conP typeName [varP localName3])
+#if MIN_VERSION_template_haskell(2,18,0)
+    let mkPatternDocs (s, _, doc) = putDoc (DeclDoc $ patternName s) doc
 
-    let patterns = join (map mkPatterns enums) ++ [ defaultPatternSig, defaultPatternDef ]
+    mapM_ (addModFinalizer . mkPatternDocs) enums
+#endif
 
     sequence $ newTypeDef : showInstance : patterns ++ binaryInstances
diff --git a/src/Data/Elf/Headers.hs b/src/Data/Elf/Headers.hs
--- a/src/Data/Elf/Headers.hs
+++ b/src/Data/Elf/Headers.hs
@@ -18,6 +18,7 @@
 {-# LANGUAGE FunctionalDependencies #-}
 {-# LANGUAGE GADTSyntax #-}
 {-# LANGUAGE InstanceSigs #-}
+{-# LANGUAGE PolyKinds #-}
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE RecordWildCards #-}
 {-# LANGUAGE ScopedTypeVariables #-}
@@ -28,52 +29,46 @@
 {-# LANGUAGE TypeOperators #-}
 {-# LANGUAGE UndecidableInstances #-}
 
-{-# LANGUAGE CPP #-}
-
-#if defined(MIN_VERSION_GLASGOW_HASKELL)
-#if MIN_VERSION_GLASGOW_HASKELL(8,10,0,0)
-{-# LANGUAGE StandaloneKindSignatures #-}
-#endif
-#endif
-
-{-# OPTIONS_GHC -Wno-unused-top-binds #-}
-
 module Data.Elf.Headers (
     -- * Data definition
       elfMagic
-    , ElfClass(..)
-    , SElfClass (..)
-    , ElfData(..)
+    , ElfClass (..)
+    , ElfData (..)
 
-    , IsElfClass(..)
-    , wordSize
+    -- * Singletons
+
+    , SingElfClass (..)
+    , SingElfClassI (..)
+    , withSingElfClass
+    , withSingElfClassI
+    , fromSingElfClass
     , withElfClass
 
     -- * Types of ELF header
-    , HeaderXX(..)
+    , HeaderXX (..)
     , headerSize
-    , Header
+    , Header (..)
 
     -- * Types of ELF tables
 
     -- ** Section table
-    , SectionXX(..)
+    , SectionXX (..)
     , sectionTableEntrySize
 
     -- ** Segment table
-    , SegmentXX(..)
+    , SegmentXX (..)
     , segmentTableEntrySize
 
     -- ** Sybmol table
-    , SymbolXX(..)
+    , SymbolXX (..)
     , symbolTableEntrySize
 
     -- ** Relocation table
-    , RelaXX(..)
+    , RelaXX (..)
     , relocationTableAEntrySize
 
     -- * Parse header and section and segment tables
-    , HeadersXX (..)
+    , Headers (..)
     , parseHeaders
 
     -- * Parse/serialize array of data
@@ -87,6 +82,9 @@
 
     -- * Misc helpers
     , sectionIsSymbolTable
+    , getSectionData
+    , getString
+    , wordSize
 
     ) where
 
@@ -98,31 +96,29 @@
 import Data.Bits
 import Data.ByteString       as BS
 import Data.ByteString.Lazy  as BSL
+import Data.ByteString.Lazy.Char8 as BSL8
 import Data.Data (Data)
+import Data.Int
+import Data.Kind
 import qualified Data.List as L
-import Data.Singletons.Sigma
-import Data.Singletons.TH
 import Data.Typeable (Typeable)
 
-#if MIN_VERSION_singletons(3,0,0)
-import Data.Eq.Singletons
-import Text.Show.Singletons
-import Data.Bool.Singletons
-#endif
-
 import Control.Exception.ChainedException
 import Data.BList
 import Data.Endian
 import Data.Elf.Constants
 
 -- | ELF class.  Tells if ELF defines 32- or 64-bit objects
-$(singletons [d|
-    data ElfClass
-        = ELFCLASS32 -- ^ 32-bit ELF format
-        | ELFCLASS64 -- ^ 64-bit ELF format
-        deriving (Eq, Show)
-    |])
+data ElfClass
+    = ELFCLASS32 -- ^ 32-bit ELF format
+    | ELFCLASS64 -- ^ 64-bit ELF format
+    deriving (Eq, Show)
 
+-- | Singletons for ElfClass
+data SingElfClass :: ElfClass -> Type where
+    SELFCLASS32 :: SingElfClass 'ELFCLASS32  -- ^ Singleton for `ELFCLASS32`
+    SELFCLASS64 :: SingElfClass 'ELFCLASS64  -- ^ Singleton for `ELFCLASS64`
+
 instance Binary ElfClass where
     get = getWord8 >>= getElfClass_
         where
@@ -205,10 +201,10 @@
 -- WordXX
 --------------------------------------------------------------------------
 
--- | @IsElfClass a@ is defined for each constructor of `ElfClass`.
+-- | @SingElfClassI a@ is defined for each constructor of `ElfClass`.
 --   It defines @WordXX a@, which is `Word32` for `ELFCLASS32` and `Word64` for `ELFCLASS64`.
-class ( SingI c
-      , Typeable c
+--   Also it defines singletons for each of the `ElfClass` type.
+class ( Typeable c
       , Typeable (WordXX c)
       , Data (WordXX c)
       , Show (WordXX c)
@@ -224,15 +220,45 @@
       , FiniteBits (WordXX c)
       , Binary (Be (WordXX c))
       , Binary (Le (WordXX c))
-      ) => IsElfClass (c :: ElfClass) where
+      ) => SingElfClassI (c :: ElfClass) where
     type WordXX c = r | r -> c
+    singElfClass :: SingElfClass c
 
-instance IsElfClass 'ELFCLASS32 where
+instance SingElfClassI 'ELFCLASS32 where
     type WordXX 'ELFCLASS32 = Word32
+    singElfClass = SELFCLASS32
 
-instance IsElfClass 'ELFCLASS64 where
+instance SingElfClassI 'ELFCLASS64 where
     type WordXX 'ELFCLASS64 = Word64
+    singElfClass = SELFCLASS64
 
+-- | Convenience function for creating a context with an implicit singleton available.
+--   See also [@withSing@](https://hackage.haskell.org/package/singletons-3.0.2/docs/Data-Singletons.html#v:withSingI)
+withSingElfClassI :: SingElfClass c -> (SingElfClassI c => r) -> r
+withSingElfClassI SELFCLASS64 x = x
+withSingElfClassI SELFCLASS32 x = x
+
+-- | A convenience function useful when we need to name a singleton value multiple times.
+--   Without this function, each use of sing could potentially refer to a different singleton,
+--   and one has to use type signatures (often with ScopedTypeVariables) to ensure that they are the same.
+--   See also [@withSingI@](https://hackage.haskell.org/package/singletons-3.0.2/docs/Data-Singletons.html#v:withSing)
+withSingElfClass :: SingElfClassI c => (SingElfClass c -> r) -> r
+withSingElfClass f = f singElfClass
+
+-- | Convert a singleton to its unrefined version.
+--   See also [@fromSing@](https://hackage.haskell.org/package/singletons-3.0.2/docs/Data-Singletons.html#v:fromSing)
+fromSingElfClass :: SingElfClass c -> ElfClass
+fromSingElfClass SELFCLASS32 = ELFCLASS32
+fromSingElfClass SELFCLASS64 = ELFCLASS64
+
+withElfClass' :: ElfClass -> (forall c . SingElfClass c -> r) -> r
+withElfClass' ELFCLASS32 f = f SELFCLASS32
+withElfClass' ELFCLASS64 f = f SELFCLASS64
+
+-- | Use this instead of [@toSing@](https://hackage.haskell.org/package/singletons-3.0.2/docs/Data-Singletons.html#v:toSing)
+withElfClass :: ElfClass -> (forall c . SingElfClassI c => SingElfClass c -> r) -> r
+withElfClass c f = withElfClass' c (\s -> withSingElfClassI s $ f s)
+
 --------------------------------------------------------------------------
 -- Header
 --------------------------------------------------------------------------
@@ -256,8 +282,8 @@
         , hShStrNdx   :: ElfSectionIndex -- ^ Section name string table index
         }
 
--- | Sigma type where `ElfClass` defines the type of `HeaderXX`
-type Header = Sigma ElfClass (TyCon1 HeaderXX)
+-- | Header is a sigma type where the first entry defines the type of the second one
+data Header = forall a . Header (SingElfClass a) (HeaderXX a)
 
 -- | Size of ELF header.
 headerSize :: Num a => ElfClass -> a
@@ -284,12 +310,7 @@
 wordSize ELFCLASS64 = 8
 wordSize ELFCLASS32 = 4
 
--- | Convenience function for creating a context with an implicit ElfClass available.
-withElfClass :: Sing c -> (IsElfClass c => a) -> a
-withElfClass SELFCLASS64 x = x
-withElfClass SELFCLASS32 x = x
-
-getHeader' :: IsElfClass c => Sing c -> Get Header
+getHeader' :: SingElfClassI c => SingElfClass c -> Get Header
 getHeader' classS = do
 
     hData <- get
@@ -314,30 +335,26 @@
 
     hFlags <- getE
     (hSize :: Word16) <- getE
-    when (hSize /= headerSize (fromSing classS)) $ error "incorrect size of elf header"
+    when (hSize /= headerSize (fromSingElfClass classS)) $ error "incorrect size of elf header"
     hPhEntSize <- getE
     hPhNum <- getE
     hShEntSize <- getE
     hShNum <- getE
     hShStrNdx <- getE
 
-    return $ classS :&: HeaderXX{..}
+    return $ Header classS HeaderXX{..}
 
 getHeader :: Get Header
 getHeader = do
     verify "magic" elfMagic
-    hClass <- get
-    let
-        f2 :: forall (c :: ElfClass) . Sing c -> Get Header
-        f2 x = withElfClass x (getHeader' x)
-
-    withSomeSing hClass f2
+    (hClass :: ElfClass) <- get
+    withElfClass hClass getHeader'
 
 putHeader :: Header -> Put
-putHeader (classS :&: HeaderXX{..}) = withElfClass classS do
+putHeader (Header classS HeaderXX{..}) = withSingElfClassI classS do
 
     put elfMagic
-    put $ fromSing classS
+    put $ fromSingElfClass classS
     put hData
     put elfSupportedVersion
     put hOSABI
@@ -356,7 +373,7 @@
     putE hPhOff
     putE hShOff
     putE hFlags
-    putE (headerSize $ fromSing classS :: Word16)
+    putE (headerSize $ fromSingElfClass classS :: Word16)
     putE hPhEntSize
     putE hPhNum
     putE hShEntSize
@@ -386,7 +403,7 @@
         , sEntSize   :: WordXX c       -- ^ Size of entries, if section has table
         }
 
-getSection ::                               IsElfClass c =>
+getSection ::                            SingElfClassI c =>
     (forall b . (Binary (Le b), Binary (Be b)) => Get b) -> Get (SectionXX c)
 getSection getE = do
 
@@ -403,7 +420,7 @@
 
     return SectionXX {..}
 
-putSection ::                                  IsElfClass c =>
+putSection ::                               SingElfClassI c =>
     (forall b . (Binary (Le b), Binary (Be b)) => b -> Put) ->
                                                 SectionXX c -> Put
 putSection putE (SectionXX{..}) = do
@@ -419,13 +436,13 @@
     putE sAddrAlign
     putE sEntSize
 
-instance forall (a :: ElfClass) . SingI a => Binary (Be (SectionXX a)) where
-    put = withElfClass (sing @a) (putSection putBe) . fromBe
-    get = Be <$> withElfClass (sing @a) (getSection getBe)
+instance forall (a :: ElfClass) . SingElfClassI a => Binary (Be (SectionXX a)) where
+    put = withSingElfClassI (singElfClass @a) (putSection putBe) . fromBe
+    get = Be <$> withSingElfClassI (singElfClass @a) (getSection getBe)
 
-instance forall (a :: ElfClass) . SingI a => Binary (Le (SectionXX a)) where
-    put = withElfClass (sing @a) (putSection putLe) . fromLe
-    get = Le <$> withElfClass (sing @a) (getSection getLe)
+instance forall (a :: ElfClass) . SingElfClassI a => Binary (Le (SectionXX a)) where
+    put = withSingElfClassI (singElfClass @a) (putSection putLe) . fromLe
+    get = Le <$> withSingElfClassI (singElfClass @a) (getSection getLe)
 
 --------------------------------------------------------------------------
 -- Segment
@@ -444,7 +461,7 @@
         , pAlign    :: WordXX c       -- ^ Alignment of segment
         }
 
-getSegment ::            forall (c :: ElfClass) . Sing c ->
+getSegment ::    forall (c :: ElfClass) . SingElfClass c ->
     (forall b . (Binary (Le b), Binary (Be b)) => Get b) -> Get (SegmentXX c)
 getSegment SELFCLASS64 getE = do
 
@@ -472,7 +489,7 @@
 
     return SegmentXX{..}
 
-putSegment ::               forall (c :: ElfClass) . Sing c ->
+putSegment ::       forall (c :: ElfClass) . SingElfClass c ->
     (forall b . (Binary (Le b), Binary (Be b)) => b -> Put) ->
                                                 SegmentXX c -> Put
 putSegment SELFCLASS64 putE (SegmentXX{..}) = do
@@ -498,14 +515,24 @@
     putE pAlign
 
 
-instance forall (a :: ElfClass) . SingI a => Binary (Be (SegmentXX a)) where
-    put = putSegment sing putBe . fromBe
-    get = Be <$> getSegment sing getBe
+instance forall (a :: ElfClass) . SingElfClassI a => Binary (Be (SegmentXX a)) where
+    put = putSegment singElfClass putBe . fromBe
+    get = Be <$> getSegment singElfClass getBe
 
-instance forall (a :: ElfClass) . SingI a => Binary (Le (SegmentXX a)) where
-    put = putSegment sing putLe . fromLe
-    get = Le <$> getSegment sing getLe
+instance forall (a :: ElfClass) . SingElfClassI a => Binary (Le (SegmentXX a)) where
+    put = putSegment singElfClass putLe . fromLe
+    get = Le <$> getSegment singElfClass getLe
 
+-- | Get section data
+getSectionData :: SingElfClassI a
+               => BSL.ByteString -- ^ ELF file
+               -> SectionXX a    -- ^ Parsed section entry
+               -> BSL.ByteString -- ^ Section Data
+getSectionData bs SectionXX{..} = BSL.take s $ BSL.drop o bs
+    where
+        o = fromIntegral sOffset
+        s = fromIntegral sSize
+
 --------------------------------------------------------------------------
 -- Symbol table entry
 --------------------------------------------------------------------------
@@ -526,8 +553,8 @@
         , stSize  :: WordXX c        -- ^ Size of object
         }
 
-getSymbolTableEntry ::    forall (c :: ElfClass) . Sing c ->
-     (forall b . (Binary (Le b), Binary (Be b)) => Get b) -> Get (SymbolXX c)
+getSymbolTableEntry :: forall (c :: ElfClass) . SingElfClass c ->
+          (forall b . (Binary (Le b), Binary (Be b)) => Get b) -> Get (SymbolXX c)
 getSymbolTableEntry SELFCLASS64 getE = do
 
     stName  <- getE
@@ -550,9 +577,9 @@
 
     return SymbolXX{..}
 
-putSymbolTableEntry ::      forall (c :: ElfClass) . Sing c ->
-    (forall b . (Binary (Le b), Binary (Be b)) => b -> Put) ->
-                                       SymbolXX c -> Put
+putSymbolTableEntry :: forall (c :: ElfClass) . SingElfClass c ->
+       (forall b . (Binary (Le b), Binary (Be b)) => b -> Put) ->
+                                                    SymbolXX c -> Put
 putSymbolTableEntry SELFCLASS64 putE (SymbolXX{..}) = do
 
     putE stName
@@ -571,13 +598,13 @@
     put  stOther
     putE stShNdx
 
-instance forall (a :: ElfClass) . SingI a => Binary (Be (SymbolXX a)) where
-    put = putSymbolTableEntry sing putBe . fromBe
-    get = Be <$> getSymbolTableEntry sing getBe
+instance forall (a :: ElfClass) . SingElfClassI a => Binary (Be (SymbolXX a)) where
+    put = putSymbolTableEntry singElfClass putBe . fromBe
+    get = Be <$> getSymbolTableEntry singElfClass getBe
 
-instance forall (a :: ElfClass) . SingI a => Binary (Le (SymbolXX a)) where
-    put = putSymbolTableEntry sing putLe . fromLe
-    get = Le <$> getSymbolTableEntry sing getLe
+instance forall (a :: ElfClass) . SingElfClassI a => Binary (Le (SymbolXX a)) where
+    put = putSymbolTableEntry singElfClass putLe . fromLe
+    get = Le <$> getSymbolTableEntry singElfClass getLe
 
 --------------------------------------------------------------------------
 -- relocation table entry
@@ -610,36 +637,36 @@
 relaInfo64 :: Word32 -> Word32 -> Word64
 relaInfo64 s t = fromIntegral t .|. (fromIntegral s `shiftL` 32)
 
-getRelocationTableAEntry ::      forall c . IsElfClass c =>
+getRelocationTableAEntry ::   forall c . SingElfClassI c =>
     (forall b . (Binary (Le b), Binary (Be b)) => Get b) -> Get (RelaXX c)
 getRelocationTableAEntry getE = do
     relaOffset <- getE
-    (relaSym, relaType) <- case sing @c of
+    (relaSym, relaType) <- case singElfClass @c of
         SELFCLASS64 -> (\x -> (relaSym64 x, relaType64 x)) <$> getE
         SELFCLASS32 -> (\x -> (relaSym32 x, relaType32 x)) <$> getE
     relaAddend <- getE
     return RelaXX{..}
 
-putRelocationTableAEntry ::         forall c . IsElfClass c =>
+putRelocationTableAEntry ::      forall c . SingElfClassI c =>
     (forall b . (Binary (Le b), Binary (Be b)) => b -> Put) ->
                                   RelaXX c -> Put
 putRelocationTableAEntry putE (RelaXX{..}) = do
     putE relaOffset
-    (case sing @c of
+    (case singElfClass @c of
         SELFCLASS64 -> putE $ relaInfo64 relaSym relaType
         SELFCLASS32 -> putE $ relaInfo32 relaSym relaType) :: Put
     putE relaAddend
 
-instance forall (a :: ElfClass) . SingI a => Binary (Be (RelaXX a)) where
-    put = withElfClass (sing @a) (putRelocationTableAEntry putBe) . fromBe
-    get = Be <$> withElfClass (sing @a) (getRelocationTableAEntry getBe)
+instance forall (a :: ElfClass) . SingElfClassI a => Binary (Be (RelaXX a)) where
+    put = withSingElfClassI (singElfClass @a) (putRelocationTableAEntry putBe) . fromBe
+    get = Be <$> withSingElfClassI (singElfClass @a) (getRelocationTableAEntry getBe)
 
-instance forall (a :: ElfClass) . SingI a => Binary (Le (RelaXX a)) where
-    put = withElfClass (sing @a) (putRelocationTableAEntry putLe) . fromLe
-    get = Le <$> withElfClass (sing @a) (getRelocationTableAEntry getLe)
+instance forall (a :: ElfClass) . SingElfClassI a => Binary (Le (RelaXX a)) where
+    put = withSingElfClassI (singElfClass @a) (putRelocationTableAEntry putLe) . fromLe
+    get = Le <$> withSingElfClassI (singElfClass @a) (getRelocationTableAEntry getLe)
 
 -- | Size of @RelaXX a@ in bytes.
-relocationTableAEntrySize :: forall a . IsElfClass a => WordXX a
+relocationTableAEntrySize :: forall a . SingElfClassI a => WordXX a
 relocationTableAEntrySize = fromIntegral $ BSL.length $ encode $ Le $ RelaXX @a 0 0 0 0
 
 --------------------------------------------------------------------------
@@ -677,12 +704,10 @@
     ELFDATA2LSB -> encode $ Le $ BList as
     ELFDATA2MSB -> encode $ Be $ BList as
 
--- FIXME: how to get rid of this? (Can we use some combinators for Sigma)
--- | The type that helps to make the sigma type of the result
---   of the `parseHeaders` function
-newtype HeadersXX a = HeadersXX (HeaderXX a, [SectionXX a], [SegmentXX a])
+-- | Sigma type to hold the ELF header and section and segment tables for a given `ElfClass`.
+data Headers = forall a . Headers (SingElfClass a) (HeaderXX a) [SectionXX a] [SegmentXX a]
 
-parseHeaders' :: (IsElfClass a, MonadThrow m) => HeaderXX a -> BSL.ByteString -> m (Sigma ElfClass (TyCon1 HeadersXX))
+parseHeaders' :: (SingElfClassI a, MonadThrow m) => HeaderXX a -> BSL.ByteString -> m Headers
 parseHeaders' hxx@HeaderXX{..} bs =
     let
         takeLen off len = BSL.take (fromIntegral len) $ BSL.drop (fromIntegral off) bs
@@ -691,10 +716,16 @@
     in do
         ss <- parseBList hData bsSections
         ps <- parseBList hData bsSegments
-        return $ sing :&: HeadersXX (hxx, ss, ps)
+        return $ Headers singElfClass hxx ss ps
 
 -- | Parse ELF file and produce header and section and segment tables
-parseHeaders :: MonadThrow m => BSL.ByteString -> m (Sigma ElfClass (TyCon1 HeadersXX))
+parseHeaders :: MonadThrow m => BSL.ByteString -> m Headers
 parseHeaders bs = do
-    ((classS :&: hxx) :: Header) <- elfDecodeOrFail bs
-    withElfClass classS parseHeaders' hxx bs
+    Header classS hxx <- elfDecodeOrFail bs
+    withSingElfClassI classS parseHeaders' hxx bs
+
+-- | Get string from string table
+getString :: BSL.ByteString -- ^ Section data of a string table section
+          -> Int64          -- ^ Offset to the start of the string in that data
+          -> String
+getString bs offset = BSL8.unpack $ BSL.takeWhile (/= 0) $ BSL.drop offset bs
diff --git a/src/Data/Elf/PrettyPrint.hs b/src/Data/Elf/PrettyPrint.hs
--- a/src/Data/Elf/PrettyPrint.hs
+++ b/src/Data/Elf/PrettyPrint.hs
@@ -40,17 +40,15 @@
 import Control.Monad.Catch
 import Data.Bits
 import qualified Data.ByteString as BS
-import qualified Data.ByteString.Lazy.Char8 as BSL8
 import qualified Data.ByteString.Lazy as BSL
+import qualified Data.ByteString.Lazy.Char8 as BSL8
 import Data.Char
 import Data.Int
 import qualified Data.List as L
-import Data.Singletons
-import Data.Singletons.Sigma
-import Prettyprinter
-import Prettyprinter.Render.Text
 import Data.Word
 import Numeric
+import Prettyprinter
+import Prettyprinter.Render.Text
 import System.IO
 
 import Control.Exception.ChainedException
@@ -92,18 +90,18 @@
 printWord64 :: Word64 -> Doc ()
 printWord64 n = pretty $ padLeadingZeros 16 $ showHex n ""
 
-printWordXXS :: Sing a -> WordXX a -> Doc ()
+printWordXXS :: SingElfClass a -> WordXX a -> Doc ()
 printWordXXS SELFCLASS32 = printWord32
 printWordXXS SELFCLASS64 = printWord64
 
-printWordXX :: SingI a => WordXX a -> Doc ()
-printWordXX = withSing printWordXXS
+printWordXX :: SingElfClassI a => WordXX a -> Doc ()
+printWordXX = withSingElfClass printWordXXS
 
 -- | Print ELF header.  It's used in golden tests
-printHeader :: forall a . SingI a => HeaderXX a -> Doc ()
+printHeader :: forall a . SingElfClassI a => HeaderXX a -> Doc ()
 printHeader HeaderXX{..} =
     formatPairs
-        [ ("Class",      viaShow $ fromSing $ sing @a )
+        [ ("Class",      viaShow $ fromSingElfClass $ singElfClass @a )
         , ("Data",       viaShow hData           ) -- ElfData
         , ("OSABI",      viaShow hOSABI          ) -- ElfOSABI
         , ("ABIVersion", viaShow hABIVersion     ) -- Word8
@@ -120,7 +118,7 @@
         , ("ShStrNdx",   viaShow hShStrNdx       ) -- Word16
         ]
 
-printSection :: SingI a => (Int, SectionXX a) -> Doc ()
+printSection :: SingElfClassI a => (Int, SectionXX a) -> Doc ()
 printSection (n, SectionXX{..}) =
     formatPairs
         [ ("N",         viaShow n              )
@@ -136,7 +134,7 @@
         , ("EntSize",   printWordXX sEntSize   ) -- WordXX c
         ]
 
-printSegment :: SingI a => (Int, SegmentXX a) -> Doc ()
+printSegment :: SingElfClassI a => (Int, SegmentXX a) -> Doc ()
 printSegment (n, SegmentXX{..}) =
     formatPairs
         [ ("N",        viaShow n             )
@@ -152,7 +150,7 @@
 
 -- | Print parsed header, section table and segment table.
 --   It's used in golden tests
-printHeaders :: SingI a => HeaderXX a -> [SectionXX a] -> [SegmentXX a] -> Doc ()
+printHeaders :: SingElfClassI a => HeaderXX a -> [SectionXX a] -> [SegmentXX a] -> Doc ()
 printHeaders hdr ss ps =
     let
         h  = printHeader hdr
@@ -169,7 +167,7 @@
 --
 --------------------------------------------------------------------
 
-printRBuilder :: IsElfClass a => [RBuilder a] -> Doc ()
+printRBuilder :: SingElfClassI a => [RBuilder a] -> Doc ()
 printRBuilder rbs = vsep ldoc
 
     where
@@ -263,8 +261,8 @@
 
 -- | Print ELF layout.  First parse ELF with `parseHeaders`, then use this function to
 --   format the layout.
-printLayout :: MonadCatch m => Sigma ElfClass (TyCon1 HeadersXX) -> BSL.ByteString -> m (Doc ())
-printLayout (classS :&: HeadersXX (hdr, ss, ps)) bs = withElfClass classS do
+printLayout :: MonadCatch m => Headers -> BSL.ByteString -> m (Doc ())
+printLayout (Headers classS hdr ss ps) bs = withSingElfClassI classS do
     rbs <- parseRBuilder hdr ss ps bs
     return $ printRBuilder rbs
 
@@ -275,7 +273,7 @@
 formatPairsBlock :: Doc a -> [(String, Doc a)] -> Doc a
 formatPairsBlock name pairs = vsep [ name <+> "{", indent 4 $ formatPairs pairs, "}" ]
 
-printElfSymbolTableEntry :: SingI a => ElfSymbolXX a -> Doc ()
+printElfSymbolTableEntry :: SingElfClassI a => ElfSymbolXX a -> Doc ()
 printElfSymbolTableEntry ElfSymbolXX{..} =
     formatPairsBlock ("symbol" <+> dquotes (pretty steName))
         [ ("Bind",  viaShow steBind      ) -- ElfSymbolBinding
@@ -285,7 +283,7 @@
         , ("Size",  printWordXX steSize  ) -- WordXX c
         ]
 
-printElfSymbolTable :: SingI a => Bool -> [ElfSymbolXX a] -> Doc ()
+printElfSymbolTable :: SingElfClassI a => Bool -> [ElfSymbolXX a] -> Doc ()
 printElfSymbolTable full l = if full then printElfSymbolTableFull else printElfSymbolTable'
     where
         printElfSymbolTableFull = align . vsep $ fmap printElfSymbolTableEntry l
@@ -341,7 +339,7 @@
                 chunks -> L.map formatBytestringLine chunks
         cl = BSL.drop (BSL.length bs - 16) bs
 
-printElfSymbolTableEntryLine :: SingI a => ElfSymbolXX a -> Doc ()
+printElfSymbolTableEntryLine :: SingElfClassI a => ElfSymbolXX a -> Doc ()
 printElfSymbolTableEntryLine ElfSymbolXX{..} =  parens (dquotes (pretty steName)
                                                     <+> "bind:"   <+> viaShow steBind
                                                     <+> "type:"   <+> viaShow steType
@@ -385,9 +383,9 @@
 
 -- | Print ELF.  If first argument is False, don't dump all the data, print just the first two and the last lines.
 printElf_ :: MonadThrow m => Bool -> Elf -> m (Doc ())
-printElf_ full (classS :&: elfs) = withElfClass classS $ printElf_' full elfs
+printElf_ full (Elf classS elfs) = withSingElfClassI classS $ printElf_' full elfs
 
-printElf_' :: forall a m . (MonadThrow m, IsElfClass a) => Bool -> ElfListXX a -> m (Doc ())
+printElf_' :: forall a m . (MonadThrow m, SingElfClassI a) => Bool -> ElfListXX a -> m (Doc ())
 printElf_' full elfs = do
 
     -- FIXME: lazy matching here is a workaround for some GHC bug, see
@@ -403,7 +401,7 @@
         printElf'' :: ElfXX t' a -> m (Doc ())
         printElf'' ElfHeader {} =
             return $ formatPairsBlock "header"
-                [ ("Class",      viaShow $ fromSing $ sing @a)
+                [ ("Class",      viaShow $ fromSingElfClass $ singElfClass @a)
                 , ("Data",       viaShow ehData       ) -- ElfData
                 , ("OSABI",      viaShow ehOSABI      ) -- ElfOSABI
                 , ("ABIVersion", viaShow ehABIVersion ) -- Word8
@@ -439,7 +437,7 @@
                                     && ehData == ELFDATA2LSB
                                     && esType == SHT_RELA
                                  && esEntSize == relocationTableAEntrySize then
-                                    case sing @a of
+                                    case singElfClass @a of
                                         SELFCLASS64 -> printSection' "section" <$> printRelocationTableA_AARCH64 full esLink elfs bs
                                         SELFCLASS32 -> $chainedError "invalid ELF: EM_AARCH64 and ELFCLASS32"
                             else
diff --git a/src/Data/Internal/Elf.hs b/src/Data/Internal/Elf.hs
--- a/src/Data/Internal/Elf.hs
+++ b/src/Data/Internal/Elf.hs
@@ -23,7 +23,8 @@
 
 import Control.Exception.ChainedException
 import Data.Elf.Constants
-import Data.Elf.Headers
+import Data.Elf.Headers hiding (Header)
+import qualified Data.Elf.Headers as H
 import Data.Interval as I
 
 import Control.Lens.Combinators hiding (contains)
@@ -40,8 +41,6 @@
 import qualified Data.List as L
 import Data.Maybe
 import Data.Monoid
-import Data.Singletons
-import Data.Singletons.Sigma
 
 -- | @RBuilder@ is an intermediate internal data type that is used by parser.
 -- It contains information about layout of the ELF file that can be used
@@ -80,18 +79,17 @@
     foldMap f (LZip l  (Just c) r) = foldMap f $ LZip l Nothing (c : r)
     foldMap f (LZip l  Nothing  r) = foldMap f $ L.reverse l ++ r
 
--- FIXME: Use validity (https://hackage.haskell.org/package/validity)
--- for constraints on the Elf type (???)
-
 -- | `Elf` is a forrest of trees of type `ElfXX`.
 -- Trees are composed of `ElfXX` nodes, `ElfSegment` can contain subtrees
 data ElfNodeType = Header | SectionTable | SegmentTable | Section | Segment | RawData | RawAlign
+
+-- | List of ELF nodes.
 data ElfListXX c where
     ElfListCons :: ElfXX t c -> ElfListXX c -> ElfListXX c
     ElfListNull :: ElfListXX c
 
--- | Elf is a sigma type where `ElfClass` defines the type of `ElfList`
-type Elf = Sigma ElfClass (TyCon1 ElfListXX)
+-- | Elf is a sigma type where the first entry defines the type of the second one
+data Elf = forall a . Elf (SingElfClass a) (ElfListXX a)
 
 -- | Section data may contain a string table.
 -- If a section contains a string table with section names, the data
@@ -176,6 +174,7 @@
 
 infixr 9 ~:
 
+-- | Helper for `ElfListCons`
 (~:) :: ElfXX t a -> ElfListXX a -> ElfListXX a
 (~:) = ElfListCons
 
@@ -191,29 +190,29 @@
 mapMElfList :: Monad m => (forall t' . (ElfXX t' a -> m b)) -> ElfListXX a -> m [b]
 mapMElfList f l = sequence $ foldMapElfList' ((: []) . f) l
 
-headerInterval :: forall a . IsElfClass a => HeaderXX a -> Interval (WordXX a)
-headerInterval _ = I 0 $ headerSize $ fromSing $ sing @a
+headerInterval :: forall a . SingElfClassI a => HeaderXX a -> Interval (WordXX a)
+headerInterval _ = I 0 $ headerSize $ fromSingElfClass $ singElfClass @a
 
-sectionTableInterval :: IsElfClass a => HeaderXX a -> Interval (WordXX a)
+sectionTableInterval :: SingElfClassI a => HeaderXX a -> Interval (WordXX a)
 sectionTableInterval HeaderXX{..} = I hShOff $ fromIntegral $ hShEntSize * hShNum
 
-segmentTableInterval :: IsElfClass a => HeaderXX a -> Interval (WordXX a)
+segmentTableInterval :: SingElfClassI a => HeaderXX a -> Interval (WordXX a)
 segmentTableInterval HeaderXX{..} = I hPhOff $ fromIntegral $ hPhEntSize * hPhNum
 
-sectionInterval :: IsElfClass a => SectionXX a -> Interval (WordXX a)
+sectionInterval :: SingElfClassI a => SectionXX a -> Interval (WordXX a)
 sectionInterval SectionXX{..} = I sOffset if sType == SHT_NOBITS then 0 else sSize
 
-segmentInterval :: IsElfClass a => SegmentXX a -> Interval (WordXX a)
+segmentInterval :: SingElfClassI a => SegmentXX a -> Interval (WordXX a)
 segmentInterval SegmentXX{..} = I pOffset pFileSize
 
-rBuilderInterval :: IsElfClass a => RBuilder a -> Interval (WordXX a)
+rBuilderInterval :: SingElfClassI a => RBuilder a -> Interval (WordXX a)
 rBuilderInterval RBuilderHeader{..}       = headerInterval rbhHeader
 rBuilderInterval RBuilderSectionTable{..} = sectionTableInterval rbstHeader
 rBuilderInterval RBuilderSegmentTable{..} = segmentTableInterval rbptHeader
 rBuilderInterval RBuilderSection{..}      = sectionInterval rbsHeader
 rBuilderInterval RBuilderSegment{..}      = segmentInterval rbpHeader
 rBuilderInterval RBuilderRawData{..}      = rbrdInterval
-rBuilderInterval RBuilderRawAlign{}       = undefined -- FIXME
+rBuilderInterval RBuilderRawAlign{}       = error "Internal error: rBuilderInterval is not defined for RBuilderRawAlign"
 
 findInterval :: (Ord t, Num t) => (a -> Interval t) -> t -> [a] -> LZip a
 findInterval f e = findInterval' []
@@ -234,21 +233,21 @@
 showRBuilder' RBuilderRawData{}      = "raw data" -- should not be called
 showRBuilder' RBuilderRawAlign{}     = "alignment" -- should not be called
 
-showRBuilder :: IsElfClass a => RBuilder a -> String
+showRBuilder :: SingElfClassI a => RBuilder a -> String
 showRBuilder v = showRBuilder' v ++ " (" ++ show (rBuilderInterval v) ++ ")"
 
--- showERBList :: IsElfClass a => [RBuilder a] -> String
+-- showERBList :: SingElfClassI a => [RBuilder a] -> String
 -- showERBList l = "[" ++ (L.concat $ L.intersperse ", " $ fmap showRBuilder l) ++ "]"
 
-intersectMessage :: IsElfClass a => RBuilder a -> RBuilder a -> String
+intersectMessage :: SingElfClassI a => RBuilder a -> RBuilder a -> String
 intersectMessage x y = showRBuilder x ++ " and " ++ showRBuilder y ++ " intersect"
 
-addRBuilders :: forall a m . (IsElfClass a, MonadCatch m) => [RBuilder a] -> m [RBuilder a]
+addRBuilders :: forall a m . (SingElfClassI a, MonadCatch m) => [RBuilder a] -> m [RBuilder a]
 addRBuilders newts =
     let
         addRBuilders' f newts' l = foldM (flip f) l newts'
 
-        addRBuilderEmpty :: (IsElfClass a, MonadCatch m) => RBuilder a -> [RBuilder a] -> m [RBuilder a]
+        addRBuilderEmpty :: (SingElfClassI a, MonadCatch m) => RBuilder a -> [RBuilder a] -> m [RBuilder a]
         addRBuilderEmpty t ts =
             -- (unsafePerformIO $ Prelude.putStrLn $ "Add Empty " ++ showRBuilder t ++ " to " ++ showERBList ts) `seq`
             let
@@ -285,14 +284,14 @@
                                 return $ toList $ LZip l Nothing (ce ++ (t : re'))
                 Nothing -> return $ toList $ LZip l (Just t) r
 
-        addRBuilderNonEmpty :: (IsElfClass a, MonadCatch m) => RBuilder a -> [RBuilder a] -> m [RBuilder a]
+        addRBuilderNonEmpty :: (SingElfClassI a, MonadCatch m) => RBuilder a -> [RBuilder a] -> m [RBuilder a]
         addRBuilderNonEmpty t ts =
             -- (unsafePerformIO $ Prelude.putStrLn $ "Add NonEmpty " ++ showRBuilder t ++ " to " ++ showERBList ts) `seq`
             let
                 ti = rBuilderInterval t
                 (LZip l c' r) = findInterval rBuilderInterval (offset ti) ts
 
-                addRBuildersNonEmpty :: (IsElfClass a, MonadCatch m) => [RBuilder a] -> RBuilder a -> m (RBuilder a)
+                addRBuildersNonEmpty :: (SingElfClassI a, MonadCatch m) => [RBuilder a] -> RBuilder a -> m (RBuilder a)
                 addRBuildersNonEmpty [] x = return x
                 addRBuildersNonEmpty ts' RBuilderSegment{..} = do
                     d <- $addContext' $ addRBuilders' addRBuilderNonEmpty ts' rbpData
@@ -397,7 +396,7 @@
         addRBuilders' addRBuilderNonEmpty nonEmptyRBs [] >>= addRBuilders' addRBuilderEmpty emptyRBs
 
 -- | Find section with a given number
-elfFindSection :: forall a m b . (SingI a, MonadThrow m, Integral b, Show b)
+elfFindSection :: forall a m b . (SingElfClassI a, MonadThrow m, Integral b, Show b)
                => ElfListXX a          -- ^ Structured ELF data
                -> b                    -- ^ Number of the section
                -> m (ElfXX 'Section a) -- ^ The section in question
@@ -411,7 +410,7 @@
             f _ = First Nothing
 
 -- | Find section with a given name
-elfFindSectionByName :: forall a m . (SingI a, MonadThrow m)
+elfFindSectionByName :: forall a m . (SingElfClassI a, MonadThrow m)
                      => ElfListXX a          -- ^ Structured ELF data
                      -> String               -- ^ Section name
                      -> m (ElfXX 'Section a) -- ^ The section in question
@@ -423,7 +422,7 @@
         f _ = First Nothing
 
 -- | Find ELF header
-elfFindHeader :: forall a m . (SingI a, MonadThrow m)
+elfFindHeader :: forall a m . (SingElfClassI a, MonadThrow m)
               => ElfListXX a         -- ^ Structured ELF data
               -> m (ElfXX 'Header a) -- ^ ELF header
 elfFindHeader elfs = $maybeAddContext "no header" maybeHeader
@@ -433,30 +432,14 @@
         f h@ElfHeader{} = First $ Just h
         f _ = First Nothing
 
--- | Get string from string table
-getString :: BSL.ByteString -- ^ Section data of a string table section
-          -> Int64          -- ^ Offset to the start of the string in that data
-          -> String
-getString bs offset = BSL8.unpack $ BSL.takeWhile (/= 0) $ BSL.drop offset bs
-
 cut :: BSL.ByteString -> Int64 -> Int64 -> BSL.ByteString
 cut content offset size = BSL.take size $ BSL.drop offset content
 
--- | Get section data
-getSectionData :: IsElfClass a
-               => BSL.ByteString -- ^ ELF file
-               -> SectionXX a    -- ^ Parsed section entry
-               -> BSL.ByteString -- ^ Section Data
-getSectionData bs SectionXX{..} = cut bs o s
-    where
-        o = fromIntegral sOffset
-        s = fromIntegral sSize
-
 tail' :: [a] -> [a]
 tail' [] = []
 tail' (_ : xs) = xs
 
-nextOffset :: IsElfClass a => WordXX a -> WordXX a -> WordXX a -> WordXX a
+nextOffset :: SingElfClassI a => WordXX a -> WordXX a -> WordXX a -> WordXX a
 nextOffset _ 0 a = a
 nextOffset t m a | m .&. (m - 1) /= 0 = error $ "align module is not power of two " ++ show m
                  | otherwise          = if a' + t' < a then a' + m + t' else a' + t'
@@ -464,7 +447,7 @@
         a' = a .&. complement (m - 1)
         t' = t .&. (m - 1)
 
-addRawData :: forall a . IsElfClass a => BSL.ByteString -> [RBuilder a] -> [RBuilder a]
+addRawData :: forall a . SingElfClassI a => BSL.ByteString -> [RBuilder a] -> [RBuilder a]
 addRawData _ [] = []
 addRawData bs rBuilders = snd $ addRawData' 0 (lrbie, rBuilders)
     where
@@ -528,7 +511,7 @@
                         eAddrAlign = case rbs' of
                             (RBuilderSegment{rbpHeader = SegmentXX{..}} : _) -> pAlign
                             (RBuilderSection{rbsHeader = SectionXX{..}} : _) -> sAddrAlign
-                            _ -> wordSize $ fromSing $ sing @a
+                            _ -> wordSize $ fromSingElfClass $ singElfClass @a
                         -- e' here is the address of the next section/segment
                         -- according to the regular alignment rules
                         e' = nextOffset eAddr eAddrAlign b
@@ -547,7 +530,7 @@
     go _ []     = Nothing
 
 -- | Parse ELF file and produce [`RBuilder`]
-parseRBuilder :: (IsElfClass a, MonadCatch m)
+parseRBuilder :: (SingElfClassI a, MonadCatch m)
               => HeaderXX a     -- ^ ELF header
               -> [SectionXX a]  -- ^ Section table
               -> [SegmentXX a]  -- ^ Segment table
@@ -559,12 +542,12 @@
     let
         maybeStringSectionData = getSectionData bs <$> (ss !!? hShStrNdx)
 
-        mkRBuilderSection :: (SingI a, MonadCatch m) => (ElfSectionIndex, SectionXX a) -> m (RBuilder a)
+        mkRBuilderSection :: (SingElfClassI a, MonadCatch m) => (ElfSectionIndex, SectionXX a) -> m (RBuilder a)
         mkRBuilderSection (n, s@SectionXX{..}) = do
             stringSectionData <- $maybeAddContext "No string table" maybeStringSectionData
             return $ RBuilderSection s n $ getString stringSectionData $ fromIntegral sName
 
-        mkRBuilderSegment :: (SingI a, MonadCatch m) => (Word16, SegmentXX a) -> m (RBuilder a)
+        mkRBuilderSegment :: (SingElfClassI a, MonadCatch m) => (Word16, SegmentXX a) -> m (RBuilder a)
         mkRBuilderSegment (n, p) = return $ RBuilderSegment p n []
 
     sections <- mapM mkRBuilderSection $ tail' $ Prelude.zip [0 .. ] ss
@@ -582,11 +565,11 @@
                                    ++ sections
     return $ addRawData bs rbs
 
-parseElf' :: forall a m . (IsElfClass a, MonadCatch m) =>
-                                            HeaderXX a ->
-                                         [SectionXX a] ->
-                                         [SegmentXX a] ->
-                                        BSL.ByteString -> m Elf
+parseElf' :: forall a m . (SingElfClassI a, MonadCatch m) =>
+                                               HeaderXX a ->
+                                            [SectionXX a] ->
+                                            [SegmentXX a] ->
+                                           BSL.ByteString -> m Elf
 parseElf' hdr@HeaderXX{..} ss ps bs = do
 
     rbs <- parseRBuilder hdr ss ps bs
@@ -645,19 +628,19 @@
             return $ ElfListCons (ElfRawAlign rbraOffset rbraAlign) l
 
     el <- foldrM rBuilderToElf ElfListNull rbs --  mapM rBuilderToElf rbs
-    return $ sing :&: el
+    return $ Elf singElfClass el
 
 -- | Parse ELF file
 parseElf :: MonadCatch m => BSL.ByteString -> m Elf
 parseElf bs = do
-    classS :&: HeadersXX (hdr, ss, ps) <- parseHeaders bs
-    withElfClass classS parseElf' hdr ss ps bs
+    Headers classS hdr ss ps <- parseHeaders bs
+    withSingElfClassI classS parseElf' hdr ss ps bs
 
 -------------------------------------------------------------------------------
 --
 -------------------------------------------------------------------------------
 
-wbStateInit :: forall a . IsElfClass a => WBuilderState a
+wbStateInit :: forall a . SingElfClassI a => WBuilderState a
 wbStateInit = WBuilderState
     { _wbsSections         = []
     , _wbsSegmentsReversed = []
@@ -669,7 +652,7 @@
     , _wbsNameIndexes      = []
     }
 
-zeroSection :: forall a . IsElfClass a => SectionXX a
+zeroSection :: forall a . SingElfClassI a => SectionXX a
 zeroSection = SectionXX 0 0 0 0 0 0 0 0 0 0
 
 neighbours :: [a] -> (a -> a -> b) -> [b]
@@ -723,7 +706,7 @@
                                     ((i', o') : iosff, insff)
                             else (iosff, (i', n') : insff)
 
-serializeElf' :: forall a m . (IsElfClass a, MonadCatch m) => ElfListXX a -> m BSL.ByteString
+serializeElf' :: forall a m . (SingElfClassI a, MonadCatch m) => ElfListXX a -> m BSL.ByteString
 serializeElf' elfs = do
 
     -- FIXME: it's better to match constructor here, but there is a bug that prevents to conclude that
@@ -736,7 +719,7 @@
 
     let
 
-        elfClass = fromSing $ sing @a
+        elfClass = fromSingElfClass $ singElfClass @a
 
         sectionN :: Num b => b
         sectionN = getSum $ foldMapElfList f elfs
@@ -776,7 +759,7 @@
             wbsDataReversed %= (WBuilderDataByteStream (BSL.replicate (fromIntegral $ offset' - offset) 0) :)
 
         alignWord :: (MonadThrow n, MonadState (WBuilderState a) n) => n ()
-        alignWord = align 0 $ wordSize $ fromSing $ sing @a
+        alignWord = align 0 $ wordSize $ fromSingElfClass $ singElfClass @a
 
         dataIsEmpty :: ElfSectionData c -> Bool
         dataIsEmpty (ElfSectionData bs)       = BSL.null bs
@@ -903,8 +886,8 @@
                                 hShNum      = (if sectionTable then sectionN + 1 else 0) :: Word16
                                 hShStrNdx   = _wbsShStrNdx
 
-                                h :: Header
-                                h = sing @a :&: HeaderXX{..}
+                                h :: H.Header
+                                h = H.Header (singElfClass @a) HeaderXX{..}
                             in
                                 encode h
                 f WBuilderDataByteStream {..} = wbdData
@@ -919,7 +902,7 @@
 
 -- | Serialze ELF file
 serializeElf :: MonadCatch m => Elf -> m BSL.ByteString
-serializeElf (classS :&: ls) = withElfClass classS serializeElf' ls
+serializeElf (Elf classS ls) = withSingElfClassI classS serializeElf' ls
 
 -------------------------------------------------------------------------------
 --
@@ -941,7 +924,7 @@
 getStringFromData :: BSL.ByteString -> Word32 -> String
 getStringFromData stringTable offset = BSL8.unpack $ BSL.takeWhile (/= 0) $ BSL.drop (fromIntegral offset) stringTable
 
-mkElfSymbolTableEntry :: SingI a => BSL.ByteString -> SymbolXX a -> ElfSymbolXX a
+mkElfSymbolTableEntry :: SingElfClassI a => BSL.ByteString -> SymbolXX a -> ElfSymbolXX a
 mkElfSymbolTableEntry stringTable SymbolXX{..} =
     let
         steName  = getStringFromData stringTable stName
@@ -954,7 +937,7 @@
         ElfSymbolXX{..}
 
 -- | Parse symbol table
-parseSymbolTable :: (MonadThrow m, SingI a)
+parseSymbolTable :: (MonadThrow m, SingElfClassI a)
                  => ElfData           -- ^ Endianness of the ELF file
                  -> ElfXX 'Section a  -- ^ Parsed section such that @`sectionIsSymbolTable` . `sType`@ is true.
                  -> ElfListXX a       -- ^ Structured ELF data
@@ -989,7 +972,7 @@
         SymbolXX{..}
 
 -- | Serialize symbol table
-serializeSymbolTable :: (MonadThrow m, SingI a)
+serializeSymbolTable :: (MonadThrow m, SingElfClassI a)
                      => ElfData                            -- ^ Endianness of the ELF file
                      -> [ElfSymbolXX a]                    -- ^ Symbol table
                      -> m (BSL.ByteString, BSL.ByteString) -- ^ Pair of symbol table section data and string table section data
diff --git a/tests/Golden.hs b/tests/Golden.hs
--- a/tests/Golden.hs
+++ b/tests/Golden.hs
@@ -24,8 +24,7 @@
 import Data.Foldable as F
 -- import Data.Functor.Identity
 import Data.Int
-import Data.Singletons
-import Data.Singletons.Sigma
+import GHC.IO.Encoding (setLocaleEncoding)
 import Prettyprinter
 import Prettyprinter.Render.Text
 import System.Directory
@@ -38,7 +37,8 @@
 import Control.Exception.ChainedException
 import Data.Elf
 import Data.Elf.PrettyPrint
-import Data.Elf.Headers
+import qualified Data.Elf.Headers as H
+import Data.Elf.Headers hiding (Header)
 import Data.Endian
 
 partitionM :: Monad m => (a -> m Bool) -> [a] -> m ([a], [a])
@@ -66,7 +66,7 @@
     Left (_, off, err) -> assertFailure (err ++ " @" ++ show off)
     Right (_, off, a) -> return (off, a)
 
-mkTest'' :: forall a . IsElfClass a => HeaderXX a -> ByteString -> Assertion
+mkTest'' :: forall a . SingElfClassI a => HeaderXX a -> ByteString -> Assertion
 mkTest'' HeaderXX{..} bs = do
 
     let
@@ -82,11 +82,11 @@
 
 mkTest' :: ByteString -> Assertion
 mkTest' bs = do
-    (off, elfh@(classS :&: hxx) :: Header) <- decodeOrFailAssertion bs
-    assertBool "Incorrect header size" (headerSize (fromSing classS) == off)
+    (off, elfh@(H.Header classS hxx)) <- decodeOrFailAssertion bs
+    assertBool "Incorrect header size" (headerSize (fromSingElfClass classS) == off)
     assertEqual "Header round trip does not work" (BSL.take off bs) (encode elfh)
 
-    withElfClass classS mkTest'' hxx bs
+    withSingElfClassI classS mkTest'' hxx bs
 
 mkTest :: FilePath -> TestTree
 mkTest p = testCase p $ withBinaryFile p ReadMode (BSL.hGetContents >=> mkTest')
@@ -123,8 +123,8 @@
                 | otherwise = $chainedError "index': negative argument."
 index' _ _                  = $chainedError "index': index too large."
 
-getStringTable :: MonadThrow m => Sigma ElfClass (TyCon1 HeadersXX) -> BSL.ByteString -> m BSL.ByteString
-getStringTable (classS :&: HeadersXX (HeaderXX{..}, ss, _)) bs = withElfClass classS
+getStringTable :: MonadThrow m => Headers -> BSL.ByteString -> m BSL.ByteString
+getStringTable (Headers classS HeaderXX{..} ss _) bs = withSingElfClassI classS
     if hShStrNdx == 0
         then return BSL.empty
         else do
@@ -137,11 +137,11 @@
 ---------------------------------------------------------------------
 
 -- This is for examples/README.md
-withHeader :: BSL.ByteString -> (forall a . IsElfClass a => HeaderXX a -> b) -> Either String b
+withHeader :: BSL.ByteString -> (forall a . SingElfClassI a => HeaderXX a -> b) -> Either String b
 withHeader bs f =
     case decodeOrFail bs of
         Left (_, _, err) -> Left err
-        Right (_, _, (classS :&: hxx) :: Header) -> Right $ withElfClass classS f hxx
+        Right (_, _, (H.Header classS hxx)) -> Right $ withSingElfClassI classS f hxx
 
 printHeaderFile :: FilePath -> IO (Doc ())
 printHeaderFile path = do
@@ -151,8 +151,8 @@
 printHeadersFile :: FilePath -> IO (Doc ())
 printHeadersFile path = do
     bs <- fromStrict <$> BS.readFile path
-    (classS :&: HeadersXX (hdr, ss, ps)) <- parseHeaders bs
-    return $ withSingI classS $ printHeaders hdr ss ps
+    Headers classS hdr ss ps <- parseHeaders bs
+    return $ withSingElfClassI classS $ printHeaders hdr ss ps
 
 printStrTableFile :: FilePath -> IO (Doc ())
 printStrTableFile path = do
@@ -197,11 +197,11 @@
 
 -----------------------------------------------------------------------
 
-testHeader64 :: Header
-testHeader64 = SELFCLASS64 :&: HeaderXX ELFDATA2LSB 0 0 0 0 0 0 0 0 0 0 0 0 0
+testHeader64 :: H.Header
+testHeader64 = H.Header SELFCLASS64 (HeaderXX ELFDATA2LSB 0 0 0 0 0 0 0 0 0 0 0 0 0)
 
-testHeader32 :: Header
-testHeader32 = SELFCLASS32 :&: HeaderXX ELFDATA2MSB 0 0 0 0 0 0 0 0 0 0 0 0 0
+testHeader32 :: H.Header
+testHeader32 = H.Header SELFCLASS32 (HeaderXX ELFDATA2MSB 0 0 0 0 0 0 0 0 0 0 0 0 0)
 
 testSection64 :: SectionXX 'ELFCLASS64
 testSection64 = SectionXX 0 0 0 0 0 0 0 0 0 0
@@ -248,6 +248,8 @@
 
 main :: IO ()
 main = do
+
+    setLocaleEncoding utf8
 
     elfs <- traverseDir "testdata" isElf
 
diff --git a/tests/exceptions/Exceptions.hs b/tests/exceptions/Exceptions.hs
--- a/tests/exceptions/Exceptions.hs
+++ b/tests/exceptions/Exceptions.hs
@@ -1,18 +1,18 @@
 {-# LANGUAGE TemplateHaskell #-}
 {-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE CPP #-}
 
 module Main (main) where
 
 import Control.Exception.ChainedException
-
 import Control.Exception hiding (try)
 import Control.Monad.Catch
+import GHC.IO.Encoding (setLocaleEncoding)
+import System.IO
 import Test.Tasty
 import Test.Tasty.HUnit
 
---------------------------------------------
-
 f :: IO ()
 f = $chainedError "some error"
 
@@ -54,14 +54,26 @@
     Left (e :: SomeException)  -> show e @?= s
 
 main :: IO ()
-main = defaultMain $ testGroup "exceptions" [ testCase "f"    $ checkExceptions f    "some error (tests/exceptions/Exceptions.hs:17)"
-                                            , testCase "f'"   $ checkExceptions f'   "(tests/exceptions/Exceptions.hs:20)"
-                                            , testCase "fe"   $ checkExceptions fe   "TestException"
-                                            , testCase "f1"   $ checkExceptions f1   "some context (tests/exceptions/Exceptions.hs:29) // some error (tests/exceptions/Exceptions.hs:17)"
-                                            , testCase "f1'"  $ checkExceptions f1'  "(tests/exceptions/Exceptions.hs:32) // some error (tests/exceptions/Exceptions.hs:17)"
-                                            , testCase "fe'"  $ checkExceptions fe'  "(tests/exceptions/Exceptions.hs:35) // TestException"
-                                            , testCase "fe'e" $ checkExceptions fe'e "some context 2 (tests/exceptions/Exceptions.hs:38) // (tests/exceptions/Exceptions.hs:35) // TestException"
-                                            , testCase "fmb"  $ checkExceptions fmb  "some context 3 (tests/exceptions/Exceptions.hs:41)"
-                                            , testCase "fmb'" $ checkExceptions fmb' "(tests/exceptions/Exceptions.hs:44)"
-                                            , testCase "fei'" $ checkExceptions fei' "some error description 4 (tests/exceptions/Exceptions.hs:47)"
-                                            ]
+main = do
+    setLocaleEncoding utf8
+    defaultMain $ testGroup "exceptions" [ testCase "f"    $ checkExceptions f    $ fixPath "some error (tests$exceptions$Exceptions.hs:17)"
+                                         , testCase "f'"   $ checkExceptions f'   $ fixPath "(tests$exceptions$Exceptions.hs:20)"
+                                         , testCase "fe"   $ checkExceptions fe   $ fixPath "TestException"
+                                         , testCase "f1"   $ checkExceptions f1   $ fixPath "some context (tests$exceptions$Exceptions.hs:29) // some error (tests$exceptions$Exceptions.hs:17)"
+                                         , testCase "f1'"  $ checkExceptions f1'  $ fixPath "(tests$exceptions$Exceptions.hs:32) // some error (tests$exceptions$Exceptions.hs:17)"
+                                         , testCase "fe'"  $ checkExceptions fe'  $ fixPath "(tests$exceptions$Exceptions.hs:35) // TestException"
+                                         , testCase "fe'e" $ checkExceptions fe'e $ fixPath "some context 2 (tests$exceptions$Exceptions.hs:38) // (tests$exceptions$Exceptions.hs:35) // TestException"
+                                         , testCase "fmb"  $ checkExceptions fmb  $ fixPath "some context 3 (tests$exceptions$Exceptions.hs:41)"
+                                         , testCase "fmb'" $ checkExceptions fmb' $ fixPath "(tests$exceptions$Exceptions.hs:44)"
+                                         , testCase "fei'" $ checkExceptions fei' $ fixPath "some error description 4 (tests$exceptions$Exceptions.hs:47)"
+                                         ]
+
+fixPath :: String -> String
+fixPath = fmap fn
+    where
+#ifdef mingw32_HOST_OS
+        fn '$' = '\\'
+#else
+        fn '$' = '/'
+#endif
+        fn  x  =  x
diff --git a/tests/testdata/orig/bloated.elf.golden b/tests/testdata/orig/bloated.elf.golden
--- a/tests/testdata/orig/bloated.elf.golden
+++ b/tests/testdata/orig/bloated.elf.golden
@@ -7,7 +7,7 @@
     Align:      0x00001000
     Data:       
         segment {
-            Type:       PT_EXT 1685382481
+            Type:       ElfSegmentType 1685382481
             Flags:      [PF_W,PF_R]
             VirtAddr:   0x00000000
             PhysAddr:   0x00000000
@@ -88,7 +88,7 @@
                 }
         }
         section 4 ".gnu.hash" {
-            Type:      SHT_EXT 1879048182
+            Type:      ElfSectionType 1879048182
             Flags:     [SHF_ALLOC]
             Addr:      0x080481ac
             AddrAlign: 0x00000004
@@ -126,7 +126,7 @@
                 symbol "_ZSt4cout" {
                     Bind:  STB_Global
                     Type:  STT_Object
-                    ShNdx: SHN_EXT 26
+                    ShNdx: ElfSectionIndex 26
                     Value: 0x0804a040
                     Size:  0x0000008c
                 }
@@ -147,7 +147,7 @@
                        total: 409
         }
         section 7 ".gnu.version" {
-            Type:      SHT_EXT 1879048191
+            Type:      ElfSectionType 1879048191
             Flags:     [SHF_ALLOC]
             Addr:      0x08048456
             AddrAlign: 0x00000002
@@ -158,7 +158,7 @@
                        00 00 03 00 01 00 03 00 03 00 03 00             # ............
         }
         section 8 ".gnu.version_r" {
-            Type:      SHT_EXT 1879048190
+            Type:      ElfSectionType 1879048190
             Flags:     [SHF_ALLOC]
             Addr:      0x08048474
             AddrAlign: 0x00000004
@@ -183,7 +183,7 @@
         }
         section 10 ".rel.plt" {
             Type:      SHT_REL
-            Flags:     [SHF_ALLOC,SHF_EXT 64]
+            Flags:     [SHF_ALLOC,ElfSectionFlag 64]
             Addr:      0x080484d4
             AddrAlign: 0x00000004
             EntSize:   0x00000008
@@ -268,7 +268,7 @@
                        6f 20 77 6f 72 6c 64 21 00                      # o world!.
         }
         segment {
-            Type:       PT_EXT 1685382480
+            Type:       ElfSegmentType 1685382480
             Flags:      [PF_R]
             VirtAddr:   0x08048804
             PhysAddr:   0x08048804
@@ -314,7 +314,7 @@
     Align:      0x00001000
     Data:       
         segment {
-            Type:       PT_EXT 1685382482
+            Type:       ElfSegmentType 1685382482
             Flags:      [PF_R]
             VirtAddr:   0x08049eec
             PhysAddr:   0x08049eec
@@ -322,7 +322,7 @@
             Align:      0x00000001
             Data:       
                 section 19 ".init_array" {
-                    Type:      SHT_EXT 14
+                    Type:      ElfSectionType 14
                     Flags:     [SHF_WRITE,SHF_ALLOC]
                     Addr:      0x08049eec
                     AddrAlign: 0x00000004
@@ -332,7 +332,7 @@
                     Data:      e0 86 04 08 00 86 04 08                         # ........
                 }
                 section 20 ".fini_array" {
-                    Type:      SHT_EXT 15
+                    Type:      ElfSectionType 15
                     Flags:     [SHF_WRITE,SHF_ALLOC]
                     Addr:      0x08049ef4
                     AddrAlign: 0x00000004
@@ -420,7 +420,7 @@
 }
 section 27 ".comment" {
     Type:      SHT_PROGBITS
-    Flags:     [SHF_EXT 16,SHF_EXT 32]
+    Flags:     [ElfSectionFlag 16,ElfSectionFlag 32]
     Addr:      0x00000000
     AddrAlign: 0x00000001
     EntSize:   0x00000001
@@ -451,7 +451,7 @@
         symbol "" {
             Bind:  STB_Local
             Type:  STT_Section
-            ShNdx: SHN_EXT 1
+            ShNdx: ElfSectionIndex 1
             Value: 0x08048154
             Size:  0x00000000
         }
@@ -459,7 +459,7 @@
         symbol "_init" {
             Bind:  STB_Global
             Type:  STT_Func
-            ShNdx: SHN_EXT 11
+            ShNdx: ElfSectionIndex 11
             Value: 0x0804850c
             Size:  0x00000000
         }
diff --git a/tests/testdata/orig/bloated.elf_header.golden b/tests/testdata/orig/bloated.elf_header.golden
--- a/tests/testdata/orig/bloated.elf_header.golden
+++ b/tests/testdata/orig/bloated.elf_header.golden
@@ -12,4 +12,4 @@
 PhNum:      9
 ShEntSize:  0x0028
 ShNum:      31
-ShStrNdx:   SHN_EXT 28
+ShStrNdx:   ElfSectionIndex 28
diff --git a/tests/testdata/orig/bloated.header.golden b/tests/testdata/orig/bloated.header.golden
--- a/tests/testdata/orig/bloated.header.golden
+++ b/tests/testdata/orig/bloated.header.golden
@@ -12,7 +12,7 @@
           PhNum:      9
           ShEntSize:  0x0028
           ShNum:      31
-          ShStrNdx:   SHN_EXT 28
+          ShStrNdx:   ElfSectionIndex 28
 Sections: - N:         0
             Name:      0
             Type:      SHT_NULL
@@ -59,7 +59,7 @@
             EntSize:   0x00000000
           - N:         4
             Name:      68
-            Type:      SHT_EXT 1879048182
+            Type:      ElfSectionType 1879048182
             Flags:     0x00000002
             Addr:      0x080481ac
             Offset:    0x000001ac
@@ -92,7 +92,7 @@
             EntSize:   0x00000000
           - N:         7
             Name:      94
-            Type:      SHT_EXT 1879048191
+            Type:      ElfSectionType 1879048191
             Flags:     0x00000002
             Addr:      0x08048456
             Offset:    0x00000456
@@ -103,7 +103,7 @@
             EntSize:   0x00000002
           - N:         8
             Name:      107
-            Type:      SHT_EXT 1879048190
+            Type:      ElfSectionType 1879048190
             Flags:     0x00000002
             Addr:      0x08048474
             Offset:    0x00000474
@@ -224,7 +224,7 @@
             EntSize:   0x00000000
           - N:         19
             Name:      199
-            Type:      SHT_EXT 14
+            Type:      ElfSectionType 14
             Flags:     0x00000003
             Addr:      0x08049eec
             Offset:    0x00000eec
@@ -235,7 +235,7 @@
             EntSize:   0x00000000
           - N:         20
             Name:      211
-            Type:      SHT_EXT 15
+            Type:      ElfSectionType 15
             Flags:     0x00000003
             Addr:      0x08049ef4
             Offset:    0x00000ef4
@@ -409,7 +409,7 @@
             MemSize:  0x00000044
             Align:    0x00000004
           - N:        6
-            Type:     PT_EXT 1685382480
+            Type:     ElfSegmentType 1685382480
             Flags:    [PF_R]
             Offset:   0x00000804
             VirtAddr: 0x08048804
@@ -418,7 +418,7 @@
             MemSize:  0x0000003c
             Align:    0x00000004
           - N:        7
-            Type:     PT_EXT 1685382481
+            Type:     ElfSegmentType 1685382481
             Flags:    [PF_W,PF_R]
             Offset:   0x00000000
             VirtAddr: 0x00000000
@@ -427,7 +427,7 @@
             MemSize:  0x00000000
             Align:    0x00000010
           - N:        8
-            Type:     PT_EXT 1685382482
+            Type:     ElfSegmentType 1685382482
             Flags:    [PF_R]
             Offset:   0x00000eec
             VirtAddr: 0x08049eec
diff --git a/tests/testdata/orig/bloated.layout.golden b/tests/testdata/orig/bloated.layout.golden
--- a/tests/testdata/orig/bloated.layout.golden
+++ b/tests/testdata/orig/bloated.layout.golden
@@ -1,5 +1,5 @@
  ┌── 0x00000000 P PT_LOAD [PF_X,PF_R]
- │ - 0x00000000 P PT_EXT 1685382481 [PF_W,PF_R]
+ │ - 0x00000000 P ElfSegmentType 1685382481 [PF_W,PF_R]
  │ ┎ 0x00000000 H
  │ ┖ 0x00000033
  │┌─ 0x00000034 P PT_PHDR [PF_X,PF_R]
@@ -16,19 +16,19 @@
  ││╓ 0x00000188 S3 ".note.gnu.build-id" SHT_NOTE [SHF_ALLOC]
  ││╙ 0x000001ab
  │└─ 0x000001ab
- │ ╓ 0x000001ac S4 ".gnu.hash" SHT_EXT 1879048182 [SHF_ALLOC]
+ │ ╓ 0x000001ac S4 ".gnu.hash" ElfSectionType 1879048182 [SHF_ALLOC]
  │ ╙ 0x000001db
  │ ╓ 0x000001dc S5 ".dynsym" SHT_DYNSYM [SHF_ALLOC]
  │ ╙ 0x000002bb
  │ ╓ 0x000002bc S6 ".dynstr" SHT_STRTAB [SHF_ALLOC]
  │ ╙ 0x00000454
- │ ╓ 0x00000456 S7 ".gnu.version" SHT_EXT 1879048191 [SHF_ALLOC]
+ │ ╓ 0x00000456 S7 ".gnu.version" ElfSectionType 1879048191 [SHF_ALLOC]
  │ ╙ 0x00000471
- │ ╓ 0x00000474 S8 ".gnu.version_r" SHT_EXT 1879048190 [SHF_ALLOC]
+ │ ╓ 0x00000474 S8 ".gnu.version_r" ElfSectionType 1879048190 [SHF_ALLOC]
  │ ╙ 0x000004c3
  │ ╓ 0x000004c4 S9 ".rel.dyn" SHT_REL [SHF_ALLOC]
  │ ╙ 0x000004d3
- │ ╓ 0x000004d4 S10 ".rel.plt" SHT_REL [SHF_ALLOC,SHF_EXT 64]
+ │ ╓ 0x000004d4 S10 ".rel.plt" SHT_REL [SHF_ALLOC,ElfSectionFlag 64]
  │ ╙ 0x0000050b
  │ ╓ 0x0000050c S11 ".init" SHT_PROGBITS [SHF_ALLOC,SHF_EXECINSTR]
  │ ╙ 0x0000052e
@@ -42,7 +42,7 @@
  │ ╙ 0x000007e7
  │ ╓ 0x000007e8 S16 ".rodata" SHT_PROGBITS [SHF_ALLOC]
  │ ╙ 0x00000800
- │┌─ 0x00000804 P PT_EXT 1685382480 [PF_R]
+ │┌─ 0x00000804 P ElfSegmentType 1685382480 [PF_R]
  ││╓ 0x00000804 S17 ".eh_frame_hdr" SHT_PROGBITS [SHF_ALLOC]
  ││╙ 0x0000083f
  │└─ 0x0000083f
@@ -50,10 +50,10 @@
  │ ╙ 0x00000933
  └── 0x00000933
 ┌─── 0x00000eec P PT_LOAD [PF_W,PF_R]
-│┌── 0x00000eec P PT_EXT 1685382482 [PF_R]
-││ ╓ 0x00000eec S19 ".init_array" SHT_EXT 14 [SHF_WRITE,SHF_ALLOC]
+│┌── 0x00000eec P ElfSegmentType 1685382482 [PF_R]
+││ ╓ 0x00000eec S19 ".init_array" ElfSectionType 14 [SHF_WRITE,SHF_ALLOC]
 ││ ╙ 0x00000ef3
-││ ╓ 0x00000ef4 S20 ".fini_array" SHT_EXT 15 [SHF_WRITE,SHF_ALLOC]
+││ ╓ 0x00000ef4 S20 ".fini_array" ElfSectionType 15 [SHF_WRITE,SHF_ALLOC]
 ││ ╙ 0x00000ef7
 ││ ╓ 0x00000ef8 S21 ".jcr" SHT_PROGBITS [SHF_WRITE,SHF_ALLOC]
 ││ ╙ 0x00000efb
@@ -70,7 +70,7 @@
 │  ╙ 0x0000102b
 └─── 0x0000102b
    - 0x0000102c S26 ".bss" SHT_NOBITS [SHF_WRITE,SHF_ALLOC]
-   ╓ 0x0000102c S27 ".comment" SHT_PROGBITS [SHF_EXT 16,SHF_EXT 32]
+   ╓ 0x0000102c S27 ".comment" SHT_PROGBITS [ElfSectionFlag 16,ElfSectionFlag 32]
    ╙ 0x00001084
    ╓ 0x00001088 S29 ".symtab" SHT_SYMTAB []
    ╙ 0x00001567
diff --git a/tests/testdata/orig/tiny.elf_header.golden b/tests/testdata/orig/tiny.elf_header.golden
--- a/tests/testdata/orig/tiny.elf_header.golden
+++ b/tests/testdata/orig/tiny.elf_header.golden
@@ -12,4 +12,4 @@
 PhNum:      2
 ShEntSize:  0x0040
 ShNum:      3
-ShStrNdx:   SHN_EXT 2
+ShStrNdx:   ElfSectionIndex 2
diff --git a/tests/testdata/orig/tiny.header.golden b/tests/testdata/orig/tiny.header.golden
--- a/tests/testdata/orig/tiny.header.golden
+++ b/tests/testdata/orig/tiny.header.golden
@@ -12,7 +12,7 @@
           PhNum:      2
           ShEntSize:  0x0040
           ShNum:      3
-          ShStrNdx:   SHN_EXT 2
+          ShStrNdx:   ElfSectionIndex 2
 Sections: - N:         0
             Name:      0
             Type:      SHT_NULL
diff --git a/tests/testdata/orig/vdso.elf.golden b/tests/testdata/orig/vdso.elf.golden
--- a/tests/testdata/orig/vdso.elf.golden
+++ b/tests/testdata/orig/vdso.elf.golden
@@ -32,7 +32,7 @@
                        total: 60
         }
         section 2 ".gnu.hash" {
-            Type:      SHT_EXT 1879048182
+            Type:      ElfSectionType 1879048182
             Flags:     [SHF_ALLOC]
             Addr:      0x0000000000000160
             AddrAlign: 0x0000000000000008
@@ -64,7 +64,7 @@
                 symbol "clock_gettime" {
                     Bind:  STB_Weak
                     Type:  STT_Func
-                    ShNdx: SHN_EXT 12
+                    ShNdx: ElfSectionIndex 12
                     Value: 0x0000000000000a30
                     Size:  0x0000000000000305
                 }
@@ -72,7 +72,7 @@
                 symbol "getcpu" {
                     Bind:  STB_Weak
                     Type:  STT_Func
-                    ShNdx: SHN_EXT 12
+                    ShNdx: ElfSectionIndex 12
                     Value: 0x0000000000000f30
                     Size:  0x000000000000002a
                 }
@@ -93,7 +93,7 @@
                        total: 94
         }
         section 5 ".gnu.version" {
-            Type:      SHT_EXT 1879048191
+            Type:      ElfSectionType 1879048191
             Flags:     [SHF_ALLOC]
             Addr:      0x00000000000002f6
             AddrAlign: 0x0000000000000002
@@ -104,7 +104,7 @@
                        02 00 02 00                                     # ....
         }
         section 6 ".gnu.version_d" {
-            Type:      SHT_EXT 1879048189
+            Type:      ElfSectionType 1879048189
             Flags:     [SHF_ALLOC]
             Addr:      0x0000000000000310
             AddrAlign: 0x0000000000000008
@@ -178,7 +178,7 @@
                 }
         }
         segment {
-            Type:       PT_EXT 1685382480
+            Type:       ElfSegmentType 1685382480
             Flags:      [PF_R]
             VirtAddr:   0x00000000000007e4
             PhysAddr:   0x00000000000007e4
@@ -257,7 +257,7 @@
 }
 section 15 ".comment" {
     Type:      SHT_PROGBITS
-    Flags:     [SHF_EXT 16,SHF_EXT 32]
+    Flags:     [ElfSectionFlag 16,ElfSectionFlag 32]
     Addr:      0x0000000000000000
     AddrAlign: 0x0000000000000001
     EntSize:   0x0000000000000001
diff --git a/tests/testdata/orig/vdso.elf_header.golden b/tests/testdata/orig/vdso.elf_header.golden
--- a/tests/testdata/orig/vdso.elf_header.golden
+++ b/tests/testdata/orig/vdso.elf_header.golden
@@ -12,4 +12,4 @@
 PhNum:      4
 ShEntSize:  0x0040
 ShNum:      17
-ShStrNdx:   SHN_EXT 16
+ShStrNdx:   ElfSectionIndex 16
diff --git a/tests/testdata/orig/vdso.header.golden b/tests/testdata/orig/vdso.header.golden
--- a/tests/testdata/orig/vdso.header.golden
+++ b/tests/testdata/orig/vdso.header.golden
@@ -12,7 +12,7 @@
           PhNum:      4
           ShEntSize:  0x0040
           ShNum:      17
-          ShStrNdx:   SHN_EXT 16
+          ShStrNdx:   ElfSectionIndex 16
 Sections: - N:         0
             Name:      0
             Type:      SHT_NULL
@@ -37,7 +37,7 @@
             EntSize:   0x0000000000000004
           - N:         2
             Name:      11
-            Type:      SHT_EXT 1879048182
+            Type:      ElfSectionType 1879048182
             Flags:     0x0000000000000002
             Addr:      0x0000000000000160
             Offset:    0x0000000000000160
@@ -70,7 +70,7 @@
             EntSize:   0x0000000000000000
           - N:         5
             Name:      37
-            Type:      SHT_EXT 1879048191
+            Type:      ElfSectionType 1879048191
             Flags:     0x0000000000000002
             Addr:      0x00000000000002f6
             Offset:    0x00000000000002f6
@@ -81,7 +81,7 @@
             EntSize:   0x0000000000000002
           - N:         6
             Name:      50
-            Type:      SHT_EXT 1879048189
+            Type:      ElfSectionType 1879048189
             Flags:     0x0000000000000002
             Addr:      0x0000000000000310
             Offset:    0x0000000000000310
@@ -228,7 +228,7 @@
             MemSize:  0x000000000000003c
             Align:    0x0000000000000004
           - N:        3
-            Type:     PT_EXT 1685382480
+            Type:     ElfSegmentType 1685382480
             Flags:    [PF_R]
             Offset:   0x00000000000007e4
             VirtAddr: 0x00000000000007e4
diff --git a/tests/testdata/orig/vdso.layout.golden b/tests/testdata/orig/vdso.layout.golden
--- a/tests/testdata/orig/vdso.layout.golden
+++ b/tests/testdata/orig/vdso.layout.golden
@@ -5,15 +5,15 @@
 │ ┖ 0x0000011f
 │ ╓ 0x00000120 S1 ".hash" SHT_HASH [SHF_ALLOC]
 │ ╙ 0x0000015b
-│ ╓ 0x00000160 S2 ".gnu.hash" SHT_EXT 1879048182 [SHF_ALLOC]
+│ ╓ 0x00000160 S2 ".gnu.hash" ElfSectionType 1879048182 [SHF_ALLOC]
 │ ╙ 0x000001a7
 │ ╓ 0x000001a8 S3 ".dynsym" SHT_DYNSYM [SHF_ALLOC]
 │ ╙ 0x00000297
 │ ╓ 0x00000298 S4 ".dynstr" SHT_STRTAB [SHF_ALLOC]
 │ ╙ 0x000002f5
-│ ╓ 0x000002f6 S5 ".gnu.version" SHT_EXT 1879048191 [SHF_ALLOC]
+│ ╓ 0x000002f6 S5 ".gnu.version" ElfSectionType 1879048191 [SHF_ALLOC]
 │ ╙ 0x00000309
-│ ╓ 0x00000310 S6 ".gnu.version_d" SHT_EXT 1879048189 [SHF_ALLOC]
+│ ╓ 0x00000310 S6 ".gnu.version_d" ElfSectionType 1879048189 [SHF_ALLOC]
 │ ╙ 0x00000347
 │┌─ 0x00000348 P PT_DYNAMIC [PF_R]
 ││╓ 0x00000348 S7 ".dynamic" SHT_DYNAMIC [SHF_WRITE,SHF_ALLOC]
@@ -25,7 +25,7 @@
 ││╓ 0x000007a8 S9 ".note" SHT_NOTE [SHF_ALLOC]
 ││╙ 0x000007e3
 │└─ 0x000007e3
-│┌─ 0x000007e4 P PT_EXT 1685382480 [PF_R]
+│┌─ 0x000007e4 P ElfSegmentType 1685382480 [PF_R]
 ││╓ 0x000007e4 S10 ".eh_frame_hdr" SHT_PROGBITS [SHF_ALLOC]
 ││╙ 0x0000081f
 │└─ 0x0000081f
@@ -38,7 +38,7 @@
 │ ╓ 0x00000fe9 S14 ".altinstr_replacement" SHT_PROGBITS [SHF_ALLOC,SHF_EXECINSTR]
 │ ╙ 0x0000100a
 └── 0x0000100a
-  ╓ 0x0000100b S15 ".comment" SHT_PROGBITS [SHF_EXT 16,SHF_EXT 32]
+  ╓ 0x0000100b S15 ".comment" SHT_PROGBITS [ElfSectionFlag 16,ElfSectionFlag 32]
   ╙ 0x0000102e
   ╓ 0x0000102f S16 ".shstrtab" SHT_STRTAB []
   ╙ 0x000010d4
