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 = ""
)
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)
}

View File

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

View File

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

View File

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

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