diff options
Diffstat (limited to 'lib/Language/Elna/Object/Elf.hs')
| -rw-r--r-- | lib/Language/Elna/Object/Elf.hs | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/lib/Language/Elna/Object/Elf.hs b/lib/Language/Elna/Object/Elf.hs index 4328f56..5dbbd78 100644 --- a/lib/Language/Elna/Object/Elf.hs +++ b/lib/Language/Elna/Object/Elf.hs @@ -33,6 +33,7 @@ module Language.Elna.Object.Elf , elfHeaderSize , elfIdentification , elfObject + , elfSectionsSize , rInfo , stInfo ) where @@ -469,11 +470,23 @@ instance Exception ElfEncodingError fromIntegralEnum :: (Enum a, Num b) => a -> b fromIntegralEnum = fromIntegral . fromEnum +-- * Object file generation. + +-- | ELF header size. elfHeaderSize :: Elf32_Off elfHeaderSize = 52 +-- | Calculates the size of all sections based on the 'sh_size' in the given +-- headers and adds 'elfHeaderSize' to it. +elfSectionsSize :: Vector Elf32_Shdr -> Elf32_Off +elfSectionsSize = (elfHeaderSize +) + . Vector.foldr ((+) . sh_size) 0 + -- Writes an ELF object with the given header to the provided file path. -- The callback writes the sections and returns headers for those sections. +-- +-- It updates some of the header header according to the given headers and +-- expects .shstrtab be the last header in the list. elfObject :: FilePath -> Elf32_Ehdr -> (Handle -> IO (Vector Elf32_Shdr)) -> IO () elfObject outFile header putContents = withFile outFile WriteMode withObjectFile where @@ -484,7 +497,9 @@ elfObject outFile header putContents = withFile outFile WriteMode withObjectFile afterContents objectHandle headers = let headerEncodingResult = elf32Ehdr $ header - { e_shoff = elfHeaderSize + Vector.foldr ((+) . sh_size) 0 headers + { e_shoff = elfSectionsSize headers + , e_shnum = fromIntegral $ Vector.length headers + , e_shstrndx = fromIntegral (Vector.length headers) - 1 } in traverse_ (ByteString.Builder.hPutBuilder objectHandle . elf32Shdr LSB) headers >> either throwIO (putHeaders objectHandle) headerEncodingResult |
