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.
|
||||||
|
@ -146,13 +146,13 @@ fn (v mut V) cc() {
|
||||||
debug_mode := v.pref.is_debug
|
debug_mode := v.pref.is_debug
|
||||||
mut debug_options := '-g'
|
mut debug_options := '-g'
|
||||||
mut optimization_options := '-O2'
|
mut optimization_options := '-O2'
|
||||||
|
|
||||||
mut guessed_compiler := v.pref.ccompiler
|
mut guessed_compiler := v.pref.ccompiler
|
||||||
if guessed_compiler == 'cc' && v.pref.is_prod {
|
if guessed_compiler == 'cc' && v.pref.is_prod {
|
||||||
// deliberately guessing only for -prod builds for performance reasons
|
// deliberately guessing only for -prod builds for performance reasons
|
||||||
if ccversion := os.exec('cc --version') {
|
if ccversion := os.exec('cc --version') {
|
||||||
if ccversion.exit_code == 0 {
|
if ccversion.exit_code == 0 {
|
||||||
if ccversion.output.contains('This is free software;')
|
if ccversion.output.contains('This is free software;')
|
||||||
&& ccversion.output.contains('Free Software Foundation, Inc.') {
|
&& ccversion.output.contains('Free Software Foundation, Inc.') {
|
||||||
guessed_compiler = 'gcc'
|
guessed_compiler = 'gcc'
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@ fn (v mut V) cc() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.pref.ccompiler.contains('clang') || guessed_compiler == 'clang' {
|
if v.pref.ccompiler.contains('clang') || guessed_compiler == 'clang' {
|
||||||
if debug_mode {
|
if debug_mode {
|
||||||
debug_options = '-g -O0 -no-pie'
|
debug_options = '-g -O0 -no-pie'
|
||||||
|
|
|
@ -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