77 lines
1.8 KiB
Fennel
77 lines
1.8 KiB
Fennel
(local {: print-string} (require :print))
|
|
|
|
(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}))
|
|
|
|
(with-open [f (io.open :test.elf :w)]
|
|
(f:write elf))
|
|
(print-string elf)
|