;;; -*-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)