mango/host/assembler/elf.fnl

71 lines
1.7 KiB
Fennel

(local byte string.char)
(fn word->byte [x]
"convert a 32 bit word into a little endian byte string"
(string.char
(-> x (band 0xff))
(-> x (rshift 8) (band 0xff))
(-> x (rshift 16) (band 0xff))
(-> x (rshift 24))))
(fn half->byte [x]
"convert a 16 bit half-word into a little endian byte string"
(string.char
(-> x (band 0xff))
(-> x (rshift 8) (band 0xff))))
(local magic
(..
(byte 0x7f)
:ELF))
(local abi {:sysv 0})
(local isa {:arm32 0x28})
(local file-type {:executable 0x2})
(fn header [{:entry-point entry-point
:phead-offset phead-offset
:phead-count phead-count
:section-header-offset shead-offset
:section-header-count shead-count
:string-section-index string-section-index
:flags flags}]
(let [phead-offset (or phead-offset 0x34)
flags (or flags 0)]
(.. magic
; 32 bit
(byte 1)
; little endian
(byte 1)
; version
(byte 1)
(byte (. abi :sysv))
;abi version -- ignored
(byte 0)
; padding
(byte 0 0 0)
(word->byte 0)
(half->byte (. file-type :executable))
(half->byte (. isa :arm32))
; version again
(word->byte 1)
(word->byte entry-point)
(word->byte phead-offset)
(word->byte shead-offset)
(word->byte flags)
; structure size
(half->byte 0x34)
; program header size
(half->byte 0x20)
(half->byte phead-count)
; section header size
(half->byte 0x28)
(half->byte shead-count)
(half->byte string-section-index))))
(fn program-header [{}])
(local elf
(header {:entry-point 0x8000
:section-header-offset 0x100
:section-header-count 0
:string-section-index 0
:phead-count 0}))