mes/elf.mes
2016-08-13 19:19:52 +02:00

353 lines
7.6 KiB
Scheme

;;; -*-scheme-*-
(define (int->bv32 value)
(let ((bv (make-bytevector 4)))
(bytevector-u32-native-set! bv 0 value)
bv))
(define (int->bv16 value)
(let ((bv (make-bytevector 2)))
(bytevector-u16-native-set! bv 0 value)
bv))
(define vaddress #x08048000)
(define ei-magic `(#x7f ,@(string->list "ELF")))
(define ei-class '(#x01)) ;; 32 bit
(define ei-data '(#x01)) ;; little endian
(define ei-version '(#x01))
(define ei-osabi '(#x00))
(define ei-pad '(#x0 #x0 #x0 #x0 #x0 #x0 #x0 #x0))
(define e-ident
(append
ei-magic
ei-class
ei-data
ei-version
ei-osabi
ei-pad))
(define e-type '(#x02 #x00)) ;; ET_EXEC
(define e-machine '(#x03 #x00))
(define e-version '(#x01 #x00 #x00 #x00))
(define e-entry '(0 0 0 0))
(define e-phoff '(0 0 0 0))
(define e-shoff '(0 0 0 0))
(define e-flags '(#x00 #x00 #x00 #x00))
(define e-ehsize '(0 0))
(define e-phentsize '(0 0))
(define e-phnum '(#x01 #x00))
(define e-shentsize '(0 0))
(define e-shnum '(#x05 #x00))
(define e-shstrndx '(#x04 #x00))
(define (elf-header)
(append
e-ident
e-type
e-machine
e-version
e-entry
e-phoff
e-shoff
e-flags
e-ehsize
e-phentsize
e-phnum
e-shentsize
e-shnum
e-shstrndx
))
(define p-type '(#x01 #x00 #x00 #x00))
(define p-offset '(0 0 0 0))
(define p-vaddr '(0 0 0 0))
(define p-paddr '(0 0 0 0))
(define p-filesz '(0 0 0 0))
(define p-memsz '(0 0 0 0))
(define p-flags '(#x07 #x00 #x00 #x00))
(define p-align '(#x01 #x00 #x00 #x00))
(define (program-header-0)
(append
p-type
p-offset
p-vaddr
p-paddr
p-filesz
p-memsz
p-flags
p-align
))
(set! e-phentsize (int->bv16 (length (program-header-0))))
(define (program-headers)
(append
(program-header-0)
))
(define (headers)
(append
(elf-header)
(program-headers)
))
(define (elf-header-size)
(length
(elf-header)))
(set! e-phoff (int->bv32 (elf-header-size)))
(set! e-ehsize (int->bv16 (elf-header-size)))
(define (text-offset)
(length (headers)))
(define (i386:puts data)
`(
#xba #x0e #x00 #x00 #x00 ;; mov $0xe,%edx
#xb9 ,@(int->bv32 data) ;; mov $data,%ecx
#xbb #x01 #x00 #x00 #x00 ;; mov $0x1,%ebx
#xb8 #x04 #x00 #x00 #x00 ;; mov $0x4,%eax
#xcd #x80 ;; int $0x80
))
(define (i386:exit code)
`(
#xbb ,@(int->bv32 code) ;; mov $code,%ebx
#xb8 #x01 #x00 #x00 #x00 ;; mov $0x1,%eax
#xcd #x80 ;; int $0x80
))
(define (text data)
(append
(i386:puts data)
(i386:exit 0)
))
(define (text-length)
(length (text 0)))
(define (data-offset)
(length
(append
(headers)
(text 0))))
(define (data-address) (+ (data-offset) vaddress))
(set! p-filesz (int->bv32 (text-length)))
(set! p-memsz (int->bv32 (text-length)))
;; 1076
(define data
(string->list "Hello, world!\n"))
(define note
(string->list
(string-append
"MES"
;;"Mes -- Maxwell Equations of Software\n"
;;"https://gitlab.com/janneke/mes"
)
;; #x05 #x00 #x00 #x00 #x00 #x00 #x00 #x00 #x02 #x00 #x00 #x00
;; #\i #\3 #\8 #\6 #x00 #x00 #x00 #x00
))
;; 1098 sh str table
(define tab
`(
#x00 ,@(string->list ".shstrtab")
#x00 ,@(string->list ".text")
#x00 ,@(string->list ".data")
#x00 ,@(string->list ".note")
#x00 #x00 #x00 #x00
))
(define sh-0-name '(#x99 #x99 #x00 #x00))
(define sh-0-type '(#x00 #x00 #x00 #x00))
(define sh-0-flags '(#x00 #x00 #x00 #x00))
(define sh-0-addr '(#x00 #x00 #x00 #x00))
(define sh-0-offset '(#x00 #x00 #x00 #x00))
(define sh-0-size '(#x00 #x00 #x00 #x00))
(define sh-0-link '(#x00 #x00 #x00 #x00))
(define sh-0-info '(#x00 #x00 #x00 #x00))
(define sh-0-addralign '(#x00 #x00 #x00 #x00))
(define sh-0-entsize '(#x00 #x00 #x00 #x00))
(define (sh-0)
(append
sh-0-name
sh-0-type
sh-0-flags
sh-0-addr
sh-0-offset
sh-0-size
sh-0-link
sh-0-info
sh-0-addralign
sh-0-entsize
))
(set! e-shentsize (int->bv16 (length (sh-0))))
;; 10e0 sh1: .text
(define sh-text-name '(#x0b #x00 #x00 #x00))
(define sh-text-type '(#x01 #x00 #x00 #x00))
(define sh-text-flags '(#x06 #x00 #x00 #x00))
(define sh-text-addr (int->bv32 (+ vaddress (text-offset))))
(set! e-entry sh-text-addr)
(set! p-vaddr sh-text-addr)
(set! p-paddr sh-text-addr)
(define sh-text-offset (int->bv32 (text-offset)))
(set! p-offset sh-text-offset)
(define sh-text-size (int->bv32 (length text)))
(define sh-text-link '(#x00 #x00 #x00 #x00))
(define sh-text-info '(#x00 #x00 #x00 #x00))
(define sh-text-addralign '(#x01 #x00 #x00 #x00))
(define sh-text-entsize '(#x00 #x00 #x00 #x00))
(define (sh-text)
(append
sh-text-name
sh-text-type
sh-text-flags
sh-text-addr
sh-text-offset
sh-text-size
sh-text-link
sh-text-info
sh-text-addralign
sh-text-entsize
))
;; 1108 sh2: .data
(define sh-data-name '(#x11 #x00 #x00 #x00))
(define sh-data-type '(#x01 #x00 #x00 #x00))
(define sh-data-flags '(#x03 #x00 #x00 #x00))
(define sh-data-addr (int->bv32 (data-address)))
(define sh-data-offset (int->bv32 (data-offset)))
(define sh-data-size (int->bv32 (length data)))
(define sh-data-link '(#x00 #x00 #x00 #x00))
(define sh-data-info '(#x00 #x00 #x00 #x00))
(define sh-data-addralign '(#x01 #x00 #x00 #x00))
(define sh-data-entsize '(#x00 #x00 #x00 #x00))
(define (sh-data)
(append
sh-data-name
sh-data-type
sh-data-flags
sh-data-addr
sh-data-offset
sh-data-size
sh-data-link
sh-data-info
sh-data-addralign
sh-data-entsize
))
;; 1130 sh3: .note
(define sh-note-name '(#x17 #x00 #x00 #x00))
(define sh-note-type '(#x07 #x00 #x00 #x00))
(define sh-note-flags '(#x00 #x00 #x00 #x00))
(define sh-note-addr '(#x00 #x00 #x00 #x00))
(define sh-note-offset '(0 0 0 0))
(define sh-note-size (int->bv32 (length note)))
(define sh-note-link '(#x00 #x00 #x00 #x00))
(define sh-note-info '(#x00 #x00 #x00 #x00))
(define sh-note-addralign '(#x01 #x00 #x00 #x00))
(define sh-note-entsize '(#x00 #x00 #x00 #x00))
(define (sh-note)
(append
sh-note-name
sh-note-type
sh-note-flags
sh-note-addr
sh-note-offset
sh-note-size
sh-note-link
sh-note-info
sh-note-addralign
sh-note-entsize
))
;; 1158 sh4: .shstrtab
(define sh-tab-name '(#x01 #x00 #x00 #x00))
(define sh-tab-type '(#x03 #x00 #x00 #x00))
(define sh-tab-flags '(#x00 #x00 #x00 #x00))
(define sh-tab-addr '(#x00 #x00 #x00 #x00))
(define sh-tab-offset '(0 0 0 0))
(define sh-tab-size (int->bv32 (length tab)))
(define sh-tab-link '(#x00 #x00 #x00 #x00))
(define sh-tab-info '(#x00 #x00 #x00 #x00))
(define sh-tab-addralign '(#x01 #x00 #x00 #x00))
(define sh-tab-entsize '(#x00 #x00 #x00 #x00))
(define (sh-tab)
(append
sh-tab-name
sh-tab-type
sh-tab-flags
sh-tab-addr
sh-tab-offset
sh-tab-size
sh-tab-link
sh-tab-info
sh-tab-addralign
sh-tab-entsize
))
(define (section-headers)
(append
(sh-0)
(sh-text)
(sh-data)
(sh-note)
(sh-tab)
))
(define (note-offset)
(length
(append
(headers)
(text 0)
data
)))
(set! sh-note-offset (int->bv32 (note-offset)))
(define (tab-offset)
(length
(append
(headers)
(text 0)
data
note
)))
(set! sh-tab-offset (int->bv32 (tab-offset)))
(define (section-headers-offset)
(length
(append
(headers)
(text 0)
data
note
tab)))
(set! e-shoff (int->bv32 (section-headers-offset)))
(define exe
(append
(headers)
(text (data-address))
data
note
tab
(section-headers)
))
(map write-char exe)