freestanding: sys_getuid, sys_waitid; minimal fork check; remove bare.S

pull/2971/head
bogen85 2019-12-04 02:46:09 -06:00 committed by Alexander Medvednikov
parent 39655a7d9b
commit a9aaa13a09
6 changed files with 106 additions and 73 deletions

View File

@ -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)
} }

View File

@ -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)))
}
/* /*

View File

@ -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)

View File

@ -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'

View File

@ -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

View File

@ -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!")
} }