melf 1.2.0 → 1.3.0
raw patch · 27 files changed
+738/−726 lines, 27 filesdep −singletonsdep −singletons-basedep −singletons-thdep ~mtldep ~template-haskell
Dependencies removed: singletons, singletons-base, singletons-th, unix
Dependency ranges changed: mtl, template-haskell
Files
- ChangeLog.md +12/−0
- README.md +58/−48
- app/hObjDump.hs +0/−1
- examples/AsmAArch64.hs +20/−18
- examples/DummyLd.hs +4/−6
- examples/Examples.hs +9/−13
- examples/helloWorldObj.o.dump.golden +1/−1
- melf.cabal +5/−22
- src/Data/Elf.hs +4/−6
- src/Data/Elf/Constants.hs +0/−1
- src/Data/Elf/Constants/Data.hs +303/−305
- src/Data/Elf/Constants/TH.hs +14/−23
- src/Data/Elf/Headers.hs +139/−108
- src/Data/Elf/PrettyPrint.hs +21/−23
- src/Data/Internal/Elf.hs +50/−67
- tests/Golden.hs +19/−17
- tests/exceptions/Exceptions.hs +26/−14
- tests/testdata/orig/bloated.elf.golden +13/−13
- tests/testdata/orig/bloated.elf_header.golden +1/−1
- tests/testdata/orig/bloated.header.golden +9/−9
- tests/testdata/orig/bloated.layout.golden +10/−10
- tests/testdata/orig/tiny.elf_header.golden +1/−1
- tests/testdata/orig/tiny.header.golden +1/−1
- tests/testdata/orig/vdso.elf.golden +7/−7
- tests/testdata/orig/vdso.elf_header.golden +1/−1
- tests/testdata/orig/vdso.header.golden +5/−5
- tests/testdata/orig/vdso.layout.golden +5/−5
ChangeLog.md view
@@ -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 =====
README.md view
@@ -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:
app/hObjDump.hs view
@@ -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
examples/AsmAArch64.hs view
@@ -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
examples/DummyLd.hs view
@@ -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
examples/Examples.hs view
@@ -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+ )
examples/helloWorldObj.o.dump.golden view
@@ -40,7 +40,7 @@ symbol "_start" { Bind: STB_Global Type: STT_NoType- ShNdx: SHN_EXT 1+ ShNdx: ElfSectionIndex 1 Value: 0x0000000000000000 Size: 0x0000000000000000 }
melf.cabal view
@@ -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
src/Data/Elf.hs view
@@ -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
src/Data/Elf/Constants.hs view
@@ -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
src/Data/Elf/Constants/Data.hs view
@@ -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)") ])
src/Data/Elf/Constants/TH.hs view
@@ -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
src/Data/Elf/Headers.hs view
@@ -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
src/Data/Elf/PrettyPrint.hs view
@@ -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
src/Data/Internal/Elf.hs view
@@ -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
tests/Golden.hs view
@@ -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
tests/exceptions/Exceptions.hs view
@@ -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
tests/testdata/orig/bloated.elf.golden view
@@ -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 }
tests/testdata/orig/bloated.elf_header.golden view
@@ -12,4 +12,4 @@ PhNum: 9 ShEntSize: 0x0028 ShNum: 31-ShStrNdx: SHN_EXT 28+ShStrNdx: ElfSectionIndex 28
tests/testdata/orig/bloated.header.golden view
@@ -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
tests/testdata/orig/bloated.layout.golden view
@@ -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
tests/testdata/orig/tiny.elf_header.golden view
@@ -12,4 +12,4 @@ PhNum: 2 ShEntSize: 0x0040 ShNum: 3-ShStrNdx: SHN_EXT 2+ShStrNdx: ElfSectionIndex 2
tests/testdata/orig/tiny.header.golden view
@@ -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
tests/testdata/orig/vdso.elf.golden view
@@ -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
tests/testdata/orig/vdso.elf_header.golden view
@@ -12,4 +12,4 @@ PhNum: 4 ShEntSize: 0x0040 ShNum: 17-ShStrNdx: SHN_EXT 16+ShStrNdx: ElfSectionIndex 16
tests/testdata/orig/vdso.header.golden view
@@ -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
tests/testdata/orig/vdso.layout.golden view
@@ -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