melf-1.0.1: examples/DummyLd.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
module DummyLd (dummyLd) where
import Control.Monad.Catch
import Data.Bits
import Data.ByteString.Lazy as BSL
import Data.Word
import Data.Singletons.Sigma
import Data.Elf
import Data.Elf.Constants
import Data.Elf.Headers
import Control.Exception.ChainedException
addr :: Word64
addr = 0x400000
mkExe :: MonadThrow m => BSL.ByteString -> m (ElfList 'ELFCLASS64)
mkExe txt = return $ ElfList [ segment ]
where
segment = ElfSegment
{ epType = PT_LOAD
, epFlags = PF_X .|. PF_R
, epVirtAddr = addr
, epPhysAddr = addr
, epAddMemSize = 0
, epAlign = 0x10000
, epData =
[ ElfHeader
{ ehData = ELFDATA2LSB
, ehOSABI = ELFOSABI_SYSV
, ehABIVersion = 0
, ehType = ET_EXEC
, ehMachine = EM_AARCH64
, ehEntry = addr + headerSize ELFCLASS64
, ehFlags = 0
}
, ElfRawData
{ edData = txt
}
, ElfSegmentTable
]
}
dummyLd' :: MonadThrow m => ElfList 'ELFCLASS64 -> m (ElfList 'ELFCLASS64)
dummyLd' (ElfList es) = do
txtSection <- elfFindSectionByName es ".text"
case txtSection of
ElfSection{esData = ElfSectionData textData} -> mkExe textData
_ -> $chainedError "could not find correct \".text\" section"
-- | It places the content of ".text" section of the input ELF into the
-- loadable segment of the resulting ELF.
-- It could work if there are no relocations or references to external symbols
dummyLd :: MonadThrow m => Elf -> m Elf
dummyLd (SELFCLASS32 :&: _) = $chainedError "AArch64 arch object expected"
dummyLd (SELFCLASS64 :&: es) = (SELFCLASS64 :&:) <$> dummyLd' es