From c86e619db399a883dd2a2ac5d9d6ef4815dd581c Mon Sep 17 00:00:00 2001 From: Ralph Ronnquist Date: Tue, 18 May 2021 09:29:33 +1000 Subject: [PATCH] snapshot (not working) --- Makefile | 14 +- machine.fasm | 54 ------- main.fasm | 263 ++++++++++++++++++++++++++-------- math.fasm | 59 ++++++++ memory.fasm | 109 +++++++++++++++ stack.fasm | 121 ++++++++++++++++ stdio.fasm | 140 +++++++++++++++++++ symbols.lsp | 118 ++++++++++++++++ syscalls.fasm | 372 +++++++++++++++++++++++++++++++++++++++++++++++++ wordlists.fasm | 59 ++++++++ 10 files changed, 1190 insertions(+), 119 deletions(-) create mode 100644 math.fasm create mode 100644 memory.fasm create mode 100644 stack.fasm create mode 100644 stdio.fasm create mode 100755 symbols.lsp create mode 100644 syscalls.fasm create mode 100644 wordlists.fasm diff --git a/Makefile b/Makefile index 1e629b9..2a4d3bb 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,24 @@ BINARY = rrqforth -default: rrqforth +default: X VFMT := "RRQ Forth version %h at %aI" VERSION := $(shell git log -1 --pretty=format:'$(VFMT)' main.fasm) -main.fasm: machine.fasm stdio.fasm +main.fasm: machine.fasm readline.fasm syscalls.fasm version: main.fasm @echo "db '$(VERSION)'\ndb 10" > $@ -rrqforth: main.fasm | version +rrqforth: main.fasm | fasm $^ $@ chmod a+x $@ +rrqforth.fas: main.fasm rrqforth + fasm $< -s $@ + +X: rrqforth.fas + ./symbols.lsp $< > $@ + clean: - rm -f version rrqforth + rm -f version rrqforth rrqforth.fas diff --git a/machine.fasm b/machine.fasm index 92f51a1..ddfb971 100644 --- a/machine.fasm +++ b/machine.fasm @@ -44,58 +44,4 @@ ;;; ;;; function calling -;;; FORTH model -;;; rsp = data stack pointer -;;; rbp = frame pointer -;;; rdi = frame stack -;;; rsi = instruction pointer -;;; ======================================== -;;; The next macro "moves" execution to the next FORTH instruction, -;;; using rsi as instruction pointer. - - macro next { - lodsq ; mov rax, qword [rsi] - ; add rsi,8 - jmp qword [rax] ; goto code of that FORTH word - } - -;;; ======================================== -;;; The pushr macro pushes x onto the return stack -;;; The popr macro pops x from the return stack - macro pushr x { - sub rbp, 8 - mov qword [rbp], x - } - - macro popr x { - mov x, [rbp] - add rbp, 8 - } - -;;; ======================================== -;;; - - previous_word = 0 - - ;; Macro WORD starts a FORTH word definition in this code - macro WORD label, name, doer, flags { -label#_tfa: - ;; TFA - dq previous_word - ;; PFA -label#_word: - previous_word = label#_word - db flags + 0 - db label - $ - 1 - db name - ;; CFA = pointer to "interpreter" -label: - dq doer - } - - ;; Macro WORD_assembler begins an assembler implementation - macro WORD_assembler label, name, flags { - WORD label, name, label#_code, flags -label#_code: - } diff --git a/main.fasm b/main.fasm index 25e48b4..f06c158 100644 --- a/main.fasm +++ b/main.fasm @@ -1,79 +1,220 @@ -; This is a forth interpreter +; This is a forth interpreter for x86_64 (elf64) format elf64 executable - entry main_code + entry main + +;;; ======================================== +;;; The pushr macro pushes x onto the return stack +;;; The popr macro pops x from the return stack +macro pushr x { + sub rbp, 8 + mov [rbp], x +} + +macro popr x { + mov x, [rbp] + add rbp, 8 +} + +;;; ======================================== +;;; The next macro "moves" execution to the next FORTH instruction, +;;; using rsi as instruction pointer. It points to the doer field of a +;;; word, which points to the assembly code that implements the +;;; execution effect of the word. That doer code is entered with rsi +;;; referring to the subsequent address in the colling word, and rax +;;; referring to the doer field of the called word. + +macro next { + lodsq ; mov rax, [rsi] + add rsi,8 + jmp qword [rax] ; goto code of that FORTH word (64 bit jump) +} + +;;; ======================================== +;;; The FORTH macro transitions to inline FORTH execution. +macro FORTH { + local forthcode + mov rsi,forthcode + next + ;; align 8 +forthcode: +} + +;;; ======================================== +;;; The ENDFORTH macro transitions back to inline assembler after FORTH +;;; ======================================== +macro ENDFORTH { + dq inline_code +} + +;;; ======================================== +;;; The DOFORTH lays out a single FORTH call +;;; ======================================== +macro DOFORTH label { + FORTH + dq label + ENDFORTH +} + +;;; Macro WORD starts a FORTH word definition in this code +;;; + previous_word = 0 ; Used for chaining the words + + IMMEDIATE = 1 ; optional flag + +macro WORD label, name, doer, flags { + ;; align 8 +label#_TFA: + ;; TFA + dq previous_word + previous_word = label#_TFA + ;; PFA +label#_PFA: + db flags + 0 + db label - $ - 2 + db name + db 0 + ;; align 8 + +label#_OFF: + dq 0 ; The DOES offset. Defaults to 0. + ;; also CFA = pointer to "doer" +label: + if doer eq + dq doforth + else + if doer in + dq label#_DFA + else + dq doer + end if + end if + ;; DFA +label#_DFA: +} + +;;; ============================================================ +;;; FORTH machine model +;;; rsp = data stack pointer +;;; rbp = return stack pointer +;;; rsi = instruction pointer + +;;; ============================================================ -;;; ############################################################ -;;; The FORTH words segment readable writable executable -include 'machine.fasm' - - ;; PROGRAM_VERSION is the program version string - WORD program_version, 'PROGRAM_VERSION', marker - db length -program_version_string: - include 'version' - length = $ - program_version_string + WORD return_stack,'RS',dovariable + ;; The return stack + rb 1048576 ; 1 Mb return stack +RS_TOP: ; The initial rbp - ;; MAIN is the program entry point - ;; ( -- ) - WORD_assembler main, "MAIN" - mov rsi,program_version_string ; address of string - mov edx,length ; length of string (cheating) - mov edi,1 ; stdout - mov eax,1 ; sys_write - syscall - jmp terminate0_code + WORD data_stack,'DS',dovariable + ;; The data stack + rb 1048576 ; 1 Mb data stack +DS_TOP: ; The initial rsp - ;; TERMINATE0 terminates the program with code 0 + WORD inline_code,'[ASM]',fasm ;; ( -- ) - WORD_assembler terminate0, 'TERMINATE0' - xor edi,edi - mov eax,60 - syscall + ;; This transitions execution into inline assembler in the + ;; calling word defintion. Note that it stops advancing rsi; + ;; code should use FORTH macro to reenter forth execution, or + ;; exit to the calling definition via "jmp exit". + jmp qword rsi - ;; EXIT ends a forth code defintion, returning to caller - ;; ( -- ) - WORD_assembler exit, 'EXIT' +;;; Execution semantics for FORTH defition word +;;; At entry, rsi points into the calling definition, at the cell +;;; following the cell indicating this word, rax points to the CFA of +;;; this word. +doforth: + pushr rsi + lea rsi, [rax+8] ; rsi = the DFA of the rax word + next + + WORD p_exit, 'EXIT',fasm + ;; ( -- ) ( R: addr -- ) + ;; Returns execution to the calling definition as per the + ;; return stack. +exit: popr rsi next - - ;; MARKER is a word that pushes the address after itself, then exits - ;; ( -- p ) - WORD_assembler marker, 'MARKER' - push qword rsi - jmp exit_code - - ;; MARKER@ is a word that pushes a the value after itself, then exits - ;; ( -- v ) - WORD_assembler marker_get, 'MARKER@' - push qword [rsi] - jmp exit_code - - ;; DOFORTH begins a FORTH defintion - WORD_assembler doforth, 'DOFORTH' - pushr rsi - lea rsi, [rax + 8] + + ;; Execution semantics for a variable ( -- addr ) + ;; rax points to doer field +dovariable: + push rax+16 + next + + ;; Execution semantics for a constant ( -- v ) + ;; rax points to doer field +dovalue: + push qword [rax+16] next - ;; LIT is a word that pushes a the value after itself, then continues - ;; ( -- v ) - WORD_assembler lit, 'LIT' - push qword [rsi] - add rsi, 8 + ;; Execution semantics for a string constant ( -- addr n ) + ;; rax points to doer field +dostring: + add rax,16 + mov bl,[rax] + mov byte [rsp],bl + push rax+1 next - ;; HERE is a variable pointing to the free heap - WORD here, 'HERE', marker - dq heap_start ; initialise to first "free" data +include 'wordlists.fasm' +include 'syscalls.fasm' +include 'memory.fasm' +include 'stack.fasm' +include 'math.fasm' +include 'stdio.fasm' - ;; WORDS is the list of words - WORD words, 'WORDS', marker - dq forth_tfa ; initialise to last forth word + WORD p_program_version,'PROGRAM_VERSION',dostring + db length +program_version_string: + db 'RRQ Forth version 0.1 - 2021-05-13',10 + length = $ - program_version_string - ;; FORTH is the last word of the VOCABULARY - WORD forth, 'FORTH', marker_get - dq forth_tfa + WORD p_stdin,'STDIN',dovalue + ;; Initialised to hold a STREAM for fd 0 + dq 0 -heap_start: + WORD p_quit,'QUIT',fasm + ;; QUIT is the program entry point ******************** +main: + mov rsp,DS_TOP + mov rbp,RS_TOP + ;; Initialize STREAM STDIN + push 0 + push 10000 + DOFORTH p_stream + pop qword [p_stdin_DFA] + + ;; read a word + push qword 1 ; ( fd ) =stdout + push qword [p_stdin_DFA] + FORTH + dq p_read_word ; ( fd s n ) + dq sys_write + ENDFORTH + + push qword 1 ; stdout + push qword program_version_string ; address of string + push qword length ; length of string (cheating) + DOFORTH sys_write ; printout + pop rax ; ignore errors + + push 0 + DOFORTH sys_exit + ;; TERMINATE0 terminates the program with code 0 + ;; ( v -- ) + WORD terminate, 'TERMINATE',fasm + pop rdx +terminate_special: + mov eax,60 + syscall + +last_word: + ;; FORTH is the last word of VOCABULARY FORTH + WORD forth,'FORTH',dovalue + dq forth_TFA + dq 0 + + +heap_start: diff --git a/math.fasm b/math.fasm new file mode 100644 index 0000000..d25d14c --- /dev/null +++ b/math.fasm @@ -0,0 +1,59 @@ +;;; Words doing arithmetics + + WORD p_plus, '+',fasm + ;; ( n1 n2 -- n3 ) + ;; n3 is the sum of n1 and n2 + pop rax + add [rsp],rax + next + + WORD p_minus, '-',fasm + ;; ( n1 n2 -- n3 ) + ;; n3 is the result of subtracting n2 from n1 + pop rax + sub [rsp], rax + next + + WORD p_mult, '*',fasm + ;; ( n1 n2 -- n3 ) + ;; Multiply n1 by n2 giving the product n3. + ;; [rsp{8}] * [rsp+8{8}] + ;; dd00 = [rsp+4{4}]*[rsp+12{4}] ignored + ;; needs checking !! + ;; + ;; 0cc0 = [rsp{4}]*[rsp+12{4}] + mov eax, dword [rsp] + imul dword [rsp+12] + mov ebx,eax + ;; 0bb0 = [rsp+4{4}]*[rsp+8{4}] + mov eax, dword [rsp+4] + imul dword [rsp+8] + add ebx, eax + ;; 00aa = [rsp{4}]*[rsp+8{4}] + mov eax, dword [rsp] + imul dword [rsp+8] + add ebx, edx + shl rbx,32 + mov eax,eax ; ensure zero-extending eax + add rax, rbx + push rax + next + + WORD p_abs, 'ABS',fasm + ;; ( n -- u ) + ;; u is the absolute value of n. + cmp qword [rsp],0 + jge p_abs_end + neg qword [rsp] +p_abs_end: + next + + WORD p_negate, 'NEGATE',fasm + ;; ( n1 -- n2 ) + ;; Negate n1, giving its arithmetic inverse n2. + xor rax,rax + sub rax,qword [rsp] + mov qword [rsp],rax + next + + diff --git a/memory.fasm b/memory.fasm new file mode 100644 index 0000000..8a7ec6e --- /dev/null +++ b/memory.fasm @@ -0,0 +1,109 @@ +;;; This file defines "memory access words" + + WORD p_get, '@',fasm + ;; ( addr -- v ) + ;; Load value v from address addr + pop rax + push qword [rax] + next + + WORD p_put, '!',fasm + ;; ( v addr -- ) + ;; Store value v at address addr. + pop rax + pop rbx + mov qword [rax], rbx + next + + WORD p_Cget, 'C@',fasm + ;; ( addr -- v ) + ;; Load the (unsigned) byte v from address addr. + pop rax + mov bl,[rax] + push 0 + mov [rsp],bl + next + + WORD p_Cput, 'C!',fasm + ;; ( v addr -- ) + ;; Store byte value v at address addr. + pop rax + pop rbx + mov byte [rax], bl + next + + WORD p_2get, '2@',fasm + ;; ( addr -- v1 v2 ) + ;; Load the cell pair {x2,x1} from address addr. + pop rax + push qword [rax+8] + push qword [rax] + next + + WORD p_2put, '!',fasm + ;; ( v1 v2 addr -- ) + ;; Store value pair {v2,v1} at address addr. + pop rax + pop rbx + mov qword [rax], rbx + pop rbx + mov qword [rax+8], rbx + next + + WORD p_erase, 'ERASE',fasm + ;; ( addr u -- ) + ;; Clear u bytes at address addr and up. + pop rax + pop rbx + xor rcx,rcx +p_erase_loop: + cmp rax,8 + jl p_erase_last + mov qword [rbx],0 ; mov qword[rbx],rcx + add rbx,8 + sub rax,8 + jmp p_erase_loop +p_erase_more: + mov [rbx],byte 0 ; mov byte [rbx], cl + inc rbx + dec rax +p_erase_last: + jg p_erase_more + next + + WORD p_1plus, '1+',fasm + ;; ( n1 -- n2 ) + ;; Add one (1) to n1 resulting in n2. + inc qword [rsp] + next + + WORD p_plus_put, '+!',fasm + ;; ( n addr -- ) + ;; Add n to the value at addr. + pop rax + pop rbx + add [rax],rbx + next + + WORD p_1minus, '1-',fasm + ;; ( n1 -- n2 ) + ;; Subtract one (1) from n1 resulting in n2. + dec qword [rsp] + next + + WORD p_2mult, '2*',fasm + ;; ( x1 -- x2 ) + ;; x2 is the result of shifting x1 one bit toward the + ;; most-significant bit, filling the vacated least-significant + ;; bit with zero. + shl qword [rsp],1 + next + + WORD p_2div, '2/',fasm + ;; ( x1 -- x2 ) + ;; x2 is the result of shifting x1 one bit toward the + ;; least-significant bit, leaving the most-significant bit + ;; unchanged. (signed right shift) + sar qword [rsp],1 + next + diff --git a/stack.fasm b/stack.fasm new file mode 100644 index 0000000..9726cc2 --- /dev/null +++ b/stack.fasm @@ -0,0 +1,121 @@ +;;; Words for stack manipulations + + WORD p_dup, 'DUP',fasm + ;; ( v -- v v ) + ;; Duplicate top ov stack value. + ;; push qword [rsp] ?? + mov rax,qword [rsp] + push rax + next + + WORD p_2dup, '2DUP',fasm + ;; ( x1 x2 -- x1 x2 x1 x2 ) + ;; Duplicate cell pair x1 x2. + push qword [rsp+8] + push qword [rsp+8] + next + + WORD p_drop, 'DROP',fasm + ;; ( x -- ) + ;; Remove x from the stack. + add rsp,8 + next + + WORD p_2drop, '2DROP',fasm + ;; ( x1 x2 -- ) + ;; Drop cell pair x1 x2 from the stack. + add rsp,16 + next + + WORD p_over, 'OVER',fasm + ;; ( x1 x2 -- x1 x2 x1 ) + ;; Place a copy of x1 on top of the stack. + push qword [rsp+8] + next + + WORD p_2over, '2OVER',fasm + ;; ( x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2 ) + ;; Copy cell pair x1 x2 to the top of the stack. + push qword [rsp+24] + push qword [rsp+24] + next + + WORD p_swap, 'SWAP',fasm + ;; ( x1 x2 -- x2 x1 ) + ;; Exchange the top two stack items. + mov rax,qword [rsp] + mov rbx,qword [rsp+8] + mov qword [rsp+8],rax + mov qword [rsp],rbx + next + + WORD p_2swap, '2SWAP',fasm + ;; ( x1 x2 x3 x4 -- x3 x4 x1 x2 ) + ;; Exchange the top two cell pairs. + mov rax,qword [rsp] + mov rbx,qword [rsp+16] + mov qword [rsp], rbx + mov qword [rsp+16],rax + mov rax,qword [rsp+8] + mov rbx,qword [rsp+24] + mov qword [rsp+8], rbx + mov qword [rsp+24],rax + next + + WORD p_rot, 'ROT',fasm + ;; ( x1 x2 x3 -- x2 x3 x1 ) + ;; Rotate the top three stack entries. + mov rax,qword [rsp+16] + mov rbx,qword [rsp+8] + mov qword [rsp+16],rbx + mov rbx,qword [rsp] + mov qword [rsp+8],rbx + mov qword [rsp],rax + next + + ;; ( xu xu-1 ... x0 u -- xu-1 ... x0 xu ) + ;; Remove u. Rotate u+1 items on the top of the stack. An + ;; ambiguous condition exists if there are less than u+2 items + ;; on the stack before ROLL is executed. + WORD p_roll, 'ROLL',fasm + pop rcx + shl rcx,3 + add rcx,rsp + mov rax,[rcx+8] +p_roll_loop: + cmp rcx,rsp + je p_roll_eq + mov rbx,[rcx] + mov [rcx+8],rbx + sub rcx,8 + jmp p_roll_loop +p_roll_eq: + mov [rsp],rax + next + + WORD p_nip, 'NIP',fasm + ;; ( x1 x2 -- x2 ) + ;; Discard the second stack item. + pop rax + mov qword [rsp],rax + next + + WORD p_pick, 'PICK',fasm + ;; ( xu...x1 x0 u -- xu...x1 x0 xu ) + ;; Remove u. Copy the xu to the top of the stack. An ambiguous + ;; condition exists if there are less than u+2 items on the + ;; stack before PICK is executed. + pop rax + shl rax,3 ; 8 bytes per index + push qword [rsp+rax] + next + + WORD w6.2.2300, 'TUCK',fasm + ;; ( x1 x2 -- x2 x1 x2 ) + ;; insert the top stack value into below second stack value. + pop rax + pop rbx + push rax + push rbx + push rax + next diff --git a/stdio.fasm b/stdio.fasm new file mode 100644 index 0000000..ae3e08e --- /dev/null +++ b/stdio.fasm @@ -0,0 +1,140 @@ +;;; ======================================== +;;; Dynamic memory management. Allocated with MALLOC and released with +;;; MUNMAP (see below) + + ;; ( size -- addr ) + ;; Allocates memory (using brk) + WORD p_malloc,'MALLOC',fasm + pushr rsi ; pretend it's a FORTH word since it + ; ends via sys_mmap_asm + pop rax + push qword 0 ; address of mapping (suggestion) + push rax ; length of mapping + push qword 3 ; protection mode PROT_READ | PROT_WRITE + push qword 8226 ; flags PRIVATE | ANONYMOUS | LOCKED + push qword -1 ; fd -1 + push qword 0 ; offset + jmp sys_mmap_asm ; exit via sys_mmap + +;;; ======================================== +;;; Mapping files + + ;; ( fd -- address ) + ;; Request memory mapping of a file + WORD p_mmap,'MMAP',fasm + pushr rsi ; pretend it's a FORTH word since it + ; ends via sys_mmap_asm + pop rax + push qword 0 ; address of mapping (suggestion) + push qword 10240 ; length of mapping + push qword 1 ; protection mode PROT_READ + push qword 2 ; flags MAP_PRIVATE + push rax ; fd + push qword 0 ; offset + jmp sys_mmap_asm ; exit via sys_mmap + +;;; ======================================== +;;; Input stream handling. An input stream has a stream buffer that is +;;; gradually filled on needs basis. The stream buffer includes a +;;; header portion with: +;;; * size of buffer (excluding the 32 byte head) +;;; * source file descriptor +;;; * current fill +;;; * current read position + + WORD p_stream,'STREAM', + ;; ( fd size -- addr ) + ;; Allocates a stream buffer of the given size and initializes + ;; it to be filled from the given input file descriptor. + dq p_dup ; ( fd size size ) + dq p_malloc ; ( fd size addr ) + dq p_2dup ; ( fd size addr size addr ) + dq p_swap ; ( fd size addr addr size ) + dq p_erase ; ( fd size addr ) + ENDFORTH + pop rax ; ( fd size ) + pop rbx ; ( fd ) + sub rbx,32 + mov [rax],rbx + pop rbx + mov [rax+8],rbx + push rax + jmp exit + + WORD p_read_stream_char,'READ-STREAM-CHAR',fasm + ;; ( stream -- ch ) + pushr rsi + mov rax,qword [rsp] + mov rbx,[rax+16] ; fill +p_read_stream_char.READ: + mov rcx,[rax+24] ; current + cmp rbx,rcx + jg p_read_stream_char.CHAR + push qword [rax+8] ; fd + lea rbx,[rax+32] + push rbx ; buffer + push qword [rax] ; size + mov qword[rax+16],0 + mov qword[rax+24],0 + DOFORTH sys_read + pop rbx + mov rax,qword [rsp] + cmp rbx,0 + jle p_read_stream_char.EOF + mov qword[rax+16],rbx + jmp p_read_stream_char.READ +p_read_stream_char.EOF: + mov qword [rsp],-1 + popr rsi + next +p_read_stream_char.CHAR: + inc qword [rax+24] + add rcx,32 + mov qword [rsp],0 + mov bl,[rax+rcx] + mov byte [rsp],bl + popr rsi + next + + WORD p_line_buffer,'LINE-BUFFER',dovariable + ;; A buffer for holding a text line + rb 1024 + + WORD p_read_word,'READ-WORD',fasm + ;; ( stream -- addr length ) + ;; Read a text line from the stream into the line buffer + pushr rsi + pop rax + push qword p_line_buffer_DFA + push qword 0 + push rax +p_read_word_skipblanks: + FORTH + dq p_dup + dq p_read_stream_char + ENDFORTH + pop rbx + cmp bl,0 + jl p_read_word_nomore + cmp bl,' ' + jle p_read_word_skipblanks +p_read_word_readword: + FORTH + dq p_dup + dq p_read_stream_char + ENDFORTH + pop rbx + cmp bl,0 + jl p_read_word_nomore + cmp bl,' ' + jle p_read_word_nomore + ;; ( buffer length stream ) + mov rax,qword [rsp+16] + mov rcx,qword [rsp+8] + mov [rax+rcx],bl + inc qword [rsp+8] + jmp p_read_word_readword +p_read_word_nomore: + pop rax + popr rsi + next diff --git a/symbols.lsp b/symbols.lsp new file mode 100755 index 0000000..98f4c41 --- /dev/null +++ b/symbols.lsp @@ -0,0 +1,118 @@ +#!/usr/bin/newlisp +# +# Print an assembly listing for ELF targets associating binary address +# with source lines. + +(signal 2 exit) ; exit on Ctrl-C + +; Format a byte or list of bytes into a hex string +(define (hex L) + (if (list? L) (string "0x" (join (map (curry format "%02x") L))) + ; else + (hex (list L)))) + +; Helper function to "copy out" a NUL terminated string from the +; beginning of a memblock. (only an issue with utf8-enabled newlisp) +(define (asciiz X) (get-string (address X))) + +; Helper function to set and print a variable +(define (print-assign X Y) (set X (println X " = " Y))) + +; Helper "macro" to set variables and print their assignments +(define-macro (setf-print) + (map (fn (P) (print-assign (P 0) (eval (P 1)))) (explode (args) 2))) + +; Load the .fas file here; named last on the command line +(setf FAS (read-file (main-args -1))) + +(setf-print + SIGNATURE (hex (reverse (unpack (dup "b" 4) FAS))) + VERSION (unpack "bb" (4 FAS)) + HEADER-LENGTH ((unpack "u" (6 FAS)) 0) + INFILEP ((unpack "lu" (8 FAS)) 0) + OUTFILEP ((unpack "lu" (12 FAS)) 0) + STRINGS-TABLE-OFFSET ((unpack "lu" (16 FAS)) 0) + STRINGS-TABLE-LENGTH ((unpack "lu" (20 FAS)) 0) + SYMBOLS-TABLE-OFFSET ((unpack "lu" (24 FAS)) 0) + SYMBOLS-TABLE-LENGTH ((unpack "lu" (28 FAS)) 0) + PREPROCESSED-OFFSET ((unpack "lu" (32 FAS)) 0) + PREPROCESSED-LENGTH ((unpack "lu" (36 FAS)) 0) + ASSEMBLY-DUMP-OFFSET ((unpack "lu" (40 FAS)) 0) + ASSEMBLY-DUMP-LENGTH ((unpack "lu" (44 FAS)) 0) + SECTION-TABLE-OFFSET ((unpack "lu" (48 FAS)) 0) + SECTION-TABLE-LENGTH ((unpack "lu" (52 FAS)) 0) + SYMBOL-REFERENCES-DUMP-OFFSET ((unpack "lu" (56 FAS)) 0) + SYMBOL-REFERENCES-DUMP-LENGTH ((unpack "lu" (60 FAS)) 0) + ) + +(setf + STRINGS (STRINGS-TABLE-OFFSET STRINGS-TABLE-LENGTH FAS) + _ (println STRINGS) + PREP (PREPROCESSED-OFFSET PREPROCESSED-LENGTH FAS) + ) + +(setf-print + MAIN-FILE (asciiz (INFILEP STRINGS)) + ) + +; Hash tables for filename->content and macroid->firstline +(define FILES:FILES nil) ; for captured file content +(define MACROS:MACROS nil) ; for captured first-appearance-line of macros + +; Get/cache content of file +(define (get-file NAME) + (or (FILES NAME) (FILES NAME (read-file NAME)))) + +; Check if N is the first-appearence-line in macro ID +; (capture N for the very first appearance of ID) +(define (macro-start ID N) + (if (MACROS ID) (= (MACROS ID) N) (MACROS ID N))) + +; The file name for prep entry index i (with 0 = main file) +(define (source-file i) + (if (= i) MAIN-FILE (asciiz (i PREP)))) + +; Extract and format the file line with line number LN that is at at +; position i of file FILE. +(define (get-line i FILE LN) + (letn ((DATA (get-file FILE)) + (END (find "\n" DATA nil i)) + (R (i (- END i) DATA)) ) + (format "%s:%-5d %s" FILE LN R))) + +; Format a "macro" prep entry by prepending an informative line for +; the first-appearance-line. +(define (resolve-macro AT PL) + (if (macro-start (PL 2) (PL 1)) + (string (PREP-SOURCE-LINE "--------" (PL 2)) "\n" + (PREP-SOURCE-LINE AT (PL 3))) + ; else + (PREP-SOURCE-LINE AT (PL 3)))) + +; Format output for "address" AT and prep line PL (unpacked) +(define (prep-source AT PL) + (if (!= (& 0x80000000 (PL 1))) (resolve-macro AT PL) + ; else + (string AT " " (get-line (PL 2) (source-file (PL 0)) (PL 1))))) + +; Format output for "address" AT and prep line at P (index) +(define (PREP-SOURCE-LINE AT P) + (prep-source AT (unpack "lu lu lu lu" (P PREP)))) + +; Format output for assembly line L (memblock) +(define (ASSEMBLY-LINE L) + (let ((AL (unpack "lu lu lu lu lu b b b b" (or L "")))) + (PREP-SOURCE-LINE (hex (AL 2)) (AL 1)) + )) + +; divide memblock D into memblocks of size N +(define (frag N D) + (unpack (dup (string "s" N " ") (/ (length D) N)) D)) + +#### Main action(s) start here + +(map println + (map ASSEMBLY-LINE + (frag 28 (ASSEMBLY-DUMP-OFFSET ASSEMBLY-DUMP-LENGTH FAS)))) + +(exit 0) diff --git a/syscalls.fasm b/syscalls.fasm new file mode 100644 index 0000000..ede8849 --- /dev/null +++ b/syscalls.fasm @@ -0,0 +1,372 @@ +;;; https://chromium.googlesource.com/chromiumos/docs/+/master/constants/syscalls.md +;;; +;;; id rtn 0 1 2 3 4 5 +;;; x86_64: rax, rax, rdi, rsi, rdx, r10, r8, r9 + +;;; %rax System call %rdi %rsi %rdx %r10 %r8 %r9 + +;;; ============================== +;;; Helper macro for layout of syscall argument registers + +macro SYSCALLARG register,count,nargs { +if count < nargs + mov register, [rsp + ((nargs-count-1)*8)] +end if +} + +;;; Code layout for system call with up to 6 arguments +macro SYSCALL id,name,fname,nargs { + WORD name,fname,fasm + pushr rsi +name#_asm: + mov rax,qword id + SYSCALLARG r9,5,nargs + SYSCALLARG r8,4,nargs + SYSCALLARG r10,3,nargs + SYSCALLARG rdx,2,nargs + SYSCALLARG rsi,1,nargs + SYSCALLARG rdi,0,nargs +if nargs > 0 + add rsp,nargs*8 +end if + syscall + push rax + jmp exit +} + + SYSCALL 0,sys_read,'SYS_READ',3 + SYSCALL 1,sys_write,'SYS_WRITE',3 + SYSCALL 2,sys_open,'SYS_OPEN',3 + SYSCALL 3,sys_close,'SYS_CLOSE',1 + SYSCALL 4,sys_stat,'SYS_STAT',2 + SYSCALL 5,sys_fstat,'SYS_FSTAT',2 + SYSCALL 6,sys_lstat,'SYS_LSTAT',2 + SYSCALL 7,sys_poll,'SYS_POLL',3 + SYSCALL 8,sys_lseek,'SYS_LSEEK',3 + SYSCALL 9,sys_mmap,'SYS_MMAP',6 + SYSCALL 10,sys_mprotect,'SYS_MPROTECT',3 + SYSCALL 11,sys_munmap,'SYS_MUNMAP',2 + SYSCALL 12,sys_brk,'SYS_BRK',1 + SYSCALL 13,sys_rt_sigaction,'SYS_RT_SIGACTION',4 + SYSCALL 14,sys_rt_sigprocmask,'SYS_RT_SIGPROCMASK',4 + SYSCALL 15,sys_rt_sigreturn,'SYS_RT_SIGRETURN',1 + SYSCALL 16,sys_ioctl,'SYS_IOCTL',3 + SYSCALL 17,sys_pread64,'SYS_PREAD64',4 + SYSCALL 18,sys_pwrite64,'SYS_PWRITE64',4 + SYSCALL 19,sys_readv,'SYS_READV',3 + SYSCALL 20,sys_writev,'SYS_WRITEV',3 + SYSCALL 21,sys_access,'SYS_ACCESS',2 + SYSCALL 22,sys_pipe,'SYS_PIPE',1 + SYSCALL 23,sys_select,'SYS_SELECT',5 + SYSCALL 24,sys_sched_yield,'SYS_SCHED_YIELD',0 + SYSCALL 25,sys_mremap,'SYS_MREMAP',5 + SYSCALL 26,sys_msync,'SYS_MSYNC',3 + SYSCALL 27,sys_mincore,'SYS_MINCORE',3 + SYSCALL 28,sys_madvise,'SYS_MADVISE',3 + SYSCALL 29,sys_shmget,'SYS_SHMGET',3 + SYSCALL 30,sys_shmat,'SYS_SHMAT',3 + SYSCALL 31,sys_shmctl,'SYS_SHMCTL',3 + SYSCALL 32,sys_dup,'SYS_DUP',1 + SYSCALL 33,sys_dup2,'SYS_DUP2',2 + SYSCALL 34,sys_pause,'SYS_PAUSE',0 + SYSCALL 35,sys_nanosleep,'SYS_NANOSLEEP',2 + SYSCALL 36,sys_getitimer,'SYS_GETITIMER',2 + SYSCALL 37,sys_alarm,'SYS_ALARM',1 + SYSCALL 38,sys_setitimer,'SYS_SETITIMER',3 + SYSCALL 39,sys_getpid,'SYS_GETPID',0 + SYSCALL 40,sys_sendfile,'SYS_SENDFILE',4 + SYSCALL 41,sys_socket,'SYS_SOCKET',3 + SYSCALL 42,sys_connect,'SYS_CONNECT',3 + SYSCALL 43,sys_accept,'SYS_ACCEPT',3 + SYSCALL 44,sys_sendto,'SYS_SENDTO',6 + SYSCALL 45,sys_recvfrom,'SYS_RECVFROM',6 + SYSCALL 46,sys_sendmsg,'SYS_SENDMSG',3 + SYSCALL 47,sys_recvmsg,'SYS_RECVMSG',3 + SYSCALL 48,sys_shutdown,'SYS_SHUTDOWN',2 + SYSCALL 49,sys_bind,'SYS_BIND',3 + SYSCALL 50,sys_listen,'SYS_LISTEN',2 + SYSCALL 51,sys_getsockname,'SYS_GETSOCKNAME',3 + SYSCALL 52,sys_getpeername,'SYS_GETPEERNAME',3 + SYSCALL 53,sys_socketpair,'SYS_SOCKETPAIR',4 + SYSCALL 54,sys_setsockopt,'SYS_SETSOCKOPT',5 + SYSCALL 55,sys_getsockopt,'SYS_GETSOCKOPT',5 + SYSCALL 56,sys_clone,'SYS_CLONE',5 + SYSCALL 57,sys_fork,'SYS_FORK',0 + SYSCALL 58,sys_vfork,'SYS_VFORK',0 + SYSCALL 59,sys_execve,'SYS_EXECVE',3 + SYSCALL 60,sys_exit,'SYS_EXIT',1 + SYSCALL 61,sys_wait4,'SYS_WAIT4',4 + SYSCALL 62,sys_kill,'SYS_KILL',2 + SYSCALL 63,sys_uname,'SYS_UNAME',1 + SYSCALL 64,sys_semget,'SYS_SEMGET',3 + SYSCALL 65,sys_semop,'SYS_SEMOP',3 + SYSCALL 66,sys_semctl,'SYS_SEMCTL',4 + SYSCALL 67,sys_shmdt,'SYS_SHMDT',1 + SYSCALL 68,sys_msgget,'SYS_MSGGET',2 + SYSCALL 69,sys_msgsnd,'SYS_MSGSND',4 + SYSCALL 70,sys_msgrcv,'SYS_MSGRCV',5 + SYSCALL 71,sys_msgctl,'SYS_MSGCTL',3 + SYSCALL 72,sys_fcntl,'SYS_FCNTL',3 + SYSCALL 73,sys_flock,'SYS_FLOCK',2 + SYSCALL 74,sys_fsync,'SYS_FSYNC',1 + SYSCALL 75,sys_fdatasync,'SYS_FDATASYNC',1 + SYSCALL 76,sys_truncate,'SYS_TRUNCATE',2 + SYSCALL 77,sys_ftruncate,'SYS_FTRUNCATE',2 + SYSCALL 78,sys_getdents,'SYS_GETDENTS',3 + SYSCALL 79,sys_getcwd,'SYS_GETCWD',2 + SYSCALL 80,sys_chdir,'SYS_CHDIR',1 + SYSCALL 81,sys_fchdir,'SYS_FCHDIR',1 + SYSCALL 82,sys_rename,'SYS_RENAME',2 + SYSCALL 83,sys_mkdir,'SYS_MKDIR',2 + SYSCALL 84,sys_rmdir,'SYS_RMDIR',1 + SYSCALL 85,sys_creat,'SYS_CREAT',2 + SYSCALL 86,sys_link,'SYS_LINK',2 + SYSCALL 87,sys_unlink,'SYS_UNLINK',1 + SYSCALL 88,sys_symlink,'SYS_SYMLINK',2 + SYSCALL 89,sys_readlink,'SYS_READLINK',3 + SYSCALL 90,sys_chmod,'SYS_CHMOD',2 + SYSCALL 91,sys_fchmod,'SYS_FCHMOD',2 + SYSCALL 92,sys_chown,'SYS_CHOWN',3 + SYSCALL 93,sys_fchown,'SYS_FCHOWN',3 + SYSCALL 94,sys_lchown,'SYS_LCHOWN',3 + SYSCALL 95,sys_umask,'SYS_UMASK',1 + SYSCALL 96,sys_gettimeofday,'SYS_GETTIMEOFDAY',2 + SYSCALL 97,sys_getrlimit,'SYS_GETRLIMIT',2 + SYSCALL 98,sys_getrusage,'SYS_GETRUSAGE',2 + SYSCALL 99,sys_sysinfo,'SYS_SYSINFO',1 + SYSCALL 100,sys_times,'SYS_TIMES',1 + SYSCALL 101,sys_ptrace,'SYS_PTRACE',4 + SYSCALL 102,sys_getuid,'SYS_GETUID',0 + SYSCALL 103,sys_syslog,'SYS_SYSLOG',3 + SYSCALL 104,sys_getgid,'SYS_GETGID',0 + SYSCALL 105,sys_setuid,'SYS_SETUID',1 + SYSCALL 106,sys_setgid,'SYS_SETGID',1 + SYSCALL 107,sys_geteuid,'SYS_GETEUID',0 + SYSCALL 108,sys_getegid,'SYS_GETEGID',0 + SYSCALL 109,sys_setpgid,'SYS_SETPGID',2 + SYSCALL 110,sys_getppid,'SYS_GETPPID',0 + SYSCALL 111,sys_getpgrp,'SYS_GETPGRP',0 + SYSCALL 112,sys_setsid,'SYS_SETSID',0 + SYSCALL 113,sys_setreuid,'SYS_SETREUID',2 + SYSCALL 114,sys_setregid,'SYS_SETREGID',2 + SYSCALL 115,sys_getgroups,'SYS_GETGROUPS',2 + SYSCALL 116,sys_setgroups,'SYS_SETGROUPS',2 + SYSCALL 117,sys_setresuid,'SYS_SETRESUID',3 + SYSCALL 118,sys_getresuid,'SYS_GETRESUID',3 + SYSCALL 119,sys_setresgid,'SYS_SETRESGID',3 + SYSCALL 120,sys_getresgid,'SYS_GETRESGID',3 + SYSCALL 121,sys_getpgid,'SYS_GETPGID',1 + SYSCALL 122,sys_setfsuid,'SYS_SETFSUID',1 + SYSCALL 123,sys_setfsgid,'SYS_SETFSGID',1 + SYSCALL 124,sys_getsid,'SYS_GETSID',1 + SYSCALL 125,sys_capget,'SYS_CAPGET',2 + SYSCALL 126,sys_capset,'SYS_CAPSET',2 + SYSCALL 127,sys_rt_sigpending,'SYS_RT_SIGPENDING',2 + SYSCALL 128,sys_rt_sigtimedwait,'SYS_RT_SIGTIMEDWAIT',4 + SYSCALL 129,sys_rt_sigqueueinfo,'SYS_RT_SIGQUEUEINFO',3 + SYSCALL 130,sys_rt_sigsuspend,'SYS_RT_SIGSUSPEND',2 + SYSCALL 131,sys_sigaltstack,'SYS_SIGALTSTACK',2 + SYSCALL 132,sys_utime,'SYS_UTIME',2 + SYSCALL 133,sys_mknod,'SYS_MKNOD',3 + ;SYSCALL 134,sys_uselib,'SYS_USELIB', NOT IMPLEMENTED + SYSCALL 135,sys_personality,'SYS_PERSONALITY',1 + SYSCALL 136,sys_ustat,'SYS_USTAT',2 + SYSCALL 137,sys_statfs,'SYS_STATFS',2 + SYSCALL 138,sys_fstatfs,'SYS_FSTATFS',2 + SYSCALL 139,sys_sysfs,'SYS_SYSFS',3 + SYSCALL 140,sys_getpriority,'SYS_GETPRIORITY',2 + SYSCALL 141,sys_setpriority,'SYS_SETPRIORITY',3 + SYSCALL 142,sys_sched_setparam,'SYS_SCHED_SETPARAM',2 + SYSCALL 143,sys_sched_getparam,'SYS_SCHED_GETPARAM',2 + SYSCALL 144,sys_sched_setscheduler,'SYS_SCHED_SETSCHEDULER',3 + SYSCALL 145,sys_sched_getscheduler,'SYS_SCHED_GETSCHEDULER',1 + SYSCALL 146,sys_sched_get_priority_max,'SYS_SCHED_GET_PRIORITY_MAX',1 + SYSCALL 147,sys_sched_get_priority_min,'SYS_SCHED_GET_PRIORITY_MIN',1 + SYSCALL 148,sys_sched_rr_get_interval,'SYS_SCHED_RR_GET_INTERVAL',2 + SYSCALL 149,sys_mlock,'SYS_MLOCK',2 + SYSCALL 150,sys_munlock,'SYS_MUNLOCK',2 + SYSCALL 151,sys_mlockall,'SYS_MLOCKALL',1 + SYSCALL 152,sys_munlockall,'SYS_MUNLOCKALL',0 + SYSCALL 153,sys_vhangup,'SYS_VHANGUP',0 + SYSCALL 154,sys_modify_ldt,'SYS_MODIFY_LDT',3 + SYSCALL 155,sys_pivot_root,'SYS_PIVOT_ROOT',2 + SYSCALL 156,sys__sysctl,'SYS__SYSCTL',1 + SYSCALL 157,sys_prctl,'SYS_PRCTL',6 + SYSCALL 158,sys_arch_prctl,'SYS_ARCH_PRCTL',3 + SYSCALL 159,sys_adjtimex,'SYS_ADJTIMEX',1 + SYSCALL 160,sys_setrlimit,'SYS_SETRLIMIT',2 + SYSCALL 161,sys_chroot,'SYS_CHROOT',1 + SYSCALL 162,sys_sync,'SYS_SYNC',0 + SYSCALL 163,sys_acct,'SYS_ACCT',1 + SYSCALL 164,sys_settimeofday,'SYS_SETTIMEOFDAY',2 + SYSCALL 165,sys_mount,'SYS_MOUNT',5 + SYSCALL 166,sys_umount2,'SYS_UMOUNT2',2 + SYSCALL 167,sys_swapon,'SYS_SWAPON',2 + SYSCALL 168,sys_swapoff,'SYS_SWAPOFF',1 + SYSCALL 169,sys_reboot,'SYS_REBOOT',4 + SYSCALL 170,sys_sethostname,'SYS_SETHOSTNAME',2 + SYSCALL 171,sys_setdomainname,'SYS_SETDOMAINNAME',2 + SYSCALL 172,sys_iopl,'SYS_IOPL',2 + SYSCALL 173,sys_ioperm,'SYS_IOPERM',3 + ;SYSCALL 174,sys_create_module,'SYS_CREATE_MODULE' REMOVED IN Linux 2.6 + SYSCALL 175,sys_init_module,'SYS_INIT_MODULE',3 + SYSCALL 176,sys_delete_module,'SYS_DELETE_MODULE',2 + ;SYSCALL 177,sys_get_kernel_syms, REMOVED IN Linux 2.6 + ;SYSCALL 178,sys_query_module,'SYS_QUERY_MODULE', REMOVED IN Linux 2.6 + SYSCALL 179,sys_quotactl,'SYS_QUOTACTL',4 + ;SYSCALL 180,sys_nfsservctl,'SYS_NFSSERVCTL', NOT IMPLEMENTED + ;SYSCALL 181,sys_getpmsg,'SYS_GETPMSG', NOT IMPLEMENTED + ;SYSCALL 182,sys_putpmsg,'SYS_PUTPMSG', NOT IMPLEMENTED + ;SYSCALL 183,sys_afs_syscall,'SYS_AFS_SYSCALL', NOT IMPLEMENTED + ;SYSCALL 184,sys_tuxcall,'SYS_TUXCALL', NOT IMPLEMENTED + ;SYSCALL 185,sys_security,'SYS_SECURITY', NOT IMPLEMENTED + SYSCALL 186,sys_gettid,'SYS_GETTID',0 + SYSCALL 187,sys_readahead,'SYS_READAHEAD',3 + SYSCALL 188,sys_setxattr,'SYS_SETXATTR',5 + SYSCALL 189,sys_lsetxattr,'SYS_LSETXATTR',5 + SYSCALL 190,sys_fsetxattr,'SYS_FSETXATTR',5 + SYSCALL 191,sys_getxattr,'SYS_GETXATTR',4 + SYSCALL 192,sys_lgetxattr,'SYS_LGETXATTR',4 + SYSCALL 193,sys_fgetxattr,'SYS_FGETXATTR',4 + SYSCALL 194,sys_listxattr,'SYS_LISTXATTR',3 + SYSCALL 195,sys_llistxattr,'SYS_LLISTXATTR',4 + SYSCALL 196,sys_flistxattr,'SYS_FLISTXATTR',3 + SYSCALL 197,sys_removexattr,'SYS_REMOVEXATTR',2 + SYSCALL 198,sys_lremovexattr,'SYS_LREMOVEXATTR',2 + SYSCALL 199,sys_fremovexattr,'SYS_FREMOVEXATTR',2 + SYSCALL 200,sys_tkill,'SYS_TKILL',2 + SYSCALL 201,sys_time,'SYS_TIME',1 + SYSCALL 202,sys_futex,'SYS_FUTEX',6 + SYSCALL 203,sys_sched_setaffinity,'SYS_SCHED_SETAFFINITY',3 + SYSCALL 204,sys_sched_getaffinity,'SYS_SCHED_GETAFFINITY',3 + ;SYSCALL 205,sys_set_thread_area, NOT IMPLEMENTED. Use arch_prctl + SYSCALL 206,sys_io_setup,'SYS_IO_SETUP',2 + SYSCALL 207,sys_io_destroy,'SYS_IO_DESTROY',2 + SYSCALL 208,sys_io_getevents,'SYS_IO_GETEVENTS',4 + SYSCALL 209,sys_io_submit,'SYS_IO_SUBMIT',3 + SYSCALL 210,sys_io_cancel,'SYS_IO_CANCEL',3 + ;SYSCALL 211,sys_get_thread_area, NOT IMPLEMENTED. Use arch_prctl + SYSCALL 212,sys_lookup_dcookie,'SYS_LOOKUP_DCOOKIE',3 + SYSCALL 213,sys_epoll_create,'SYS_EPOLL_CREATE',1 + ;SYSCALL 214,sys_epoll_ctl_old,'SYS_EPOLL_CTL_OLD', NOT IMPLEMENTED + ;SYSCALL 215,sys_epoll_wait_old,'SYS_EPOLL_WAIT_OLD', NOT IMPLEMENTED + SYSCALL 216,sys_remap_file_pages,'SYS_REMAP_FILE_PAGES',5 + SYSCALL 217,sys_getdents64,'SYS_GETDENTS64',3 + SYSCALL 218,sys_set_tid_address,'SYS_SET_TID_ADDRESS',1 + SYSCALL 219,sys_restart_syscall,'SYS_RESTART_SYSCALL',0 + SYSCALL 220,sys_semtimedop,'SYS_SEMTIMEDOP',4 + SYSCALL 221,sys_fadvise64,'SYS_FADVISE64',4 + SYSCALL 222,sys_timer_create,'SYS_TIMER_CREATE',3 + SYSCALL 223,sys_timer_settime,'SYS_TIMER_SETTIME',4 + SYSCALL 224,sys_timer_gettime,'SYS_TIMER_GETTIME',2 + SYSCALL 225,sys_timer_getoverrun,'SYS_TIMER_GETOVERRUN',1 + SYSCALL 226,sys_timer_delete,'SYS_TIMER_DELETE',1 + SYSCALL 227,sys_clock_settime,'SYS_CLOCK_SETTIME',2 + SYSCALL 228,sys_clock_gettime,'SYS_CLOCK_GETTIME',2 + SYSCALL 229,sys_clock_getres,'SYS_CLOCK_GETRES',2 + SYSCALL 230,sys_clock_nanosleep,'SYS_CLOCK_NANOSLEEP',4 + SYSCALL 231,sys_exit_group,'SYS_EXIT_GROUP',1 + SYSCALL 232,sys_epoll_wait,'SYS_EPOLL_WAIT',4 + SYSCALL 233,sys_epoll_ctl,'SYS_EPOLL_CTL',4 + SYSCALL 234,sys_tgkill,'SYS_TGKILL',3 + SYSCALL 235,sys_utimes,'SYS_UTIMES',2 + ;SYSCALL 236,sys_vserver,'SYS_VSERVER', NOT IMPLEMENTED + SYSCALL 237,sys_mbind,'SYS_MBIND',6 + SYSCALL 238,sys_set_mempolicy,'SYS_SET_MEMPOLICY',3 + SYSCALL 239,sys_get_mempolicy,'SYS_GET_MEMPOLICY',5 + SYSCALL 240,sys_mq_open,'SYS_MQ_OPEN',4 + SYSCALL 241,sys_mq_unlink,'SYS_MQ_UNLINK',1 + SYSCALL 242,sys_mq_timedsend,'SYS_MQ_TIMEDSEND',5 + SYSCALL 243,sys_mq_timedreceive,'SYS_MQ_TIMEDRECEIVE',5 + SYSCALL 244,sys_mq_notify,'SYS_MQ_NOTIFY',2 + SYSCALL 245,sys_mq_getsetattr,'SYS_MQ_GETSETATTR',3 + SYSCALL 246,sys_kexec_load,'SYS_KEXEC_LOAD',4 + SYSCALL 247,sys_waitid,'SYS_WAITID',5 + SYSCALL 248,sys_add_key,'SYS_ADD_KEY',4 + SYSCALL 249,sys_request_key,'SYS_REQUEST_KEY',4 + SYSCALL 250,sys_keyctl,'SYS_KEYCTL',5 + SYSCALL 251,sys_ioprio_set,'SYS_IOPRIO_SET',3 + SYSCALL 252,sys_ioprio_get,'SYS_IOPRIO_GET',2 + SYSCALL 253,sys_inotify_init,'SYS_INOTIFY_INIT',0 + SYSCALL 254,sys_inotify_add_watch,'SYS_INOTIFY_ADD_WATCH',3 + SYSCALL 255,sys_inotify_rm_watch,'SYS_INOTIFY_RM_WATCH',2 + SYSCALL 256,sys_migrate_pages,'SYS_MIGRATE_PAGES',4 + SYSCALL 257,sys_openat,'SYS_OPENAT',4 + SYSCALL 258,sys_mkdirat,'SYS_MKDIRAT',3 + SYSCALL 259,sys_mknodat,'SYS_MKNODAT',4 + SYSCALL 260,sys_fchownat,'SYS_FCHOWNAT',5 + SYSCALL 261,sys_futimesat,'SYS_FUTIMESAT',3 + SYSCALL 262,sys_newfstatat,'SYS_NEWFSTATAT',4 + SYSCALL 263,sys_unlinkat,'SYS_UNLINKAT',3 + SYSCALL 264,sys_renameat,'SYS_RENAMEAT',4 + SYSCALL 265,sys_linkat,'SYS_LINKAT',5 + SYSCALL 266,sys_symlinkat,'SYS_SYMLINKAT',3 + SYSCALL 267,sys_readlinkat,'SYS_READLINKAT',4 + SYSCALL 268,sys_fchmodat,'SYS_FCHMODAT',3 + SYSCALL 269,sys_faccessat,'SYS_FACCESSAT',3 + SYSCALL 270,sys_pselect6,'SYS_PSELECT6',6 + SYSCALL 271,sys_ppoll,'SYS_PPOLL',5 + SYSCALL 272,sys_unshare,'SYS_UNSHARE',1 + SYSCALL 273,sys_set_robust_list,'SYS_SET_ROBUST_LIST',2 + SYSCALL 274,sys_get_robust_list,'SYS_GET_ROBUST_LIST',3 + SYSCALL 275,sys_splice,'SYS_SPLICE',6 + SYSCALL 276,sys_tee,'SYS_TEE',4 + SYSCALL 277,sys_sync_file_range,'SYS_SYNC_FILE_RANGE',4 + SYSCALL 278,sys_vmsplice,'SYS_VMSPLICE',4 + SYSCALL 279,sys_move_pages,'SYS_MOVE_PAGES',6 + SYSCALL 280,sys_utimensat,'SYS_UTIMENSAT',4 + SYSCALL 281,sys_epoll_pwait,'SYS_EPOLL_PWAIT',6 + SYSCALL 282,sys_signalfd,'SYS_SIGNALFD',3 + SYSCALL 283,sys_timerfd_create,'SYS_TIMERFD_CREATE',2 + SYSCALL 284,sys_eventfd,'SYS_EVENTFD',1 + SYSCALL 285,sys_fallocate,'SYS_FALLOCATE',4 + SYSCALL 286,sys_timerfd_settime,'SYS_TIMERFD_SETTIME',4 + SYSCALL 287,sys_timerfd_gettime,'SYS_TIMERFD_GETTIME',2 + SYSCALL 288,sys_accept4,'SYS_ACCEPT4',4 + SYSCALL 289,sys_signalfd4,'SYS_SIGNALFD4',4 + SYSCALL 290,sys_eventfd2,'SYS_EVENTFD2',2 + SYSCALL 291,sys_epoll_create1,'SYS_EPOLL_CREATE1',1 + SYSCALL 292,sys_dup3,'SYS_DUP3',3 + SYSCALL 293,sys_pipe2,'SYS_PIPE2',2 + SYSCALL 294,sys_inotify_init1,'SYS_INOTIFY_INIT1',1 + SYSCALL 295,sys_preadv,'SYS_PREADV',5 + SYSCALL 296,sys_pwritev,'SYS_PWRITEV',5 + SYSCALL 297,sys_rt_tgsigqueueinfo,'SYS_RT_TGSIGQUEUEINFO',4 + SYSCALL 298,sys_perf_event_open,'SYS_PERF_EVENT_OPEN',5 + SYSCALL 299,sys_recvmmsg,'SYS_RECVMMSG',5 + SYSCALL 300,sys_fanotify_init,'SYS_FANOTIFY_INIT',2 + SYSCALL 301,sys_fanotify_mark,'SYS_FANOTIFY_MARK',5 + SYSCALL 302,sys_prlimit64,'SYS_PRLIMIT64',4 + SYSCALL 303,sys_name_to_handle_at,'SYS_NAME_TO_HANDLE_AT',5 + SYSCALL 304,sys_open_by_handle_at,'SYS_OPEN_BY_HANDLE_AT',5 + SYSCALL 305,sys_clock_adjtime,'SYS_CLOCK_ADJTIME',2 + SYSCALL 306,sys_syncfs,'SYS_SYNCFS',1 + SYSCALL 307,sys_sendmmsg,'SYS_SENDMMSG',4 + SYSCALL 308,sys_setns,'SYS_SETNS',2 + SYSCALL 309,sys_getcpu,'SYS_GETCPU',3 + SYSCALL 310,sys_process_vm_readv,'SYS_PROCESS_VM_READV',6 + SYSCALL 311,sys_process_vm_writev,'SYS_PROCESS_VM_WRITEV',6 + SYSCALL 312,sys_kcmp,'SYS_KCMP',5 + SYSCALL 313,sys_finit_module,'SYS_FINIT_MODULE',3 + SYSCALL 314,sys_sched_setattr,'SYS_SCHED_SETATTR',3 + SYSCALL 315,sys_sched_getattr,'SYS_SCHED_GETATTR',4 + SYSCALL 316,sys_renameat2,'SYS_RENAMEAT2',5 + SYSCALL 317,sys_seccomp,'SYS_SECCOMP',3 + SYSCALL 318,sys_getrandom,'SYS_GETRANDOM',3 + SYSCALL 319,sys_memfd_create,'SYS_MEMFD_CREATE',2 + SYSCALL 320,sys_kexec_file_load,'SYS_KEXEC_FILE_LOAD',5 + SYSCALL 321,sys_bpf,'SYS_BPF',3 + SYSCALL 322,stub_execveat,'STUB_EXECVEAT',5 + SYSCALL 323,userfaultfd,'USERFAULTFD',1 + SYSCALL 324,membarrier,'MEMBARRIER',2 + SYSCALL 325,mlock2,'MLOCK2',3 + SYSCALL 326,copy_file_range,'COPY_FILE_RANGE',6 + SYSCALL 327,preadv2,'PREADV2',6 + SYSCALL 328,pwritev2,'PWRITEV2',6 + SYSCALL 329,pkey_mprotect,'PKEY_MPROTECT',0 + SYSCALL 330,pkey_alloc,'PKEY_ALLOC',0 + SYSCALL 331,pkey_free,'PKEY_FREE',0 + SYSCALL 332,statx,'STATX',0 + SYSCALL 333,io_pgetevents,'IO_PGETEVENTS',0 + SYSCALL 334,rseq,'RSEQ',0 + SYSCALL 335,pkey_mprotect1,'PKEY_MPROTECT1',0 diff --git a/wordlists.fasm b/wordlists.fasm new file mode 100644 index 0000000..9790a28 --- /dev/null +++ b/wordlists.fasm @@ -0,0 +1,59 @@ +;;; This file contains words dealing with word lists (vocabularies) +;;; + WORD p_wordlists,'WORDLIST',dovariable + ;; VARIABLE WORDLIST is the currently active wordlist. + dq last_word + + WORD p_strncmp,'STRNCMP',fasm + ;; ( chars1 chars2 n -- flag ) + ;; Compare bytes until one is NUL, return <0, =0 or >0 to + ;; indicate that chars1 is lesser, they are equal, or chars2 + ;; is lesser in ascii ordering respectively. + pop rdx + pop rbx + pop rax + xor rcx,rcx + ;; rax = chars1, rbx = chars2, cl = byte acc, rdx = length + inc rdx +p_strncmp_loop: + dec rdx + je p_strncmp_end + mov cl,[rax] + inc rax + sub cl,[rbx] + inc rbx + je p_strncmp_loop +p_strncmp_end: + push rcx + next + + WORD p_find,'FIND' + ;; ( chars length -- [ chars 0 | cfa 1 ) + ;; Search the current wordlists for the given pname + mov rcx,[p_wordlists_DFA] +p_find_loop: + cmp rcx,0 + je p_find_done + mov rbx,[rsp] + mov rax,[rsp+8] + cmp bl,byte [rcx+10] + jne p_find_nextword + push rcx + ;; check word + push rax + push rcx+11 + push rbx + DOFORTH p_strncmp + pop rax ; return value + pop rcx + cmp rax,0 + je p_find_done +p_find_nextword: + mov rcx,[rcx] + jmp p_find_loop +p_find_found: + mov qword [rsp+8],rcx ; replace chars with tfa + mov rcx,1 +p_find_done: + push rcx + next -- 2.39.2