summaryrefslogtreecommitdiff
path: root/lib/Language/Elna/Object/ElfCoder.hs
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2024-10-27 14:00:54 +0100
committerEugen Wissner <belka@caraus.de>2024-10-27 20:43:56 +0100
commit6b92e5059c04709b3506bb4e7bef29872b16811f (patch)
tree3ff4762c38bb7930bebc5b02ac3c48f49579c612 /lib/Language/Elna/Object/ElfCoder.hs
parent57436f664e7d138bd915fb30f486e4bb802d74b6 (diff)
downloadelna-6b92e5059c04709b3506bb4e7bef29872b16811f.tar.gz
Encode labels as untyped local symbols in ELF
Diffstat (limited to 'lib/Language/Elna/Object/ElfCoder.hs')
-rw-r--r--lib/Language/Elna/Object/ElfCoder.hs34
1 files changed, 25 insertions, 9 deletions
diff --git a/lib/Language/Elna/Object/ElfCoder.hs b/lib/Language/Elna/Object/ElfCoder.hs
index c3d58a1..b01045a 100644
--- a/lib/Language/Elna/Object/ElfCoder.hs
+++ b/lib/Language/Elna/Object/ElfCoder.hs
@@ -3,20 +3,26 @@ module Language.Elna.Object.ElfCoder
( ElfEnvironment(..)
, ElfWriter(..)
, ElfHeaderResult(..)
- , elfHeaderSize
+ , UnresolvedRelocation(..)
+ , UnresolvedRelocations(..)
+ , addHeaderToResult
, addSectionHeader
+ , elfHeaderSize
, elfObject
, elfSectionsSize
, putSectionHeader
+ , partitionSymbols
, module Language.Elna.Object.Elf
) where
import Control.Exception (throwIO)
import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Trans.State (StateT, runStateT, modify', gets)
+import Data.Bits (Bits(..))
import Data.ByteString (StrictByteString)
import qualified Data.ByteString as ByteString
import qualified Data.ByteString.Builder as ByteString.Builder
+import Data.Word (Word8)
import Data.Vector (Vector)
import qualified Data.Vector as Vector
import System.IO (Handle, IOMode(..), SeekMode(..), hSeek, withFile)
@@ -26,6 +32,10 @@ import Language.Elna.Object.StringTable (StringTable)
import qualified Language.Elna.Object.StringTable as StringTable
import GHC.Records (HasField(..))
+data UnresolvedRelocation = UnresolvedRelocation StrictByteString Elf32_Addr Word8
+data UnresolvedRelocations =
+ UnresolvedRelocations (Vector UnresolvedRelocation) (ElfHeaderResult Elf32_Sym) Elf32_Word
+
data ElfEnvironment = ElfEnvironment
{ objectHeaders :: ElfHeaderResult Elf32_Shdr
, objectHandle :: Handle
@@ -57,6 +67,11 @@ instance MonadIO ElfWriter
where
liftIO = ElfWriter . liftIO
+partitionSymbols :: ElfHeaderResult Elf32_Sym -> (Vector Elf32_Sym, Vector Elf32_Sym)
+partitionSymbols = Vector.partition go . getField @"sectionHeaders"
+ where
+ go Elf32_Sym{ st_info } = (st_info .&. 0xf0) == 0
+
-- | ELF header size.
elfHeaderSize :: Elf32_Off
elfHeaderSize = 52
@@ -67,17 +82,18 @@ elfSectionsSize :: Vector Elf32_Shdr -> Elf32_Off
elfSectionsSize = (elfHeaderSize +)
. Vector.foldr ((+) . sh_size) 0
+addHeaderToResult :: StrictByteString -> a -> ElfHeaderResult a -> ElfHeaderResult a
+addHeaderToResult name newHeader accumulator@ElfHeaderResult{..} = accumulator
+ { sectionHeaders = Vector.snoc sectionHeaders newHeader
+ , sectionNames = StringTable.append name sectionNames
+ }
+
addSectionHeader :: StrictByteString -> Elf32_Shdr -> ElfWriter ()
addSectionHeader name newHeader = ElfWriter $ modify' modifier
where
- modifier elfEnvironment@ElfEnvironment{ objectHeaders } =
- let ElfHeaderResult{..} = objectHeaders
- in elfEnvironment
- { objectHeaders = ElfHeaderResult
- { sectionHeaders = Vector.snoc sectionHeaders newHeader
- , sectionNames = StringTable.append name sectionNames
- }
- }
+ modifier elfEnvironment@ElfEnvironment{ objectHeaders } = elfEnvironment
+ { objectHeaders = addHeaderToResult name newHeader objectHeaders
+ }
putSectionHeader :: StrictByteString -> Elf32_Shdr -> StrictByteString -> ElfWriter ()
putSectionHeader name newHeader encoded = do