(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}))