1 ;; Native x86 GNU/Linux Forth System, Direct Threaded Code
3 ;; Copyright (C) 2020 Ketmar Dark // Invisible Vector
5 ;; This program is free software: you can redistribute it and/or modify
6 ;; it under the terms of the GNU General Public License as published by
7 ;; the Free Software Foundation, version 3 of the License ONLY.
9 ;; This program is distributed in the hope that it will be useful,
10 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ;; GNU General Public License for more details.
14 ;; You should have received a copy of the GNU General Public License
15 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
18 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19 ;; ensure that the string at EDI with length in ECX is asciiz
20 ;; returns new EDI if necessary
21 ;; doesn't modify other registers (except flags)
22 ;; but sets carry if ECX is invalid
23 ;; rejects empty strings
24 ;; may allocate temp pool, so take care of releasing it
26 urword_code
"(DONT-CALL-OSFACE-CSTR)",par_dontcall_osface_cstr
27 urword_uses par_no_call_temp_pool_subs
29 ensure_asciiz_edi_ecx:
39 or ecx,ecx ; reset carry flag
47 inc eax ; for trailing zero
49 push edi ; save new address
50 rep movsb ; copy string
51 xor al,al ; store trailing zero
53 pop edi ; restore new address (we'll return it)
54 pop esi ; restore ESI (because we promised to not change it)
55 pop ecx ; restore length (just in case)
56 pop eax ; restore EAX (because we promised to not change it)
57 or ecx,ecx ; reset carry flag
65 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
66 urword_code
"(DLCLOSE)",par_dlclose
69 jr z
,fword_par_dlclose_fucked
76 add esp,4 ; remove args
77 fword_par_dlclose_fucked:
82 urword_code
"(DLOPEN)",par_dlopen
83 ;; ( addr count -- handle-or-0 )
84 urword_uses par_dontcall_osface_cstr
89 call ensure_asciiz_edi_ecx
90 jr c
,fword_par_dlopen_fucked
95 ld
eax,1+256+8 ; RTLD_LAZY+RTLD_GLOBAL+RTLD_DEEPBIND
99 add esp,4*2 ; remove arguments
108 fword_par_dlopen_fucked:
116 urword_code
"(DLSYM)",par_dlsym
117 ;; ( addr count handle -- address-or-0 )
118 urword_uses par_dontcall_osface_cstr
119 ld FREEREG
,TOS
; save handle
125 call ensure_asciiz_edi_ecx
126 jr c
,fword_par_dlsym_fucked
134 add esp,4*2 ; remove arguments
143 fword_par_dlsym_fucked:
151 urword_const
"RTLD_DEFAULT",rtld_default
,0
152 urword_const
"RTLD_NEXT",rtld_next
,-1
155 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
156 urword_code
"(FCLOSE)",par_fclose
172 urword_code
"(FOPEN)",par_fopen
173 ;; ( addr count flags mode -- fd-or-minusone )
174 urword_uses par_dontcall_osface_cstr
187 call ensure_asciiz_edi_ecx
214 urword_code
"(FREAD)",par_fread
215 ;; ( addr count fd -- count )
233 urword_code
"(FWRITE)",par_fwrite
234 ;; ( addr count fd -- count )
252 urword_code
"(LSEEK)",par_lseek
253 ;; ( ofs whence fd -- res )
274 urword_const
"O-RDONLY",o_rdonly
,0
275 urword_const
"O-WRONLY",o_wronly
,1
276 urword_const
"O-RDWR",o_rdwr
,2
278 urword_const
"O-CREAT", o_creat
, 0x000040 ; 0100
279 urword_const
"O-EXCL", o_excl
, 0x000080 ; 0200
280 urword_const
"O-NOCTTY", o_noctty
, 0x000100 ; 0400
281 urword_const
"O-TRUNC", o_trunc
, 0x000200 ; 01000
282 urword_const
"O-APPEND", o_append
, 0x000400 ; 02000
283 urword_const
"O-NONBLOCK", o_nonblock
, 0x000800 ; 04000
284 urword_const
"O-DSYNC", o_dsync
, 0x001000 ; 010000
285 urword_const
"O-SYNC", o_sync
, 0x101000 ; 04010000
286 urword_const
"O-RSYNC", o_rsync
, 0x101000 ; 04010000
287 urword_const
"O-DIRECTORY",o_directory
,0x010000 ; 0200000
288 urword_const
"O-NOFOLLOW", o_nofollow
, 0x020000 ; 0400000
289 urword_const
"O-CLOEXEC", o_cloexec
, 0x080000 ; 02000000
291 urword_const
"O-ASYNC", o_async
, 0x002000 ; 020000
292 urword_const
"O-DIRECT", o_direct
, 0x004000 ; 040000
293 urword_const
"O-LARGEFILE",o_largefile
,0x008000 ; 0100000
294 urword_const
"O-NOATIME", o_noatime
, 0x040000 ; 01000000
295 urword_const
"O-PATH", o_path
, 0x200000 ; 010000000
296 urword_const
"O-TMPFILE", o_tmpfile
, 0x410000 ; 020200000
297 urword_const
"O-NDELAY", o_ndelay
, 0x000800 ; 04000
299 urword_const
"O-CREATE-WRONLY-FLAGS",o_create_wronly_flags
,(1 or 0x000040 or 0x000200)
300 urword_const
"O-CREATE-MODE-NORMAL",o_create_mode_normal
,(0x100 or 0x080 or 0x020 or 0x004)
302 urword_const
"(SEEK-SET)",seek_set
,0
303 urword_const
"(SEEK-CUR)",seek_cur
,1
304 urword_const
"(SEEK-END)",seek_end
,2
306 urword_const
"S-ISUID",s_isuid
,0x800 ; 04000
307 urword_const
"S-ISGID",s_isgid
,0x400 ; 02000
308 urword_const
"S-ISVTX",s_isvtx
,0x200 ; 01000
309 urword_const
"S-IRUSR",s_irusr
,0x100 ; 0400
310 urword_const
"S-IWUSR",s_iwusr
,0x080 ; 0200
311 urword_const
"S-IXUSR",s_ixusr
,0x040 ; 0100
312 urword_const
"S-IRWXU",s_irwxu
,0x1c0 ; 0700
313 urword_const
"S-IRGRP",s_irgrp
,0x020 ; 0040
314 urword_const
"S-IWGRP",s_iwgrp
,0x010 ; 0020
315 urword_const
"S-IXGRP",s_ixgrp
,0x008 ; 0010
316 urword_const
"S-IRWXG",s_irwxg
,0x038 ; 0070
317 urword_const
"S-IROTH",s_iroth
,0x004 ; 0004
318 urword_const
"S-IWOTH",s_iwoth
,0x002 ; 0002
319 urword_const
"S-IXOTH",s_ixoth
,0x001 ; 0001
320 urword_const
"S-IRWXO",s_irwxo
,0x007 ; 0007
323 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
352 urword_code
"(FILE?)",par_is_file
353 ;; ( addr count -- flag )
354 urword_uses par_dontcall_osface_cstr
362 call ensure_asciiz_edi_ecx
368 sub esp,statshit.statsize
375 movzx TOS
,word [esp+statshit.st_mode
]
377 add esp,statshit.statsize
384 and TOS
,0x8000 ; 0100000, S_IFREG
400 urword_code
"(DIR?)",par_is_dir
401 ;; ( addr count -- flag )
402 urword_uses par_dontcall_osface_cstr
410 call ensure_asciiz_edi_ecx
416 sub esp,statshit.statsize
423 movzx TOS
,word [esp+statshit.st_mode
]
425 add esp,statshit.statsize
432 and TOS
,0x4000 ; 0040000, S_IFDIR
448 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
449 ;; get seconds since epoch
450 urword_code
"SYS-TIME",sys_time
456 xor ebx,ebx ; result only in eax
464 urword_const
"CLOCK_REALTIME",clock_realtime
,0
465 urword_const
"CLOCK_MONOTONIC",clock_mono
,1
466 urword_const
"CLOCK_PROCESS_CPUTIME_ID",clock_process_cpu
,2
467 urword_const
"CLOCK_THREAD_CPUTIME_ID",clock_thread_cpu
,3
468 urword_const
"CLOCK_MONOTONIC_RAW",clock_mono_raw
,4
469 urword_const
"CLOCK_REALTIME_COARSE",clock_realtime_coarse
,5
470 urword_const
"CLOCK_MONOTONIC_COARSE",clock_mono_coarse
,6
471 urword_const
"CLOCK_BOOTTIME",clock_boot
,7
472 urword_const
"CLOCK_REALTIME_ALARM",clock_realtime_alarm
,8
473 urword_const
"CLOCK_BOOTTIME_ALARM",clock_boot_alarm
,9
475 urword_const
"NANOSECONS-PER-SECOND",nano_per_second
,1000000000
476 urword_const
"NANOSECONS-PER-MSEC",nano_per_msec
,1000000
478 ;; get seconds and nanoseconds (since some random starting point)
479 urword_code
"SYS-CLOCK-GETTIME",sys_clock_gettime
480 ;; ( clockid -- seconds nanoseconds )
483 sub esp,4+4 ; timespec
484 ld
eax,265 ; sys_clock_gettime
490 ld
eax,[esp] ; seconds
491 ld TOS
,[esp+4] ; nanoseconds
507 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
508 urword_const
"(SYS-GETTICKCOUNT-START-SECS)",sys_gettickccount_start_secs
,0
511 urword_forth
"(SYS-GETTICKCOUNT-INIT)",sys_gettickcount_init
514 UF clock_mono sys_clock_gettime drop
519 urlit fconst_sys_gettickccount_start_secs_data
524 urword_forth
"SYS-GETTICKCOUNT",sys_gettickcount
525 UF clock_mono sys_clock_gettime
526 UF nano_per_msec udiv
527 UF swap sys_gettickccount_start_secs
- 1000 umul
532 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
533 urword_code
"(CINVOKE)",par_cinvoke
534 ;; ( ... argcount addr -- res )
550 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
551 ;; urword_const "MAP-FILE" ,0x00000000
552 ;; urword_const "MAP-SHARED" ,0x00000001
553 ;; urword_const "MAP-PRIVATE" ,0x00000002
554 ;; urword_const "MAP-SHARED_VALIDATE" ,0x00000003
555 ;; urword_const "MAP-TYPE" ,0x0000000f
556 ;; urword_const "MAP-FIXED" ,0x00000010
557 ;; urword_const "MAP-ANON" ,0x00000020
558 ;; urword_const "MAP-ANONYMOUS" ,0x00000020
559 ;; urword_const "MAP-NORESERVE" ,0x00004000
560 ;; urword_const "MAP-GROWSDOWN" ,0x00000100
561 ;; urword_const "MAP-DENYWRITE" ,0x00000800
562 ;; urword_const "MAP-EXECUTABLE" ,0x00001000
563 ;; urword_const "MAP-LOCKED" ,0x00002000
564 ;; urword_const "MAP-POPULATE" ,0x00008000
565 ;; urword_const "MAP-NONBLOCK" ,0x00010000
566 ;; urword_const "MAP-STACK" ,0x00020000
567 ;; urword_const "MAP-HUGETLB" ,0x00040000
568 ;; urword_const "MAP-SYNC" ,0x00080000
569 ;; urword_const "MAP-FIXED_NOREPLACE" ,0x00100000
571 ;; urword_const "PROT-NONE" ,0
572 ;; urword_const "PROT-READ" ,1
573 ;; urword_const "PROT-WRITE" ,2
574 ;; urword_const "PROT-EXEC" ,4
575 urword_const
"PROT-R/W",mmap_const_prot_rw
,3
577 ;; urword_const "PROT-GROWSDOWN" ,0x01000000
578 ;; urword_const "PROT-GROWSUP" ,0x02000000
580 ;; WARNING! this can return negative for high addresses
581 ;; therefore, check for error like this:
582 ;; err -4095 0 within, or use "MMAP-ERROR?"
583 ;; it is ok to use "0" as modeflags, they will be set to private
584 urword_code
"MMAP",mmap
;;( size protflags -- addr true // error false )
585 ;; fix flags (we always doing anon private alloc)
586 xor ebx,ebx ;; address
587 ld
edx,TOS
;; protflags
591 ld
esi,0x0000_0022 ;; we always doing anon private alloc
592 xor ebp,ebp ;; offset, it is ignored, but why not
593 xor edi,edi ;; fd (-1)
606 urword_code
"MUNMAP",munmap
;;( addr size -- res )