diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,11 @@
+1.1.0
+=====
+
+- Compile with GHC 8.8, 9.0, 9.2.
+- Set up Github CI to build that.
+- Fix bug that did not allow to specify length of `NOBITS` sections.
+- Misc minor fixes
+
 1.0.2
 =====
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -255,7 +255,7 @@
 
 To create machine code that is used in the examples a pair of modules were created.
 The module
-[`AsmAArch64`](https://github.com/aleksey-makarov/melf/blob/v1.0.2/examples/AsmAarch64.hs)
+[`AsmAArch64`](https://github.com/aleksey-makarov/melf/blob/v1.0.2/examples/AsmAArch64.hs)
 provides a DSL embedded in Haskell.
 This DSL is a kind of assembler language for the AArch64 platform.
 It exports some primitives to generate machine instructions and organize machine code.
@@ -267,7 +267,8 @@
 ```
 
 The idea was inspired by the article
-([Stephen Diehl "Monads to Machine Code"](https://www.stephendiehl.com/posts/monads_machine_code.html)).
+["Monads to Machine Code"](https://www.stephendiehl.com/posts/monads_machine_code.html)
+by Stephen Diehl.
 Detailed description of this module is available in russian:
 [README_ru.md](https://github.com/aleksey-makarov/melf/blob/v1.0.2/examples/README_ru.md).
 
diff --git a/examples/AsmAArch64.hs b/examples/AsmAArch64.hs
--- a/examples/AsmAArch64.hs
+++ b/examples/AsmAArch64.hs
@@ -5,11 +5,18 @@
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE RecordWildCards #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE StandaloneKindSignatures #-}
 {-# LANGUAGE TemplateHaskell #-}
 {-# 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
@@ -39,7 +46,6 @@
 import Data.ByteString.Lazy as BSL
 import Data.ByteString.Lazy.Char8 as BSLC
 import Data.Int
-import Data.Kind
 import Data.Singletons.Sigma
 import Data.Singletons.TH
 import Data.Word
@@ -50,8 +56,7 @@
 
 $(singletons [d| data RegisterWidth = X | W |])
 
-type Register :: RegisterWidth -> Type
-newtype Register c = R Word32
+newtype Register (c :: RegisterWidth) = R Word32
 
 newtype CodeOffset  = CodeOffset  { getCodeOffset  :: Int64 }  deriving (Eq, Show, Ord, Num, Enum, Real, Integral, Bits, FiniteBits)
 newtype Instruction = Instruction { getInstruction :: Word32 } deriving (Eq, Show, Ord, Num, Enum, Real, Integral, Bits, FiniteBits)
@@ -120,7 +125,7 @@
 builderRepeatZero n = mconcat $ P.replicate n (word8 0)
 
 b64 :: forall w . SingI w => Register w -> Word32
-b64 _ = case sing @ w of
+b64 _ = case sing @w of
     SX -> 1
     SW -> 0
 
diff --git a/examples/README_ru.md b/examples/README_ru.md
--- a/examples/README_ru.md
+++ b/examples/README_ru.md
@@ -175,8 +175,8 @@
 на основании этой информации создаётся список элементов типа
 [`ElfXX`](https://hackage.haskell.org/package/melf-1.0.1/docs/Data-Elf.html#t:ElfXX),
 отображающий рекурсивную
-структуру файла ELF.  Кроме восстановления структуры в процессе разбора, по номерам
-секций восстанавливаются их имена.  В результате получается объект типа
+структуру файла ELF.  Кроме восстановления структуры, в процессе разбора по индексам таблицы
+строк восстанавливаются имена секций.  В результате получается объект типа
 [`Elf`](https://hackage.haskell.org/package/melf-1.0.1/docs/Data-Elf.html#t:Elf):
 
 ``` Haskell
@@ -392,7 +392,7 @@
 -- | C6.2.10 ADR
 adr :: MonadState CodeState m =>
                   Register 'X ->
-                  Label -> m ()
+                        Label -> m ()
 ```
 
 Для добавления данных в массив литералов используется функция `emitPool`:
diff --git a/melf.cabal b/melf.cabal
--- a/melf.cabal
+++ b/melf.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           melf
-version:        1.0.2
+version:        1.1.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.10.7
+    GHC == 8.8.4, GHC == 8.10.7, GHC == 9.0.1, GHC == 9.2.1
 extra-doc-files:
     ChangeLog.md
     README.md
@@ -71,14 +71,18 @@
       src
   ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wno-redundant-constraints
   build-depends:
-      base >=4.6 && <5.0
-    , binary >=0.8.8 && <0.9
-    , bytestring >=0.10.12 && <0.11
+      base >=4.13 && <5.0
+    , binary >=0.8.7 && <0.9
+    , bytestring >=0.10.10 && <0.12
     , exceptions >=0.10.4 && <0.11
     , mtl >=2.2.2 && <2.3
     , prettyprinter >=1.7.0 && <1.8
-    , singletons >=2.7 && <3
-    , template-haskell ==2.16.*
+    , singletons >=2.6 && <3.2
+    , template-haskell >=2.15 && <2.19
+  if impl(ghc >= 9.0)
+    build-depends:
+        singletons-base >=3.0 && <3.2
+      , singletons-th >=3.0 && <3.2
   default-language: Haskell2010
 
 executable hobjdump
@@ -89,7 +93,7 @@
       app
   ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wno-redundant-constraints -fno-warn-unused-do-bind -threaded -rtsopts -with-rtsopts=-N
   build-depends:
-      base >=4.6 && <5.0
+      base >=4.13 && <5.0
     , binary
     , bytestring
     , melf
@@ -105,7 +109,7 @@
       app
   ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wno-redundant-constraints -fno-warn-unused-do-bind -threaded -rtsopts -with-rtsopts=-N
   build-depends:
-      base >=4.6 && <5.0
+      base >=4.13 && <5.0
     , binary
     , bytestring
     , exceptions
@@ -126,7 +130,7 @@
       examples
   ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wno-redundant-constraints
   build-depends:
-      base >=4.6 && <5.0
+      base >=4.13 && <5.0
     , bytestring
     , containers >=0.6.2.1 && <0.7
     , exceptions
@@ -138,6 +142,9 @@
     , tasty-golden
     , tasty-hunit
     , unix >=2.7.2.2 && <2.8
+  if impl(ghc >= 9.0)
+    build-depends:
+        singletons-th
   default-language: Haskell2010
 
 test-suite exceptions
@@ -149,7 +156,7 @@
       tests/exceptions
   ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wno-redundant-constraints
   build-depends:
-      base >=4.6 && <5.0
+      base >=4.13 && <5.0
     , exceptions
     , melf
     , tasty
@@ -165,7 +172,7 @@
       tests
   ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wno-redundant-constraints
   build-depends:
-      base >=4.6 && <5.0
+      base >=4.13 && <5.0
     , binary
     , bytestring
     , directory >=1.3.6 && <1.4
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
@@ -22,13 +22,20 @@
 {-# LANGUAGE RecordWildCards #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE StandaloneKindSignatures #-}
 {-# LANGUAGE TemplateHaskell #-}
 {-# LANGUAGE TypeApplications #-}
 {-# LANGUAGE TypeFamilyDependencies #-}
 {-# 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 (
@@ -83,29 +90,28 @@
 
     ) where
 
--- import Control.Lens hiding (at)
--- import Control.Arrow
 import Control.Monad
 import Control.Monad.Catch
--- import Control.Monad.State hiding (get, put)
--- import qualified Control.Monad.State as S
 import Data.Binary
 import Data.Binary.Get
 import Data.Binary.Put
 import Data.Bits
 import Data.ByteString       as BS
 import Data.ByteString.Lazy  as BSL
--- import Data.ByteString.Char8 as BSC
 import Data.Data (Data)
-import Data.Kind
--- import Data.Kind
 import qualified Data.List as L
 import Data.Singletons.Sigma
 import Data.Singletons.TH
 import Data.Typeable (Typeable)
--- import Numeric.Interval as I
--- import Numeric.Interval.NonEmpty as INE
 
+#if defined(MIN_VERSION_GLASGOW_HASKELL)
+#if MIN_VERSION_GLASGOW_HASKELL(9,0,0,0)
+import Data.Eq.Singletons
+import Text.Show.Singletons
+import Data.Bool.Singletons
+#endif
+#endif
+
 import Control.Exception.ChainedException
 import Data.BList
 import Data.Endian
@@ -203,7 +209,6 @@
 
 -- | @IsElfClass a@ is defined for each constructor of `ElfClass`.
 --   It defines @WordXX a@, which is `Word32` for `ELFCLASS32` and `Word64` for `ELFCLASS64`.
-type IsElfClass :: ElfClass -> Constraint
 class ( SingI c
       , Typeable c
       , Typeable (WordXX c)
@@ -221,7 +226,7 @@
       , FiniteBits (WordXX c)
       , Binary (Be (WordXX c))
       , Binary (Le (WordXX c))
-      ) => IsElfClass c where
+      ) => IsElfClass (c :: ElfClass) where
     type WordXX c = r | r -> c
 
 instance IsElfClass 'ELFCLASS32 where
@@ -235,7 +240,6 @@
 --------------------------------------------------------------------------
 
 -- | Parsed ELF header
-type HeaderXX :: ElfClass -> Type
 data HeaderXX c =
     HeaderXX
         { hData       :: ElfData    -- ^ Data encoding (big- or little-endian)
@@ -370,7 +374,7 @@
 --------------------------------------------------------------------------
 
 -- | Parsed ELF section table entry
-data SectionXX (c :: ElfClass) =
+data SectionXX c =
     SectionXX
         { sName      :: Word32         -- ^ Section name
         , sType      :: ElfSectionType -- ^ Section type
@@ -418,19 +422,19 @@
     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)
+    put = withElfClass (sing @a) (putSection putBe) . fromBe
+    get = Be <$> withElfClass (sing @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)
+    put = withElfClass (sing @a) (putSection putLe) . fromLe
+    get = Le <$> withElfClass (sing @a) (getSection getLe)
 
 --------------------------------------------------------------------------
 -- Segment
 --------------------------------------------------------------------------
 
 -- | Parsed ELF segment table entry
-data SegmentXX (c :: ElfClass) =
+data SegmentXX c =
     SegmentXX
         { pType     :: ElfSegmentType -- ^ Type of segment
         , pFlags    :: ElfSegmentFlag -- ^ Segment attributes
@@ -514,7 +518,7 @@
 sectionIsSymbolTable sType  = sType `L.elem` [SHT_SYMTAB, SHT_DYNSYM]
 
 -- | Parsed ELF symbol table entry
-data SymbolXX (c :: ElfClass) =
+data SymbolXX c =
     SymbolXX
         { stName  :: Word32          -- ^ Symbol name
         , stInfo  :: Word8           -- ^ Type and Binding attributes
@@ -582,7 +586,7 @@
 --------------------------------------------------------------------------
 
 -- | Parsed relocation table entry (@ElfXX_Rela@)
-data RelaXX (c :: ElfClass) =
+data RelaXX c =
     RelaXX
         { relaOffset :: WordXX c -- ^ Address of reference
         , relaSym    :: Word32   -- ^ Symbol table index
@@ -612,7 +616,7 @@
     (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 sing @c of
         SELFCLASS64 -> (\x -> (relaSym64 x, relaType64 x)) <$> getE
         SELFCLASS32 -> (\x -> (relaSym32 x, relaType32 x)) <$> getE
     relaAddend <- getE
@@ -623,22 +627,22 @@
                                   RelaXX c -> Put
 putRelocationTableAEntry putE (RelaXX{..}) = do
     putE relaOffset
-    (case sing @ c of
+    (case sing @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)
+    put = withElfClass (sing @a) (putRelocationTableAEntry putBe) . fromBe
+    get = Be <$> withElfClass (sing @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)
+    put = withElfClass (sing @a) (putRelocationTableAEntry putLe) . fromLe
+    get = Le <$> withElfClass (sing @a) (getRelocationTableAEntry getLe)
 
 -- | Size of @RelaXX a@ in bytes.
 relocationTableAEntrySize :: forall a . IsElfClass a => WordXX a
-relocationTableAEntrySize = fromIntegral $ BSL.length $ encode $ Le $ RelaXX @ a 0 0 0 0
+relocationTableAEntrySize = fromIntegral $ BSL.length $ encode $ Le $ RelaXX @a 0 0 0 0
 
 --------------------------------------------------------------------------
 -- parseHeaders
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
@@ -365,6 +365,7 @@
             return $  printWord64 relaOffset
                   <+> printWord64 relaAddend
                   <+> viaShow (ElfRelocationType_AARCH64 relaType)
+                  <+> viaShow relaSym
                   <+> printElfSymbolTableEntryLine symbolTableEntry
 
         split xs = if full then xs else
@@ -405,32 +406,38 @@
                 , ("Entry",      printWordXX ehEntry  ) -- WordXX c
                 , ("Flags",      printWord32 ehFlags  ) -- Word32
                 ]
-        printElf'' s@ElfSection{ esData = (ElfSectionData bs), ..} = do
-            (sectionName, dataDoc) <- if sectionIsSymbolTable esType
-                then do
-                    stes <- parseSymbolTable hData s elfs
-                    return ("symbol table section", if null stes then "" else line <> indent 4 (printElfSymbolTable full stes))
-                else if hMachine == EM_AARCH64
-                        && hData == ELFDATA2LSB
-                       && esType == SHT_RELA
-                    && esEntSize == withElfClass classS relocationTableAEntrySize then
-                        case classS of
-                            SELFCLASS64 -> ("section", ) <$> printRelocationTableA_AARCH64 full esLink elfs bs
-                            SELFCLASS32 -> $chainedError "invalid ELF: EM_AARCH64 and ELFCLASS32"
-                else
-                    return ("section", printData full bs)
-            return $ formatPairsBlock (sectionName <+> viaShow (fromIntegral esN :: Word) <+> dquotes (pretty esName))
-                [ ("Type",       viaShow esType          )
-                , ("Flags",      viaShow $ splitBits esFlags )
-                , ("Addr",       printWordXX esAddr      )
-                , ("AddrAlign",  printWordXX esAddrAlign )
-                , ("EntSize",    printWordXX esEntSize   )
-                , ("Info",       printWord32 esInfo      )
-                , ("Link",       printWord32 esLink      )
-                , ("Data",       dataDoc )
-                ]
-        printElf'' ElfSection{ esData = ElfSectionDataStringTable, ..} =
-            return $ "string table section" <+> viaShow (fromIntegral esN :: Word) <+> dquotes (pretty esName)
+        printElf'' s@ElfSection{ ..} =
+            let
+                printSection' sectionTitle dataDoc = formatPairsBlock (sectionTitle <+> viaShow (fromIntegral esN :: Word) <+> dquotes (pretty esName))
+                    [ ("Type",       viaShow esType          )
+                    , ("Flags",      viaShow $ splitBits esFlags )
+                    , ("Addr",       printWordXX esAddr      )
+                    , ("AddrAlign",  printWordXX esAddrAlign )
+                    , ("EntSize",    printWordXX esEntSize   )
+                    , ("Info",       printWord32 esInfo      )
+                    , ("Link",       printWord32 esLink      )
+                    , ("Data",       dataDoc )
+                    ]
+            in
+                case esData of
+                    ElfSectionDataNoBits { .. } ->
+                        return $ printSection' "section" ("NoBits:" <+> viaShow esdSize)
+                    ElfSectionDataStringTable ->
+                        return $ "string table section" <+> viaShow (fromIntegral esN :: Word) <+> dquotes (pretty esName)
+                    ElfSectionData bs ->
+                        if sectionIsSymbolTable esType
+                            then do
+                                stes <- parseSymbolTable hData s elfs
+                                return $ printSection' "symbol table section" $ if null stes then "" else line <> indent 4 (printElfSymbolTable full stes)
+                            else if hMachine == EM_AARCH64
+                                    && hData == ELFDATA2LSB
+                                && esType == SHT_RELA
+                                && esEntSize == withElfClass classS relocationTableAEntrySize then
+                                    case classS of
+                                        SELFCLASS64 -> printSection' "section" <$> printRelocationTableA_AARCH64 full esLink elfs bs
+                                        SELFCLASS32 -> $chainedError "invalid ELF: EM_AARCH64 and ELFCLASS32"
+                            else
+                                return $ printSection' "section" $ printData full bs
         printElf'' ElfSegment{..} = do
             dataDoc <- if null epData
                 then return ""
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
@@ -11,7 +11,6 @@
 {-# LANGUAGE RecordWildCards #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE StandaloneKindSignatures #-}
 {-# LANGUAGE TemplateHaskell #-}
 {-# LANGUAGE TypeApplications #-}
 {-# LANGUAGE TypeFamilyDependencies #-}
@@ -29,21 +28,17 @@
 import Control.Monad
 import Control.Monad.Catch
 import Control.Monad.State as MS
--- import Data.Bifunctor
 import Data.Binary
 import Data.Bits as Bin
 import Data.ByteString.Lazy.Char8 as BSL8
 import Data.ByteString.Lazy as BSL
--- import Data.Either
 import Data.Foldable
 import Data.Int
--- import Data.Kind
 import qualified Data.List as L
 import Data.Maybe
 import Data.Monoid
 import Data.Singletons
 import Data.Singletons.Sigma
--- import Data.Word
 
 -- import System.IO.Unsafe
 
@@ -65,7 +60,7 @@
 -- | @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
 -- by `Data.Elf.PrettyPrint.printLayout`
-data RBuilder (c :: ElfClass)
+data RBuilder c
     = RBuilderHeader
         { rbhHeader :: HeaderXX c
         }
@@ -289,6 +284,8 @@
     in
         addRBuilders' addRBuilderNonEmpty nonEmptyRBs [] >>= addRBuilders' addRBuilderEmpty emptyRBs
 
+-- 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
 newtype ElfList c = ElfList [ElfXX c]
@@ -299,12 +296,17 @@
 -- | Section data may contain a string table.
 -- If a section contains a string table with section names, the data
 -- for such a section is generated and `esData` should contain `ElfSectionDataStringTable`
-data ElfSectionData
-    = ElfSectionData BSL.ByteString -- ^ Regular section data
+data ElfSectionData c
+    = ElfSectionData                -- ^ Regular section data
+        { esdData :: BSL.ByteString -- ^ The content of the section
+        }
     | ElfSectionDataStringTable     -- ^ Section data will be generated from section names
+    | ElfSectionDataNoBits          -- ^ SHT_NOBITS uninitialized section data: section has size but no content
+        { esdSize :: WordXX c       -- ^ Size of the section
+        }
 
 -- | The type of node that defines Elf structure.
-data ElfXX (c :: ElfClass)
+data ElfXX c
     = ElfHeader
         { ehData       :: ElfData    -- ^ Data encoding (big- or little-endian)
         , ehOSABI      :: ElfOSABI   -- ^ OS/ABI identification
@@ -326,7 +328,7 @@
         , esN         :: ElfSectionIndex -- ^ Section number
         , esInfo      :: Word32         -- ^ Miscellaneous information
         , esLink      :: Word32         -- ^ Link to other section
-        , esData      :: ElfSectionData -- ^ The content of the section
+        , esData      :: ElfSectionData c -- ^ The content of the section
         }
     | ElfSegment
         { epType       :: ElfSegmentType -- ^ Type of segment
@@ -576,13 +578,12 @@
                 , esN         = rbsN
                 , esInfo      = sInfo
                 , esLink      = sLink
-                , esData      = if rbsN == hShStrNdx
-                    then
-                        ElfSectionDataStringTable
-                    else
-                        ElfSectionData if I.empty $ sectionInterval s
-                            then BSL.empty
-                            else getSectionData bs s
+                , esData      =
+                    if rbsN == hShStrNdx
+                        then ElfSectionDataStringTable
+                        else if sType == SHT_NOBITS
+                            then ElfSectionDataNoBits sSize
+                            else ElfSectionData $ getSectionData bs s
                 }
         rBuilderToElf RBuilderSegment{ rbpHeader = SegmentXX{..}, ..} = do
             d <- mapM rBuilderToElf rbpData
@@ -622,7 +623,7 @@
     | WBuilderDataSectionTable
     | WBuilderDataSegmentTable
 
-data WBuilderState (a :: ElfClass) =
+data WBuilderState a =
     WBuilderState
         { wbsSections         :: [(ElfSectionIndex, SectionXX a)]
         , wbsSegmentsReversed :: [SegmentXX a]
@@ -758,14 +759,15 @@
         alignWord :: MonadThrow n => WBuilderState a -> n (WBuilderState a)
         alignWord = align 0 $ wordSize $ fromSing $ sing @a
 
-        dataIsEmpty :: ElfSectionData -> Bool
+        dataIsEmpty :: ElfSectionData c -> Bool
         dataIsEmpty (ElfSectionData bs)       = BSL.null bs
         dataIsEmpty ElfSectionDataStringTable = BSL.null stringTable
+        dataIsEmpty (ElfSectionDataNoBits _)  = True
 
         lastSectionIsEmpty :: [ElfXX a] -> Bool
         lastSectionIsEmpty [] = False
         lastSectionIsEmpty l = case L.last l of
-            ElfSection{..} -> esType == SHT_NOBITS || dataIsEmpty esData
+            ElfSection{..} -> dataIsEmpty esData
             _ -> False
 
         elf2WBuilder' :: MonadThrow n => ElfXX a -> WBuilderState a -> n (WBuilderState a)
@@ -792,15 +794,18 @@
                 , ..
                 }
         elf2WBuilder' ElfSection{esFlags = ElfSectionFlag f, ..} s = do
-            when (f .&. fromIntegral (complement (maxBound @ (WordXX a))) /= 0)
+            when (f .&. fromIntegral (complement (maxBound @(WordXX a))) /= 0)
                 ($chainedError $ "section flags at section " ++ show esN ++ "don't fit")
-            WBuilderState{..} <- if esType == SHT_NOBITS
+            -- I don't see any sense in aligning NOBITS sections
+            -- still gcc does it for .o files
+            WBuilderState{..} <- if esType == SHT_NOBITS && (ehType header') /= ET_REL
                 then return s
                 else align 0 esAddrAlign s
             let
-                (d, shStrNdx) = case esData of
-                    ElfSectionData bs -> (bs, wbsShStrNdx)
-                    ElfSectionDataStringTable -> (stringTable, esN)
+                (d, shStrNdx, sz) = case esData of
+                    ElfSectionData { .. } -> (esdData, wbsShStrNdx, fromIntegral $ BSL.length esdData)
+                    ElfSectionDataStringTable -> (stringTable, esN, fromIntegral $ BSL.length stringTable)
+                    ElfSectionDataNoBits { .. } -> (BSL.empty, wbsShStrNdx, esdSize)
                 (n, ns) = case wbsNameIndexes of
                     n' : ns' -> (n', ns')
                     _ -> error "internal error: different number of sections in two iterations"
@@ -809,7 +814,7 @@
                 sFlags = fromIntegral f
                 sAddr = esAddr                         -- WXX c
                 sOffset = wbsOffset                    -- WXX c
-                sSize = fromIntegral $ BSL.length d    -- WXX c
+                sSize = sz                             -- WXX c
                 sLink = esLink                         -- Word32
                 sInfo = esInfo                         -- Word32
                 sAddrAlign = esAddrAlign               -- WXX c
@@ -898,7 +903,7 @@
                                 hShStrNdx   = wbsShStrNdx
 
                                 h :: Header
-                                h = sing @ a :&: HeaderXX{..}
+                                h = sing @a :&: HeaderXX{..}
                             in
                                 encode h
                         _ -> error "this should be ElfHeader" -- FIXME
@@ -923,7 +928,7 @@
 -- FIXME: move this to a separate file
 
 -- | Parsed ELF symbol table entry. NB: This is work in progress
-data ElfSymbolXX (c :: ElfClass) =
+data ElfSymbolXX c =
     ElfSymbolXX
         { steName  :: String           -- ^ Symbol name (NB: String, not string index)
         , steBind  :: ElfSymbolBinding -- ^ Symbol binding attributes
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
@@ -416,7 +416,7 @@
     EntSize:   0x00000000
     Info:      0x00000000
     Link:      0x00000000
-    Data:      
+    Data:      NoBits: 144
 }
 section 27 ".comment" {
     Type:      SHT_PROGBITS
