summaryrefslogtreecommitdiff
path: root/src/Main.hs
blob: 4d5e406046279f6b9d6fe0c09e8012b1f0bfa986 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
module Main
    ( main
    ) where

import Language.Elna.CommandLine (CommandLine(..), commandLine, execParser)
import Language.Elna.Object.Elf
    ( Elf32_Ehdr(..)
    , ElfMachine(..)
    , ElfType(..)
    , ElfVersion(..)
    , ElfIdentification(..)
    , ElfClass(..)
    , ElfData(..)
    , Elf32_Shdr(..)
    , ElfSectionType(..)
    , elfHeaderSize
    , elfObject
    )
import qualified Data.ByteString as ByteString
import Data.Vector (Vector)
import qualified Data.Vector as Vector
import Data.Maybe (fromMaybe)
import System.IO (Handle)
import System.FilePath (replaceExtension, takeFileName)

riscv32Elf :: Handle -> IO (Vector Elf32_Shdr)
riscv32Elf objectHandle =
    let stringTable = "\0shstrtab\0"
        written = Vector.fromList
            [ Elf32_Shdr
                { sh_type = SHT_NULL
                , sh_size = 0
                , sh_offset = 0
                , sh_name = 0
                , sh_link = 0
                , sh_info = 0
                , sh_flags = 0
                , sh_entsize = 0
                , sh_addralign = 0
                , sh_addr = 0
                }
            , Elf32_Shdr
                { sh_type = SHT_STRTAB
                , sh_size = fromIntegral $ ByteString.length stringTable
                , sh_offset = fromIntegral elfHeaderSize
                , sh_name = 1
                , sh_link = 0
                , sh_info = 0
                , sh_flags = 0
                , sh_entsize = 0
                , sh_addralign = 0
                , sh_addr = 0
                }
            ]
        in ByteString.hPut objectHandle stringTable >> pure written

riscv32Header :: Elf32_Ehdr
riscv32Header = Elf32_Ehdr
    { e_version = EV_CURRENT
    , e_type = ET_REL
    , e_shstrndx = 1 -- String table. SHN_UNDEF
    , e_shoff = 0
    , e_shnum = 2
    , e_shentsize = 40
    , e_phoff = 0
    , e_phnum = 0
    , e_phentsize = 32
    , e_machine = EM_RISCV
    , e_ident = ElfIdentification ELFCLASS32 ELFDATA2LSB
    , e_flags = 0x4 -- EF_RISCV_FLOAT_ABI_DOUBLE
    , e_entry = 0
    , e_ehsize = fromIntegral elfHeaderSize
    }

main :: IO ()
main  = execParser commandLine >>= withCommandLine
  where
    withCommandLine CommandLine{..} =
        let defaultOutput = replaceExtension (takeFileName input) "o"
         in elfObject (fromMaybe defaultOutput output) riscv32Header riscv32Elf