freestanding: sys_getuid, sys_waitid; minimal fork check; remove bare.S
parent
39655a7d9b
commit
a9aaa13a09
|
@ -7,17 +7,34 @@ const (
|
|||
sample_text_file1 = ""
|
||||
)
|
||||
|
||||
fn fork_test (test_fn fn(), name string) {
|
||||
//print ("checking")
|
||||
// a := "$name"
|
||||
println (name)
|
||||
fn check_fork_minimal () {
|
||||
child := sys_fork()
|
||||
ec := 100
|
||||
if child == 0 {
|
||||
test_fn()
|
||||
sys_exit(0)
|
||||
println("child")
|
||||
sys_exit(ec)
|
||||
}
|
||||
// pid := sys_wait(0)
|
||||
// assert
|
||||
siginfo := [
|
||||
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() {
|
||||
|
@ -316,5 +333,6 @@ fn main() {
|
|||
check_int64_array_ro()
|
||||
check_voidptr_array_ro()
|
||||
check_voidptr_array_rw()
|
||||
check_fork_minimal()
|
||||
sys_exit(0)
|
||||
}
|
||||
|
|
|
@ -64,6 +64,50 @@ pub enum wi_si_code {
|
|||
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 {
|
||||
fd_cloexec = 0x00000001
|
||||
f_dupfd = 0x00000000
|
||||
|
@ -191,10 +235,23 @@ fn do_not_call_me_asm_keeper0() {
|
|||
"ret\n"
|
||||
""
|
||||
".intel_syntax noprefix\n"
|
||||
".globl sys_call0\n"
|
||||
".globl _start, sys_call0\n"
|
||||
".globl sys_call1, sys_call2, sys_call3\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"
|
||||
"mov rax,rdi\n"
|
||||
"syscall\n"
|
||||
|
@ -352,8 +409,16 @@ pub fn sys_exit (ec int) {
|
|||
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
|
||||
//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
|
||||
|
||||
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 {
|
||||
pages := (u64(size+u64(4))+u64(linux_mem.page_size))/u64(linux_mem.page_size)
|
||||
return u32(pages)
|
||||
|
@ -9,9 +14,6 @@ pub fn mm_alloc(size u64) (byteptr, errno) {
|
|||
pages := mm_pages(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)
|
||||
if e == .enoerror {
|
||||
mut ap := intptr(a)
|
||||
|
|
|
@ -126,7 +126,7 @@ fn (v mut V) cc() {
|
|||
v.out_name = v.out_name + '.so'
|
||||
}
|
||||
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 {
|
||||
// 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
|
||||
mut debug_options := '-g'
|
||||
mut optimization_options := '-O2'
|
||||
|
||||
|
||||
mut guessed_compiler := v.pref.ccompiler
|
||||
if guessed_compiler == 'cc' && v.pref.is_prod {
|
||||
// deliberately guessing only for -prod builds for performance reasons
|
||||
if ccversion := os.exec('cc --version') {
|
||||
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.') {
|
||||
guessed_compiler = 'gcc'
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ fn (v mut V) cc() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if v.pref.ccompiler.contains('clang') || guessed_compiler == 'clang' {
|
||||
if debug_mode {
|
||||
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() {
|
||||
write(1, c'hello\n', 6)
|
||||
s := 'test string'
|
||||
write(1, s.str, s.len)
|
||||
sys_write(1, 'hello\n'.str, 6)
|
||||
s := 'test string\n'
|
||||
sys_write(1, s.str, u64(s.len))
|
||||
a := s[0]
|
||||
println("Hello freestanding!")
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue