1/*
2 * Copyright 2014, NICTA
3 *
4 * This software may be distributed and modified according to the terms of
5 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
6 * See "LICENSE_BSD2.txt" for details.
7 *
8 * @TAG(NICTA_BSD)
9 */
10
11#include <autoconf.h>
12#include <stdio.h>
13#include <stdint.h>
14#include <sel4/sel4.h>
15#include <utils/util.h>
16#include <bits/syscall.h>
17#include <bits/errno.h>
18#include "syscalls.h"
19
20/* construct a lookup table of all the syscalls */
21long (*syscall_table[])(va_list) = {
22#ifdef __NR_set_thread_area
23    [__NR_set_thread_area] = sys_set_thread_area,
24#endif
25    [__NR_set_tid_address] = sys_set_tid_address,
26    [__NR_writev] = sys_writev,
27    [__NR_sched_yield] = sys_sched_yield,
28    [__NR_exit] = sys_exit,
29    [__NR_rt_sigprocmask] = sys_rt_sigprocmask,
30    [__NR_gettid] = sys_gettid,
31    [__NR_getpid] = sys_getpid,
32    [__NR_tgkill] = sys_tgkill,
33    [__NR_tkill] = sys_tkill,
34    [__NR_exit_group] = sys_exit_group,
35    [__NR_open] = sys_open,
36    [__NR_close] = sys_close,
37    [__NR_readv] = sys_readv,
38    [__NR_read] = sys_read,
39    [__NR_ioctl] = sys_ioctl,
40    [__NR_prlimit64] = sys_prlimit64,
41    [__NR_lseek] = sys_lseek,
42#ifdef __NR__llseek
43    [__NR__llseek] = sys__llseek,
44#endif
45    [__NR_access] = sys_access,
46    [__NR_brk] = sys_brk,
47#ifdef __NR_mmap2
48    [__NR_mmap2] = sys_mmap2,
49#endif
50    [__NR_mremap] = sys_mremap,
51};
52
53#ifdef CONFIG_DEBUG_BUILD
54static void debug_error(int sysnum) {
55    char buf[100];
56    int i;
57    sprintf(buf, "librefossys: Error attempting syscall %d\n", sysnum);
58    for (i = 0; buf[i]; i++) {
59        seL4_DebugPutChar(buf[i]);
60    }
61}
62#else
63static void debug_error(int sysnum) {
64}
65#endif
66
67long sel4_vsyscall(long sysnum, ...) {
68    va_list al;
69    va_start(al, sysnum);
70    if (sysnum < 0 || sysnum >= ARRAY_SIZE(syscall_table)) {
71        debug_error(sysnum);
72        return -ENOSYS;
73    }
74    /* Check a syscall is implemented there */
75    if (!syscall_table[sysnum]) {
76        debug_error(sysnum);
77        return -ENOSYS;
78    }
79    /* Call it */
80    long ret = syscall_table[sysnum](al);
81    va_end(al);
82    return ret;
83}
84
85/* Put a pointer to sel4_vsyscall in a special section so anyone loading us
86 * knows how to configure our syscall table */
87uintptr_t VISIBLE SECTION("__vsyscall") __vsyscall_ptr = (uintptr_t) sel4_vsyscall;
88