melf 1.0.2 → 1.1.0
raw patch · 9 files changed
+142/−105 lines, 9 filesdep +singletons-basedep +singletons-thdep ~basedep ~binarydep ~bytestring
Dependencies added: singletons-base, singletons-th
Dependency ranges changed: base, binary, bytestring, singletons, template-haskell
Files
- ChangeLog.md +8/−0
- README.md +3/−2
- examples/AsmAArch64.hs +10/−5
- examples/README_ru.md +3/−3
- melf.cabal +19/−12
- src/Data/Elf/Headers.hs +32/−28
- src/Data/Elf/PrettyPrint.hs +33/−26
- src/Data/Internal/Elf.hs +33/−28
- tests/testdata/orig/bloated.elf.golden +1/−1
ChangeLog.md view
@@ -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 =====
README.md view
@@ -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).
examples/AsmAArch64.hs view
@@ -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
examples/README_ru.md view
@@ -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`:
melf.cabal view
@@ -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
src/Data/Elf/Headers.hs view
@@ -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
src/Data/Elf/PrettyPrint.hs view
@@ -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 ""
src/Data/Internal/Elf.hs view
@@ -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
tests/testdata/orig/bloated.elf.golden view
@@ -416,7 +416,7 @@ EntSize: 0x00000000 Info: 0x00000000 Link: 0x00000000- Data: + Data: NoBits: 144 } section 27 ".comment" { Type: SHT_PROGBITS