freestanding: sys_getuid, sys_waitid; minimal fork check; remove bare.S
							parent
							
								
									39655a7d9b
								
							
						
					
					
						commit
						a9aaa13a09
					
				| 
						 | 
					@ -7,17 +7,34 @@ const (
 | 
				
			||||||
	sample_text_file1 = ""
 | 
						sample_text_file1 = ""
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn fork_test (test_fn fn(), name string) {
 | 
					fn check_fork_minimal () {
 | 
				
			||||||
	//print ("checking")
 | 
					 | 
				
			||||||
	// a := "$name"
 | 
					 | 
				
			||||||
	println (name)
 | 
					 | 
				
			||||||
	child := sys_fork()
 | 
						child := sys_fork()
 | 
				
			||||||
 | 
						ec := 100
 | 
				
			||||||
	if child == 0 {
 | 
						if child == 0 {
 | 
				
			||||||
		test_fn()
 | 
							println("child")
 | 
				
			||||||
		sys_exit(0)
 | 
							sys_exit(ec)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
//	pid := sys_wait(0)
 | 
						siginfo := [
 | 
				
			||||||
//	assert
 | 
							int(0), 0, 0, 0, 0, 0, 0, 0,
 | 
				
			||||||
 | 
							0, 0, 0, 0, 0, 0, 0, 0,
 | 
				
			||||||
 | 
							0, 0, 0, 0, 0, 0, 0, 0,
 | 
				
			||||||
 | 
							0, 0, 0, 0, 0, 0, 0, 0,
 | 
				
			||||||
 | 
							0, 0, 0, 0, 0, 0, 0, 0,
 | 
				
			||||||
 | 
							0, 0, 0, 0, 0, 0, 0, 0,
 | 
				
			||||||
 | 
							0, 0, 0, 0, 0, 0, 0, 0,
 | 
				
			||||||
 | 
							0, 0, 0, 0, 0, 0, 0, 0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						e := sys_waitid(.p_pid, child, intptr(siginfo.data) , .wexited, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert e == .enoerror
 | 
				
			||||||
 | 
						//println(i64_tos(buffer,80,siginfo[sig_index.si_code],16))
 | 
				
			||||||
 | 
						assert siginfo[sig_index.si_code] == int(wi_si_code.cld_exited)
 | 
				
			||||||
 | 
						assert siginfo[sig_index.si_pid] == child
 | 
				
			||||||
 | 
						assert siginfo[sig_index.si_status] == ec
 | 
				
			||||||
 | 
						assert siginfo[sig_index.si_signo] == int(signo.sigchld)
 | 
				
			||||||
 | 
						assert siginfo[sig_index.si_uid] == sys_getuid()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						println("fork minimal check passed")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn check_read_write_pipe() {
 | 
					fn check_read_write_pipe() {
 | 
				
			||||||
| 
						 | 
					@ -316,5 +333,6 @@ fn main() {
 | 
				
			||||||
	check_int64_array_ro()
 | 
						check_int64_array_ro()
 | 
				
			||||||
	check_voidptr_array_ro()
 | 
						check_voidptr_array_ro()
 | 
				
			||||||
	check_voidptr_array_rw()
 | 
						check_voidptr_array_rw()
 | 
				
			||||||
 | 
						check_fork_minimal()
 | 
				
			||||||
	sys_exit(0)
 | 
						sys_exit(0)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,6 +64,50 @@ pub enum wi_si_code {
 | 
				
			||||||
		CLD_CONTINUED (child continued by SIGCONT).
 | 
							CLD_CONTINUED (child continued by SIGCONT).
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub enum sig_index {
 | 
				
			||||||
 | 
						si_signo = 0x00
 | 
				
			||||||
 | 
						si_code = 0x02
 | 
				
			||||||
 | 
						si_pid = 0x04
 | 
				
			||||||
 | 
						si_uid = 0x05
 | 
				
			||||||
 | 
						si_status = 0x06
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub enum signo {
 | 
				
			||||||
 | 
						sigint = 2	// Interactive attention signal.
 | 
				
			||||||
 | 
						sigill = 4	// Illegal instruction.
 | 
				
			||||||
 | 
						sigabrt = 6	// Abnormal termination.
 | 
				
			||||||
 | 
						sigfpe = 8	// Erroneous arithmetic operation.
 | 
				
			||||||
 | 
						sigsegv = 11	// Invalid access to storage.
 | 
				
			||||||
 | 
						sigterm = 15	// Termination request.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sighup =  1	// Hangup.
 | 
				
			||||||
 | 
						sigquit = 3	// Quit.
 | 
				
			||||||
 | 
						sigtrap = 5	// Trace/breakpoint trap.
 | 
				
			||||||
 | 
						sigkill = 9	// Killed.
 | 
				
			||||||
 | 
						sigpipe = 13	// Broken pipe.
 | 
				
			||||||
 | 
						sigalrm = 14	// Alarm clock.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sigttin = 21	// Background read from control terminal.
 | 
				
			||||||
 | 
						sigttou = 22	// Background write to control terminal.
 | 
				
			||||||
 | 
						sigpoll = 23	// Pollable event occurred (System V).
 | 
				
			||||||
 | 
						sigxcpu = 24	// CPU time limit exceeded.
 | 
				
			||||||
 | 
						sigxfsz = 25	// File size limit exceeded.
 | 
				
			||||||
 | 
						sigvtalrm = 26	// Virtual timer expired.
 | 
				
			||||||
 | 
						sigprof = 27	// Profiling timer expired.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sigbus = 7
 | 
				
			||||||
 | 
						sigusr1 = 10
 | 
				
			||||||
 | 
						sigusr2 = 12
 | 
				
			||||||
 | 
						sigchld = 17
 | 
				
			||||||
 | 
						sigcont = 18
 | 
				
			||||||
 | 
						sigstop = 19
 | 
				
			||||||
 | 
						sigtstp = 20
 | 
				
			||||||
 | 
						sigurg = 23
 | 
				
			||||||
 | 
						sigpoll = 29
 | 
				
			||||||
 | 
						sigsys = 31
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub enum fcntl {
 | 
					pub enum fcntl {
 | 
				
			||||||
	fd_cloexec = 0x00000001
 | 
						fd_cloexec = 0x00000001
 | 
				
			||||||
	f_dupfd = 0x00000000
 | 
						f_dupfd = 0x00000000
 | 
				
			||||||
| 
						 | 
					@ -191,10 +235,23 @@ fn do_not_call_me_asm_keeper0() {
 | 
				
			||||||
			"ret\n"
 | 
								"ret\n"
 | 
				
			||||||
			""
 | 
								""
 | 
				
			||||||
			".intel_syntax noprefix\n"
 | 
								".intel_syntax noprefix\n"
 | 
				
			||||||
			".globl sys_call0\n"
 | 
								".globl _start, sys_call0\n"
 | 
				
			||||||
			".globl sys_call1, sys_call2, sys_call3\n"
 | 
								".globl sys_call1, sys_call2, sys_call3\n"
 | 
				
			||||||
			".globl sys_call4, sys_call5, sys_call6\n"
 | 
								".globl sys_call4, sys_call5, sys_call6\n"
 | 
				
			||||||
			""
 | 
								""
 | 
				
			||||||
 | 
								"_start:\n"
 | 
				
			||||||
 | 
									"xor rbp,rbp\n"
 | 
				
			||||||
 | 
									"pop rdi\n"
 | 
				
			||||||
 | 
									"mov rsi,rsp\n"
 | 
				
			||||||
 | 
									"and rsp,-16\n"
 | 
				
			||||||
 | 
									"call main\n"
 | 
				
			||||||
 | 
									"mov rdi,rax\n" /* syscall param 1 = rax (ret value of main) */
 | 
				
			||||||
 | 
									"mov rax,60\n"  /* SYS_exit */
 | 
				
			||||||
 | 
									"syscall\n"
 | 
				
			||||||
 | 
									""
 | 
				
			||||||
 | 
									// should never be reached, but if the OS somehow fails to kill us,
 | 
				
			||||||
 | 
									// it will cause a segmentation fault
 | 
				
			||||||
 | 
									"ret\n"
 | 
				
			||||||
			"sys_call0:\n"
 | 
								"sys_call0:\n"
 | 
				
			||||||
				"mov rax,rdi\n"
 | 
									"mov rax,rdi\n"
 | 
				
			||||||
				"syscall\n"
 | 
									"syscall\n"
 | 
				
			||||||
| 
						 | 
					@ -352,8 +409,16 @@ pub fn sys_exit (ec int) {
 | 
				
			||||||
	sys_call1(60, u64(ec))
 | 
						sys_call1(60, u64(ec))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 102 sys_getuid
 | 
				
			||||||
 | 
					pub fn sys_getuid() int {
 | 
				
			||||||
 | 
						return int(sys_call0(102))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 247 sys_waitid  int which pid_t upid  struct siginfo *infop int options struct rusage *ru
 | 
					// 247 sys_waitid  int which pid_t upid  struct siginfo *infop int options struct rusage *ru
 | 
				
			||||||
//pub fn sys_waitid (idtype wi_sys, pid i64, infop voidptr, options
 | 
					pub fn sys_waitid (which wi_which, pid int, infop intptr, options wp_sys, ru voidptr) errno {
 | 
				
			||||||
 | 
						return errno(sys_call5(247, u64(which), u64(pid), u64(infop), u64(options), u64(ru)))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,10 @@
 | 
				
			||||||
module builtin
 | 
					module builtin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						mem_prot = mm_prot(int(mm_prot.prot_read) | int(mm_prot.prot_write))
 | 
				
			||||||
 | 
						mem_flags = map_flags(int(map_flags.map_private) | int(map_flags.map_anonymous))
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn mm_pages(size u64) u32 {
 | 
					pub fn mm_pages(size u64) u32 {
 | 
				
			||||||
	pages := (u64(size+u64(4))+u64(linux_mem.page_size))/u64(linux_mem.page_size)
 | 
						pages := (u64(size+u64(4))+u64(linux_mem.page_size))/u64(linux_mem.page_size)
 | 
				
			||||||
	return u32(pages)
 | 
						return u32(pages)
 | 
				
			||||||
| 
						 | 
					@ -9,9 +14,6 @@ pub fn mm_alloc(size u64) (byteptr, errno) {
 | 
				
			||||||
	pages := mm_pages(size)
 | 
						pages := mm_pages(size)
 | 
				
			||||||
	n_bytes := u64(pages*u32(linux_mem.page_size))
 | 
						n_bytes := u64(pages*u32(linux_mem.page_size))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mem_prot := mm_prot(int(mm_prot.prot_read) | int(mm_prot.prot_write))
 | 
					 | 
				
			||||||
	mem_flags := map_flags(int(map_flags.map_private) | int(map_flags.map_anonymous))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	a, e := sys_mmap(0, n_bytes, mem_prot, mem_flags, -1, 0)
 | 
						a, e := sys_mmap(0, n_bytes, mem_prot, mem_flags, -1, 0)
 | 
				
			||||||
	if e == .enoerror {
 | 
						if e == .enoerror {
 | 
				
			||||||
		mut ap := intptr(a)
 | 
							mut ap := intptr(a)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -126,7 +126,7 @@ fn (v mut V) cc() {
 | 
				
			||||||
		v.out_name = v.out_name + '.so'
 | 
							v.out_name = v.out_name + '.so'
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if v.pref.is_bare {
 | 
						if v.pref.is_bare {
 | 
				
			||||||
		a << '-fno-stack-protector -static -ffreestanding -nostdlib $vdir/vlib/os/bare/bare.S'
 | 
							a << '-fno-stack-protector -static -ffreestanding -nostdlib'
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if v.pref.build_mode == .build_module {
 | 
						if v.pref.build_mode == .build_module {
 | 
				
			||||||
		// Create the modules & out directory if it's not there.
 | 
							// Create the modules & out directory if it's not there.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,39 +0,0 @@
 | 
				
			||||||
.intel_syntax noprefix
 | 
					 | 
				
			||||||
.text
 | 
					 | 
				
			||||||
    .globl _start, main__syscall5
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    _start:
 | 
					 | 
				
			||||||
        xor rbp,rbp
 | 
					 | 
				
			||||||
        pop rdi
 | 
					 | 
				
			||||||
        mov rsi,rsp
 | 
					 | 
				
			||||||
        and rsp,-16
 | 
					 | 
				
			||||||
        call main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        mov rdi,rax /* syscall param 1 = rax (ret value of main) */
 | 
					 | 
				
			||||||
        mov rax,60 /* SYS_exit */
 | 
					 | 
				
			||||||
        syscall
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ret /* should never be reached, but if the OS somehow fails
 | 
					 | 
				
			||||||
               to kill us, it will cause a segmentation fault */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    main__syscall5:
 | 
					 | 
				
			||||||
        mov rax,rdi
 | 
					 | 
				
			||||||
        mov rdi,rsi
 | 
					 | 
				
			||||||
        mov rsi,rdx
 | 
					 | 
				
			||||||
        mov rdx,rcx
 | 
					 | 
				
			||||||
        mov r10,r8
 | 
					 | 
				
			||||||
        mov r8,r9
 | 
					 | 
				
			||||||
        syscall
 | 
					 | 
				
			||||||
        ret
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    main__syscall6:
 | 
					 | 
				
			||||||
        mov rax,rdi
 | 
					 | 
				
			||||||
        mov rdi,rsi
 | 
					 | 
				
			||||||
        mov rsi,rdx
 | 
					 | 
				
			||||||
        mov rdx,rcx
 | 
					 | 
				
			||||||
        mov r10,r8
 | 
					 | 
				
			||||||
        mov r8,r9
 | 
					 | 
				
			||||||
        mov r9, [rsp+8]
 | 
					 | 
				
			||||||
        syscall
 | 
					 | 
				
			||||||
        ret
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,20 +1,7 @@
 | 
				
			||||||
fn syscall5(number, arg1, arg2, arg3, arg4, arg5 voidptr) voidptr
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn write(fd int, data voidptr, nbytes int) int {
 | 
					 | 
				
			||||||
	return 	 syscall5(
 | 
					 | 
				
			||||||
          1, // SYS_write
 | 
					 | 
				
			||||||
           fd,
 | 
					 | 
				
			||||||
            data,
 | 
					 | 
				
			||||||
            nbytes,
 | 
					 | 
				
			||||||
            0, // ignored
 | 
					 | 
				
			||||||
            0  // ignored
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn main() {
 | 
					fn main() {
 | 
				
			||||||
	write(1, c'hello\n', 6)
 | 
						sys_write(1, 'hello\n'.str, 6)
 | 
				
			||||||
	s := 'test string'
 | 
						s := 'test string\n'
 | 
				
			||||||
	write(1, s.str, s.len)
 | 
						sys_write(1, s.str, u64(s.len))
 | 
				
			||||||
	a := s[0]
 | 
						a := s[0]
 | 
				
			||||||
 | 
						println("Hello freestanding!")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue