set machine_arch to that of the hostdiff -r1.42 -r1.43 src/sys/arch/usermode/include/thunk.h
(jmcneill)
--- src/sys/arch/usermode/include/thunk.h 2011/12/20 15:45:36 1.42
+++ src/sys/arch/usermode/include/thunk.h 2011/12/20 21:26:37 1.43
@@ -1,150 +1,152 @@ | @@ -1,150 +1,152 @@ | |||
1 | /* $NetBSD: thunk.h,v 1.42 2011/12/20 15:45:36 reinoud Exp $ */ | 1 | /* $NetBSD: thunk.h,v 1.43 2011/12/20 21:26:37 jmcneill Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> | 4 | * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
15 | * | 15 | * | |
16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #ifndef _ARCH_USERMODE_INCLUDE_THUNK_H | 29 | #ifndef _ARCH_USERMODE_INCLUDE_THUNK_H | |
30 | #define _ARCH_USERMODE_INCLUDE_THUNK_H | 30 | #define _ARCH_USERMODE_INCLUDE_THUNK_H | |
31 | 31 | |||
32 | #include <sys/types.h> | 32 | #include <sys/types.h> | |
33 | #include <sys/time.h> | 33 | #include <sys/time.h> | |
34 | #include <sys/stat.h> | 34 | #include <sys/stat.h> | |
35 | #include <sys/fcntl.h> | 35 | #include <sys/fcntl.h> | |
36 | #include <sys/ucontext.h> | 36 | #include <sys/ucontext.h> | |
37 | #include <sys/signal.h> | 37 | #include <sys/signal.h> | |
38 | 38 | |||
39 | struct thunk_timeval { | 39 | struct thunk_timeval { | |
40 | int64_t tv_sec; | 40 | int64_t tv_sec; | |
41 | int32_t tv_usec; | 41 | int32_t tv_usec; | |
42 | }; | 42 | }; | |
43 | 43 | |||
44 | struct thunk_itimerval { | 44 | struct thunk_itimerval { | |
45 | struct thunk_timeval it_interval; | 45 | struct thunk_timeval it_interval; | |
46 | struct thunk_timeval it_value; | 46 | struct thunk_timeval it_value; | |
47 | }; | 47 | }; | |
48 | 48 | |||
49 | struct thunk_termios { | 49 | struct thunk_termios { | |
50 | uint32_t c_iflag; | 50 | uint32_t c_iflag; | |
51 | uint32_t c_oflag; | 51 | uint32_t c_oflag; | |
52 | uint32_t c_cflag; | 52 | uint32_t c_cflag; | |
53 | uint32_t c_lflag; | 53 | uint32_t c_lflag; | |
54 | uint8_t c_cc[20]; | 54 | uint8_t c_cc[20]; | |
55 | int32_t c_ispeed; | 55 | int32_t c_ispeed; | |
56 | int32_t c_ospeed; | 56 | int32_t c_ospeed; | |
57 | }; | 57 | }; | |
58 | 58 | |||
59 | #define THUNK_MAP_ANON 0x0001 | 59 | #define THUNK_MAP_ANON 0x0001 | |
60 | #define THUNK_MAP_FIXED 0x0002 | 60 | #define THUNK_MAP_FIXED 0x0002 | |
61 | #define THUNK_MAP_FILE 0x0004 | 61 | #define THUNK_MAP_FILE 0x0004 | |
62 | #define THUNK_MAP_SHARED 0x0010 | 62 | #define THUNK_MAP_SHARED 0x0010 | |
63 | #define THUNK_MAP_PRIVATE 0x0020 | 63 | #define THUNK_MAP_PRIVATE 0x0020 | |
64 | #define THUNK_MAP_NOSYSCALLS 0x0040 | 64 | #define THUNK_MAP_NOSYSCALLS 0x0040 | |
65 | 65 | |||
66 | #define THUNK_PROT_NONE 0x00 | 66 | #define THUNK_PROT_NONE 0x00 | |
67 | #define THUNK_PROT_READ 0x01 | 67 | #define THUNK_PROT_READ 0x01 | |
68 | #define THUNK_PROT_WRITE 0x02 | 68 | #define THUNK_PROT_WRITE 0x02 | |
69 | #define THUNK_PROT_EXEC 0x04 | 69 | #define THUNK_PROT_EXEC 0x04 | |
70 | 70 | |||
71 | struct aiocb; | 71 | struct aiocb; | |
72 | 72 | |||
73 | void dprintf_debug(const char *fmt, ...) __attribute__((__format__(__printf__, 1, 2))); | 73 | void dprintf_debug(const char *fmt, ...) __attribute__((__format__(__printf__, 1, 2))); | |
74 | 74 | |||
75 | int thunk_setitimer(int, const struct thunk_itimerval *, struct thunk_itimerval *); | 75 | int thunk_setitimer(int, const struct thunk_itimerval *, struct thunk_itimerval *); | |
76 | int thunk_gettimeofday(struct thunk_timeval *, void *); | 76 | int thunk_gettimeofday(struct thunk_timeval *, void *); | |
77 | unsigned int thunk_getcounter(void); | 77 | unsigned int thunk_getcounter(void); | |
78 | long thunk_clock_getres_monotonic(void); | 78 | long thunk_clock_getres_monotonic(void); | |
79 | int thunk_usleep(useconds_t); | 79 | int thunk_usleep(useconds_t); | |
80 | 80 | |||
81 | timer_t thunk_timer_attach(void); | 81 | timer_t thunk_timer_attach(void); | |
82 | int thunk_timer_start(timer_t, int); | 82 | int thunk_timer_start(timer_t, int); | |
83 | int thunk_timer_getoverrun(timer_t); | 83 | int thunk_timer_getoverrun(timer_t); | |
84 | 84 | |||
85 | void thunk_exit(int); | 85 | void thunk_exit(int); | |
86 | void thunk_abort(void); | 86 | void thunk_abort(void); | |
87 | 87 | |||
88 | int thunk_geterrno(void); | 88 | int thunk_geterrno(void); | |
89 | void thunk_seterrno(int err); | 89 | void thunk_seterrno(int err); | |
90 | 90 | |||
91 | int thunk_getcontext(ucontext_t *); | 91 | int thunk_getcontext(ucontext_t *); | |
92 | int thunk_setcontext(const ucontext_t *); | 92 | int thunk_setcontext(const ucontext_t *); | |
93 | void thunk_makecontext(ucontext_t *ucp, void (*func)(void), | 93 | void thunk_makecontext(ucontext_t *ucp, void (*func)(void), | |
94 | int nargs, void *arg1, void *arg2, void *arg3); | 94 | int nargs, void *arg1, void *arg2, void *arg3); | |
95 | int thunk_swapcontext(ucontext_t *, ucontext_t *); | 95 | int thunk_swapcontext(ucontext_t *, ucontext_t *); | |
96 | 96 | |||
97 | int thunk_tcgetattr(int, struct thunk_termios *); | 97 | int thunk_tcgetattr(int, struct thunk_termios *); | |
98 | int thunk_tcsetattr(int, int, const struct thunk_termios *); | 98 | int thunk_tcsetattr(int, int, const struct thunk_termios *); | |
99 | 99 | |||
100 | int thunk_set_stdin_sigio(int); | 100 | int thunk_set_stdin_sigio(int); | |
101 | int thunk_pollchar(void); | 101 | int thunk_pollchar(void); | |
102 | int thunk_getchar(void); | 102 | int thunk_getchar(void); | |
103 | void thunk_putchar(int); | 103 | void thunk_putchar(int); | |
104 | 104 | |||
105 | int thunk_execv(const char *, char * const []); | 105 | int thunk_execv(const char *, char * const []); | |
106 | 106 | |||
107 | int thunk_open(const char *, int, mode_t); | 107 | int thunk_open(const char *, int, mode_t); | |
108 | int thunk_fstat_getsize(int, ssize_t *, ssize_t *); | 108 | int thunk_fstat_getsize(int, ssize_t *, ssize_t *); | |
109 | ssize_t thunk_pread(int, void *, size_t, off_t); | 109 | ssize_t thunk_pread(int, void *, size_t, off_t); | |
110 | ssize_t thunk_pwrite(int, const void *, size_t, off_t); | 110 | ssize_t thunk_pwrite(int, const void *, size_t, off_t); | |
111 | ssize_t thunk_write(int, const void *, size_t); | 111 | ssize_t thunk_write(int, const void *, size_t); | |
112 | int thunk_fsync(int); | 112 | int thunk_fsync(int); | |
113 | int thunk_mkstemp(char *); | 113 | int thunk_mkstemp(char *); | |
114 | int thunk_unlink(const char *); | 114 | int thunk_unlink(const char *); | |
115 | 115 | |||
116 | int thunk_sigaction(int, const struct sigaction *, struct sigaction *); | 116 | int thunk_sigaction(int, const struct sigaction *, struct sigaction *); | |
117 | int thunk_sigaltstack(const stack_t *, stack_t *); | 117 | int thunk_sigaltstack(const stack_t *, stack_t *); | |
118 | void thunk_signal(int, void (*)(int)); | 118 | void thunk_signal(int, void (*)(int)); | |
119 | int thunk_sigblock(int); | 119 | int thunk_sigblock(int); | |
120 | int thunk_sigunblock(int); | 120 | int thunk_sigunblock(int); | |
121 | int thunk_sigemptyset(sigset_t *sa_mask); | 121 | int thunk_sigemptyset(sigset_t *sa_mask); | |
122 | void thunk_sigaddset(sigset_t *sa_mask, int sig); | 122 | void thunk_sigaddset(sigset_t *sa_mask, int sig); | |
123 | int thunk_sigprocmask(int how, const sigset_t * set, sigset_t *oset); | 123 | int thunk_sigprocmask(int how, const sigset_t * set, sigset_t *oset); | |
124 | int thunk_atexit(void (*function)(void)); | 124 | int thunk_atexit(void (*function)(void)); | |
125 | 125 | |||
126 | int thunk_aio_read(struct aiocb *); | 126 | int thunk_aio_read(struct aiocb *); | |
127 | int thunk_aio_write(struct aiocb *); | 127 | int thunk_aio_write(struct aiocb *); | |
128 | int thunk_aio_error(const struct aiocb *); | 128 | int thunk_aio_error(const struct aiocb *); | |
129 | int thunk_aio_return(struct aiocb *); | 129 | int thunk_aio_return(struct aiocb *); | |
130 | 130 | |||
131 | void * thunk_malloc(size_t len); | 131 | void * thunk_malloc(size_t len); | |
132 | void thunk_free(void *addr); | 132 | void thunk_free(void *addr); | |
133 | void * thunk_sbrk(intptr_t len); | 133 | void * thunk_sbrk(intptr_t len); | |
134 | void * thunk_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset); | 134 | void * thunk_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset); | |
135 | int thunk_munmap(void *addr, size_t len); | 135 | int thunk_munmap(void *addr, size_t len); | |
136 | int thunk_mprotect(void *addr, size_t len, int prot); | 136 | int thunk_mprotect(void *addr, size_t len, int prot); | |
137 | int thunk_posix_memalign(void **, size_t, size_t); | 137 | int thunk_posix_memalign(void **, size_t, size_t); | |
138 | 138 | |||
139 | int thunk_idle(void); | 139 | int thunk_idle(void); | |
140 | 140 | |||
141 | char * thunk_getenv(const char *); | 141 | char * thunk_getenv(const char *); | |
142 | vaddr_t thunk_get_vm_min_address(void); | 142 | vaddr_t thunk_get_vm_min_address(void); | |
143 | 143 | |||
144 | int thunk_getcpuinfo(char *, int *); | 144 | int thunk_getcpuinfo(char *, int *); | |
145 | 145 | |||
146 | int thunk_getmachine(char *, size_t); | |||
147 | ||||
146 | int thunk_sdl_init(unsigned int, unsigned int, unsigned short); | 148 | int thunk_sdl_init(unsigned int, unsigned int, unsigned short); | |
147 | void * thunk_sdl_getfb(size_t); | 149 | void * thunk_sdl_getfb(size_t); | |
148 | int thunk_sdl_getchar(void); | 150 | int thunk_sdl_getchar(void); | |
149 | 151 | |||
150 | #endif /* !_ARCH_USERMODE_INCLUDE_THUNK_H */ | 152 | #endif /* !_ARCH_USERMODE_INCLUDE_THUNK_H */ |
--- src/sys/arch/usermode/usermode/machdep.c 2011/12/20 21:01:39 1.39
+++ src/sys/arch/usermode/usermode/machdep.c 2011/12/20 21:26:37 1.40
@@ -1,347 +1,350 @@ | @@ -1,347 +1,350 @@ | |||
1 | /* $NetBSD: machdep.c,v 1.39 2011/12/20 21:01:39 jmcneill Exp $ */ | 1 | /* $NetBSD: machdep.c,v 1.40 2011/12/20 21:26:37 jmcneill Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2011 Reinoud Zandijk <reinoud@netbsd.org> | 4 | * Copyright (c) 2011 Reinoud Zandijk <reinoud@netbsd.org> | |
5 | * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> | 5 | * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> | |
6 | * All rights reserved. | 6 | * All rights reserved. | |
7 | * | 7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | 9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | 10 | * are met: | |
11 | * 1. Redistributions of source code must retain the above copyright | 11 | * 1. Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | 12 | * notice, this list of conditions and the following disclaimer. | |
13 | * 2. Redistributions in binary form must reproduce the above copyright | 13 | * 2. Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in the | 14 | * notice, this list of conditions and the following disclaimer in the | |
15 | * documentation and/or other materials provided with the distribution. | 15 | * documentation and/or other materials provided with the distribution. | |
16 | * | 16 | * | |
17 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 17 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
18 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 18 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
19 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 19 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
20 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 20 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
27 | * POSSIBILITY OF SUCH DAMAGE. | 27 | * POSSIBILITY OF SUCH DAMAGE. | |
28 | */ | 28 | */ | |
29 | 29 | |||
30 | #include "opt_memsize.h" | 30 | #include "opt_memsize.h" | |
31 | #include "opt_sdl.h" | 31 | #include "opt_sdl.h" | |
32 | 32 | |||
33 | #include <sys/cdefs.h> | 33 | #include <sys/cdefs.h> | |
34 | __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.39 2011/12/20 21:01:39 jmcneill Exp $"); | 34 | __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.40 2011/12/20 21:26:37 jmcneill Exp $"); | |
35 | 35 | |||
36 | #include <sys/types.h> | 36 | #include <sys/types.h> | |
37 | #include <sys/param.h> | 37 | #include <sys/param.h> | |
38 | #include <sys/time.h> | 38 | #include <sys/time.h> | |
39 | #include <sys/exec.h> | 39 | #include <sys/exec.h> | |
40 | #include <sys/buf.h> | 40 | #include <sys/buf.h> | |
41 | #include <sys/boot_flag.h> | 41 | #include <sys/boot_flag.h> | |
42 | #include <sys/ucontext.h> | 42 | #include <sys/ucontext.h> | |
43 | #include <sys/utsname.h> | |||
43 | #include <machine/pcb.h> | 44 | #include <machine/pcb.h> | |
44 | #include <machine/psl.h> | 45 | #include <machine/psl.h> | |
45 | 46 | |||
46 | #include <uvm/uvm_extern.h> | 47 | #include <uvm/uvm_extern.h> | |
47 | #include <uvm/uvm_page.h> | 48 | #include <uvm/uvm_page.h> | |
48 | 49 | |||
49 | #include <dev/mm.h> | 50 | #include <dev/mm.h> | |
50 | #include <machine/machdep.h> | 51 | #include <machine/machdep.h> | |
51 | #include <machine/thunk.h> | 52 | #include <machine/thunk.h> | |
52 | 53 | |||
53 | char machine[] = "usermode"; | 54 | char machine[] = "usermode"; | |
54 | char machine_arch[] = "usermode"; | 55 | char machine_arch[_SYS_NMLN] = ""; | |
55 | 56 | |||
56 | static char **saved_argv; | 57 | static char **saved_argv; | |
57 | char *usermode_root_image_path = NULL; | 58 | char *usermode_root_image_path = NULL; | |
58 | 59 | |||
59 | void main(int argc, char *argv[]); | 60 | void main(int argc, char *argv[]); | |
60 | void usermode_reboot(void); | 61 | void usermode_reboot(void); | |
61 | 62 | |||
62 | void | 63 | void | |
63 | main(int argc, char *argv[]) | 64 | main(int argc, char *argv[]) | |
64 | { | 65 | { | |
65 | #if defined(SDL) | 66 | #if defined(SDL) | |
66 | extern int genfb_thunkbus_cnattach(void); | 67 | extern int genfb_thunkbus_cnattach(void); | |
67 | #endif | 68 | #endif | |
68 | extern void ttycons_consinit(void); | 69 | extern void ttycons_consinit(void); | |
69 | extern void pmap_bootstrap(void); | 70 | extern void pmap_bootstrap(void); | |
70 | extern void kernmain(void); | 71 | extern void kernmain(void); | |
71 | int i, j, r, tmpopt = 0; | 72 | int i, j, r, tmpopt = 0; | |
72 | 73 | |||
73 | saved_argv = argv; | 74 | saved_argv = argv; | |
74 | 75 | |||
76 | thunk_getmachine(machine_arch, sizeof(machine_arch)); | |||
77 | ||||
75 | #if defined(SDL) | 78 | #if defined(SDL) | |
76 | if (genfb_thunkbus_cnattach() == 0) | 79 | if (genfb_thunkbus_cnattach() == 0) | |
77 | #endif | 80 | #endif | |
78 | ttycons_consinit(); | 81 | ttycons_consinit(); | |
79 | 82 | |||
80 | for (i = 1; i < argc; i++) { | 83 | for (i = 1; i < argc; i++) { | |
81 | if (argv[i][0] != '-') { | 84 | if (argv[i][0] != '-') { | |
82 | usermode_root_image_path = argv[i]; | 85 | usermode_root_image_path = argv[i]; | |
83 | continue; | 86 | continue; | |
84 | } | 87 | } | |
85 | for (j = 1; argv[i][j] != '\0'; j++) { | 88 | for (j = 1; argv[i][j] != '\0'; j++) { | |
86 | r = 0; | 89 | r = 0; | |
87 | BOOT_FLAG(argv[i][j], r); | 90 | BOOT_FLAG(argv[i][j], r); | |
88 | if (r == 0) { | 91 | if (r == 0) { | |
89 | printf("-%c: unknown flag\n", argv[i][j]); | 92 | printf("-%c: unknown flag\n", argv[i][j]); | |
90 | printf("usage: %s [-acdqsvxz]\n", argv[0]); | 93 | printf("usage: %s [-acdqsvxz]\n", argv[0]); | |
91 | printf(" (ex. \"%s -s\")\n", argv[0]); | 94 | printf(" (ex. \"%s -s\")\n", argv[0]); | |
92 | return; | 95 | return; | |
93 | } | 96 | } | |
94 | tmpopt |= r; | 97 | tmpopt |= r; | |
95 | } | 98 | } | |
96 | } | 99 | } | |
97 | boothowto = tmpopt; | 100 | boothowto = tmpopt; | |
98 | 101 | |||
99 | uvm_setpagesize(); | 102 | uvm_setpagesize(); | |
100 | uvmexp.ncolors = 2; | 103 | uvmexp.ncolors = 2; | |
101 | 104 | |||
102 | pmap_bootstrap(); | 105 | pmap_bootstrap(); | |
103 | 106 | |||
104 | splinit(); | 107 | splinit(); | |
105 | splraise(IPL_HIGH); | 108 | splraise(IPL_HIGH); | |
106 | 109 | |||
107 | kernmain(); | 110 | kernmain(); | |
108 | } | 111 | } | |
109 | 112 | |||
110 | void | 113 | void | |
111 | usermode_reboot(void) | 114 | usermode_reboot(void) | |
112 | { | 115 | { | |
113 | struct thunk_itimerval itimer; | 116 | struct thunk_itimerval itimer; | |
114 | 117 | |||
115 | /* make sure the timer is turned off */ | 118 | /* make sure the timer is turned off */ | |
116 | memset(&itimer, 0, sizeof(itimer)); | 119 | memset(&itimer, 0, sizeof(itimer)); | |
117 | thunk_setitimer(ITIMER_REAL, &itimer, NULL); | 120 | thunk_setitimer(ITIMER_REAL, &itimer, NULL); | |
118 | 121 | |||
119 | if (thunk_execv(saved_argv[0], saved_argv) == -1) | 122 | if (thunk_execv(saved_argv[0], saved_argv) == -1) | |
120 | thunk_abort(); | 123 | thunk_abort(); | |
121 | /* NOTREACHED */ | 124 | /* NOTREACHED */ | |
122 | } | 125 | } | |
123 | 126 | |||
124 | void | 127 | void | |
125 | setstatclockrate(int arg) | 128 | setstatclockrate(int arg) | |
126 | { | 129 | { | |
127 | } | 130 | } | |
128 | 131 | |||
129 | void | 132 | void | |
130 | consinit(void) | 133 | consinit(void) | |
131 | { | 134 | { | |
132 | printf("NetBSD/usermode startup\n"); | 135 | printf("NetBSD/usermode startup\n"); | |
133 | } | 136 | } | |
134 | 137 | |||
135 | void | 138 | void | |
136 | sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask) | 139 | sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask) | |
137 | { | 140 | { | |
138 | #if 1 | 141 | #if 1 | |
139 | printf("%s: ", __func__); | 142 | printf("%s: ", __func__); | |
140 | printf("flags %d, ", (int) ksi->ksi_flags); | 143 | printf("flags %d, ", (int) ksi->ksi_flags); | |
141 | printf("to lwp %d, signo %d, code %d, errno %d\n", | 144 | printf("to lwp %d, signo %d, code %d, errno %d\n", | |
142 | (int) ksi->ksi_lid, | 145 | (int) ksi->ksi_lid, | |
143 | ksi->ksi_signo, | 146 | ksi->ksi_signo, | |
144 | ksi->ksi_code, | 147 | ksi->ksi_code, | |
145 | ksi->ksi_errno); | 148 | ksi->ksi_errno); | |
146 | #endif | 149 | #endif | |
147 | 150 | |||
148 | panic("%s not implemented", __func__); | 151 | panic("%s not implemented", __func__); | |
149 | } | 152 | } | |
150 | 153 | |||
151 | int | 154 | int | |
152 | mm_md_physacc(paddr_t pa, vm_prot_t prog) | 155 | mm_md_physacc(paddr_t pa, vm_prot_t prog) | |
153 | { | 156 | { | |
154 | return 0; | 157 | return 0; | |
155 | } | 158 | } | |
156 | 159 | |||
157 | 160 | |||
158 | #ifdef __i386__ | 161 | #ifdef __i386__ | |
159 | 162 | |||
160 | #if 0 | 163 | #if 0 | |
161 | static void dump_regs(register_t *reg);; | 164 | static void dump_regs(register_t *reg);; | |
162 | 165 | |||
163 | static void | 166 | static void | |
164 | dump_regs(register_t *reg) | 167 | dump_regs(register_t *reg) | |
165 | { | 168 | { | |
166 | int i; | 169 | int i; | |
167 | 170 | |||
168 | /* register dump before call */ | 171 | /* register dump before call */ | |
169 | const char *name[] = {"GS", "FS", "ES", "DS", "EDI", "ESI", "EBP", "ESP", | 172 | const char *name[] = {"GS", "FS", "ES", "DS", "EDI", "ESI", "EBP", "ESP", | |
170 | "EBX", "EDX", "ECX", "EAX", "TRAPNO", "ERR", "EIP", "CS", "EFL", | 173 | "EBX", "EDX", "ECX", "EAX", "TRAPNO", "ERR", "EIP", "CS", "EFL", | |
171 | "UESP", "SS"}; | 174 | "UESP", "SS"}; | |
172 | 175 | |||
173 | for (i =0; i < 19; i++) | 176 | for (i =0; i < 19; i++) | |
174 | printf("reg[%02d] (%6s) = %"PRIx32"\n", i, name[i], (uint32_t) reg[i]); | 177 | printf("reg[%02d] (%6s) = %"PRIx32"\n", i, name[i], (uint32_t) reg[i]); | |
175 | } | 178 | } | |
176 | #endif | 179 | #endif | |
177 | 180 | |||
178 | void | 181 | void | |
179 | setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack) | 182 | setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack) | |
180 | { | 183 | { | |
181 | struct pcb *pcb = lwp_getpcb(l); | 184 | struct pcb *pcb = lwp_getpcb(l); | |
182 | ucontext_t *ucp = &pcb->pcb_userret_ucp; | 185 | ucontext_t *ucp = &pcb->pcb_userret_ucp; | |
183 | uint *reg, i; | 186 | uint *reg, i; | |
184 | 187 | |||
185 | #ifdef DEBUG_EXEC | 188 | #ifdef DEBUG_EXEC | |
186 | printf("setregs called: lwp %p, exec package %p, stack %p\n", | 189 | printf("setregs called: lwp %p, exec package %p, stack %p\n", | |
187 | l, pack, (void *) stack); | 190 | l, pack, (void *) stack); | |
188 | printf("current stat of pcb %p\n", pcb); | 191 | printf("current stat of pcb %p\n", pcb); | |
189 | printf("\tpcb->pcb_ucp.uc_stack.ss_sp = %p\n", | 192 | printf("\tpcb->pcb_ucp.uc_stack.ss_sp = %p\n", | |
190 | pcb->pcb_ucp.uc_stack.ss_sp); | 193 | pcb->pcb_ucp.uc_stack.ss_sp); | |
191 | printf("\tpcb->pcb_ucp.uc_stack.ss_size = %d\n", | 194 | printf("\tpcb->pcb_ucp.uc_stack.ss_size = %d\n", | |
192 | (int) pcb->pcb_ucp.uc_stack.ss_size); | 195 | (int) pcb->pcb_ucp.uc_stack.ss_size); | |
193 | printf("\tpcb->pcb_userret_ucp.uc_stack.ss_sp = %p\n", | 196 | printf("\tpcb->pcb_userret_ucp.uc_stack.ss_sp = %p\n", | |
194 | pcb->pcb_userret_ucp.uc_stack.ss_sp); | 197 | pcb->pcb_userret_ucp.uc_stack.ss_sp); | |
195 | printf("\tpcb->pcb_userret_ucp.uc_stack.ss_size = %d\n", | 198 | printf("\tpcb->pcb_userret_ucp.uc_stack.ss_size = %d\n", | |
196 | (int) pcb->pcb_userret_ucp.uc_stack.ss_size); | 199 | (int) pcb->pcb_userret_ucp.uc_stack.ss_size); | |
197 | #endif | 200 | #endif | |
198 | 201 | |||
199 | reg = (int *) &ucp->uc_mcontext; | 202 | reg = (int *) &ucp->uc_mcontext; | |
200 | for (i = 4; i < 11; i++) | 203 | for (i = 4; i < 11; i++) | |
201 | reg[i] = 0; | 204 | reg[i] = 0; | |
202 | 205 | |||
203 | ucp->uc_stack.ss_sp = (void *) (stack-4); /* to prevent clearing */ | 206 | ucp->uc_stack.ss_sp = (void *) (stack-4); /* to prevent clearing */ | |
204 | ucp->uc_stack.ss_size = 0; //pack->ep_ssize; | 207 | ucp->uc_stack.ss_size = 0; //pack->ep_ssize; | |
205 | thunk_makecontext(ucp, (void *) pack->ep_entry, 0, NULL, NULL, NULL); | 208 | thunk_makecontext(ucp, (void *) pack->ep_entry, 0, NULL, NULL, NULL); | |
206 | 209 | |||
207 | /* patch up */ | 210 | /* patch up */ | |
208 | reg[ 8] = l->l_proc->p_psstrp; /* _REG_EBX */ | 211 | reg[ 8] = l->l_proc->p_psstrp; /* _REG_EBX */ | |
209 | reg[17] = (stack); /* _REG_UESP */ | 212 | reg[17] = (stack); /* _REG_UESP */ | |
210 | 213 | |||
211 | //dump_regs(reg); | 214 | //dump_regs(reg); | |
212 | 215 | |||
213 | #ifdef DEBUG_EXEC | 216 | #ifdef DEBUG_EXEC | |
214 | printf("updated pcb %p\n", pcb); | 217 | printf("updated pcb %p\n", pcb); | |
215 | printf("\tpcb->pcb_ucp.uc_stack.ss_sp = %p\n", | 218 | printf("\tpcb->pcb_ucp.uc_stack.ss_sp = %p\n", | |
216 | pcb->pcb_ucp.uc_stack.ss_sp); | 219 | pcb->pcb_ucp.uc_stack.ss_sp); | |
217 | printf("\tpcb->pcb_ucp.uc_stack.ss_size = %d\n", | 220 | printf("\tpcb->pcb_ucp.uc_stack.ss_size = %d\n", | |
218 | (int) pcb->pcb_ucp.uc_stack.ss_size); | 221 | (int) pcb->pcb_ucp.uc_stack.ss_size); | |
219 | printf("\tpcb->pcb_userret_ucp.uc_stack.ss_sp = %p\n", | 222 | printf("\tpcb->pcb_userret_ucp.uc_stack.ss_sp = %p\n", | |
220 | pcb->pcb_userret_ucp.uc_stack.ss_sp); | 223 | pcb->pcb_userret_ucp.uc_stack.ss_sp); | |
221 | printf("\tpcb->pcb_userret_ucp.uc_stack.ss_size = %d\n", | 224 | printf("\tpcb->pcb_userret_ucp.uc_stack.ss_size = %d\n", | |
222 | (int) pcb->pcb_userret_ucp.uc_stack.ss_size); | 225 | (int) pcb->pcb_userret_ucp.uc_stack.ss_size); | |
223 | printf("\tpack->ep_entry = %p\n", | 226 | printf("\tpack->ep_entry = %p\n", | |
224 | (void *) pack->ep_entry); | 227 | (void *) pack->ep_entry); | |
225 | #endif | 228 | #endif | |
226 | } | 229 | } | |
227 | 230 | |||
228 | void | 231 | void | |
229 | md_syscall_get_syscallnumber(ucontext_t *ucp, uint32_t *code) | 232 | md_syscall_get_syscallnumber(ucontext_t *ucp, uint32_t *code) | |
230 | { | 233 | { | |
231 | uint *reg = (int *) &ucp->uc_mcontext; | 234 | uint *reg = (int *) &ucp->uc_mcontext; | |
232 | *code = reg[11]; /* EAX */ | 235 | *code = reg[11]; /* EAX */ | |
233 | } | 236 | } | |
234 | 237 | |||
235 | int | 238 | int | |
236 | md_syscall_getargs(lwp_t *l, ucontext_t *ucp, int nargs, int argsize, | 239 | md_syscall_getargs(lwp_t *l, ucontext_t *ucp, int nargs, int argsize, | |
237 | register_t *args) | 240 | register_t *args) | |
238 | { | 241 | { | |
239 | uint *reg = (int *) &ucp->uc_mcontext; | 242 | uint *reg = (int *) &ucp->uc_mcontext; | |
240 | register_t *sp = (register_t *) reg[17];/* ESP */ | 243 | register_t *sp = (register_t *) reg[17];/* ESP */ | |
241 | int ret; | 244 | int ret; | |
242 | 245 | |||
243 | //dump_regs(reg); | 246 | //dump_regs(reg); | |
244 | ret = copyin(sp + 1, args, argsize); | 247 | ret = copyin(sp + 1, args, argsize); | |
245 | 248 | |||
246 | return ret; | 249 | return ret; | |
247 | } | 250 | } | |
248 | 251 | |||
249 | void | 252 | void | |
250 | md_syscall_set_returnargs(lwp_t *l, ucontext_t *ucp, | 253 | md_syscall_set_returnargs(lwp_t *l, ucontext_t *ucp, | |
251 | int error, register_t *rval) | 254 | int error, register_t *rval) | |
252 | { | 255 | { | |
253 | register_t *reg = (register_t *) &ucp->uc_mcontext; | 256 | register_t *reg = (register_t *) &ucp->uc_mcontext; | |
254 | 257 | |||
255 | reg[16] &= ~PSL_C; /* EFL */ | 258 | reg[16] &= ~PSL_C; /* EFL */ | |
256 | if (error > 0) { | 259 | if (error > 0) { | |
257 | rval[0] = error; | 260 | rval[0] = error; | |
258 | reg[16] |= PSL_C; /* EFL */ | 261 | reg[16] |= PSL_C; /* EFL */ | |
259 | } | 262 | } | |
260 | 263 | |||
261 | /* set return parameters */ | 264 | /* set return parameters */ | |
262 | reg[11] = rval[0]; /* EAX */ | 265 | reg[11] = rval[0]; /* EAX */ | |
263 | if (error == 0) | 266 | if (error == 0) | |
264 | reg[ 9] = rval[1]; /* EDX */ | 267 | reg[ 9] = rval[1]; /* EDX */ | |
265 | 268 | |||
266 | //dump_regs(reg); | 269 | //dump_regs(reg); | |
267 | } | 270 | } | |
268 | 271 | |||
269 | int | 272 | int | |
270 | md_syscall_check_opcode(ucontext_t *ucp) | 273 | md_syscall_check_opcode(ucontext_t *ucp) | |
271 | { | 274 | { | |
272 | uint32_t opcode; | 275 | uint32_t opcode; | |
273 | 276 | |||
274 | md_syscall_get_opcode(ucp, &opcode); | 277 | md_syscall_get_opcode(ucp, &opcode); | |
275 | 278 | |||
276 | switch (opcode) { | 279 | switch (opcode) { | |
277 | case 0xff0f: /* UD1 */ | 280 | case 0xff0f: /* UD1 */ | |
278 | case 0xff0b: /* UD2 */ | 281 | case 0xff0b: /* UD2 */ | |
279 | case 0x80cd: /* int $80 */ | 282 | case 0x80cd: /* int $80 */ | |
280 | case 0x340f: /* sysenter */ | 283 | case 0x340f: /* sysenter */ | |
281 | return 1; | 284 | return 1; | |
282 | default: | 285 | default: | |
283 | return 0; | 286 | return 0; | |
284 | } | 287 | } | |
285 | } | 288 | } | |
286 | 289 | |||
287 | void | 290 | void | |
288 | md_syscall_get_opcode(ucontext_t *ucp, uint32_t *opcode) | 291 | md_syscall_get_opcode(ucontext_t *ucp, uint32_t *opcode) | |
289 | { | 292 | { | |
290 | register_t *reg = (register_t *) &ucp->uc_mcontext; | 293 | register_t *reg = (register_t *) &ucp->uc_mcontext; | |
291 | // uint8_t *p8 = (uint8_t *) (reg[14]); | 294 | // uint8_t *p8 = (uint8_t *) (reg[14]); | |
292 | uint16_t *p16 = (uint16_t*) (reg[14]); | 295 | uint16_t *p16 = (uint16_t*) (reg[14]); | |
293 | 296 | |||
294 | switch (*p16) { | 297 | switch (*p16) { | |
295 | case 0xff0f: /* UD1 */ | 298 | case 0xff0f: /* UD1 */ | |
296 | case 0xff0b: /* UD2 */ | 299 | case 0xff0b: /* UD2 */ | |
297 | case 0x80cd: /* int $80 */ | 300 | case 0x80cd: /* int $80 */ | |
298 | case 0x340f: /* sysenter */ | 301 | case 0x340f: /* sysenter */ | |
299 | *opcode = *p16; | 302 | *opcode = *p16; | |
300 | break; | 303 | break; | |
301 | default: | 304 | default: | |
302 | *opcode = 0; | 305 | *opcode = 0; | |
303 | } | 306 | } | |
304 | } | 307 | } | |
305 | 308 | |||
306 | void | 309 | void | |
307 | md_syscall_inc_pc(ucontext_t *ucp, uint32_t opcode) | 310 | md_syscall_inc_pc(ucontext_t *ucp, uint32_t opcode) | |
308 | { | 311 | { | |
309 | uint *reg = (int *) &ucp->uc_mcontext; | 312 | uint *reg = (int *) &ucp->uc_mcontext; | |
310 | 313 | |||
311 | /* advance program counter */ | 314 | /* advance program counter */ | |
312 | switch (opcode) { | 315 | switch (opcode) { | |
313 | case 0xff0f: /* UD1 */ | 316 | case 0xff0f: /* UD1 */ | |
314 | case 0xff0b: /* UD2 */ | 317 | case 0xff0b: /* UD2 */ | |
315 | case 0x80cd: /* int $80 */ | 318 | case 0x80cd: /* int $80 */ | |
316 | case 0x340f: /* sysenter */ | 319 | case 0x340f: /* sysenter */ | |
317 | reg[14] += 2; /* EIP */ | 320 | reg[14] += 2; /* EIP */ | |
318 | break; | 321 | break; | |
319 | default: | 322 | default: | |
320 | panic("%s, unknown illegal instruction: opcode = %x\n", | 323 | panic("%s, unknown illegal instruction: opcode = %x\n", | |
321 | __func__, (uint32_t) opcode); | 324 | __func__, (uint32_t) opcode); | |
322 | } | 325 | } | |
323 | } | 326 | } | |
324 | 327 | |||
325 | void | 328 | void | |
326 | md_syscall_dec_pc(ucontext_t *ucp, uint32_t opcode) | 329 | md_syscall_dec_pc(ucontext_t *ucp, uint32_t opcode) | |
327 | { | 330 | { | |
328 | uint *reg = (int *) &ucp->uc_mcontext; | 331 | uint *reg = (int *) &ucp->uc_mcontext; | |
329 | 332 | |||
330 | switch (opcode) { | 333 | switch (opcode) { | |
331 | case 0xff0f: /* UD1 */ | 334 | case 0xff0f: /* UD1 */ | |
332 | case 0xff0b: /* UD2 */ | 335 | case 0xff0b: /* UD2 */ | |
333 | case 0x80cd: /* int $80 */ | 336 | case 0x80cd: /* int $80 */ | |
334 | case 0x340f: /* sysenter */ | 337 | case 0x340f: /* sysenter */ | |
335 | reg[14] -= 2; /* EIP */ | 338 | reg[14] -= 2; /* EIP */ | |
336 | break; | 339 | break; | |
337 | default: | 340 | default: | |
338 | panic("%s, unknown illegal instruction: opcode = %x\n", | 341 | panic("%s, unknown illegal instruction: opcode = %x\n", | |
339 | __func__, (uint32_t) opcode); | 342 | __func__, (uint32_t) opcode); | |
340 | } | 343 | } | |
341 | } | 344 | } | |
342 | 345 | |||
343 | 346 | |||
344 | #else | 347 | #else | |
345 | # error machdep functions not yet ported to this architecture | 348 | # error machdep functions not yet ported to this architecture | |
346 | #endif | 349 | #endif | |
347 | 350 |
--- src/sys/arch/usermode/usermode/thunk.c 2011/12/20 21:07:56 1.49
+++ src/sys/arch/usermode/usermode/thunk.c 2011/12/20 21:26:37 1.50
@@ -1,666 +1,692 @@ | @@ -1,666 +1,692 @@ | |||
1 | /* $NetBSD: thunk.c,v 1.49 2011/12/20 21:07:56 jmcneill Exp $ */ | 1 | /* $NetBSD: thunk.c,v 1.50 2011/12/20 21:26:37 jmcneill Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> | 4 | * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
15 | * | 15 | * | |
16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #include <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
30 | #ifdef __NetBSD__ | 30 | #ifdef __NetBSD__ | |
31 | __RCSID("$NetBSD: thunk.c,v 1.49 2011/12/20 21:07:56 jmcneill Exp $"); | 31 | __RCSID("$NetBSD: thunk.c,v 1.50 2011/12/20 21:26:37 jmcneill Exp $"); | |
32 | #endif | 32 | #endif | |
33 | 33 | |||
34 | #include <sys/types.h> | 34 | #include <sys/types.h> | |
35 | #include <sys/mman.h> | 35 | #include <sys/mman.h> | |
36 | #include <sys/reboot.h> | 36 | #include <sys/reboot.h> | |
37 | #include <sys/poll.h> | 37 | #include <sys/poll.h> | |
38 | #include <sys/utsname.h> | |||
39 | #include <sys/sysctl.h> | |||
38 | #include <machine/vmparam.h> | 40 | #include <machine/vmparam.h> | |
39 | 41 | |||
40 | #include <aio.h> | 42 | #include <aio.h> | |
41 | #include <assert.h> | 43 | #include <assert.h> | |
42 | #include <errno.h> | 44 | #include <errno.h> | |
43 | #include <fcntl.h> | 45 | #include <fcntl.h> | |
44 | #include <sched.h> | 46 | #include <sched.h> | |
45 | #include <stdarg.h> | 47 | #include <stdarg.h> | |
46 | #include <stdint.h> | 48 | #include <stdint.h> | |
47 | #include <stdio.h> | 49 | #include <stdio.h> | |
48 | #include <stdlib.h> | 50 | #include <stdlib.h> | |
49 | #include <signal.h> | 51 | #include <signal.h> | |
50 | #include <string.h> | 52 | #include <string.h> | |
51 | #include <termios.h> | 53 | #include <termios.h> | |
52 | #include <time.h> | 54 | #include <time.h> | |
53 | #include <ucontext.h> | 55 | #include <ucontext.h> | |
54 | #include <unistd.h> | 56 | #include <unistd.h> | |
55 | 57 | |||
56 | #include "../include/thunk.h" | 58 | #include "../include/thunk.h" | |
57 | 59 | |||
58 | #ifndef __arraycount | 60 | #ifndef __arraycount | |
59 | #define __arraycount(x) (sizeof((x)) / sizeof((x)[0])) | 61 | #define __arraycount(x) (sizeof((x)) / sizeof((x)[0])) | |
60 | #endif | 62 | #endif | |
61 | 63 | |||
62 | #ifndef MAP_ANON | 64 | #ifndef MAP_ANON | |
63 | #define MAP_ANON MAP_ANONYMOUS | 65 | #define MAP_ANON MAP_ANONYMOUS | |
64 | #endif | 66 | #endif | |
65 | 67 | |||
66 | extern int boothowto; | 68 | extern int boothowto; | |
67 | 69 | |||
68 | void | 70 | void | |
69 | dprintf_debug(const char *fmt, ...) | 71 | dprintf_debug(const char *fmt, ...) | |
70 | { | 72 | { | |
71 | if (boothowto & AB_DEBUG) { | 73 | if (boothowto & AB_DEBUG) { | |
72 | va_list ap; | 74 | va_list ap; | |
73 | 75 | |||
74 | va_start(ap, fmt); | 76 | va_start(ap, fmt); | |
75 | vfprintf(stderr, fmt, ap); | 77 | vfprintf(stderr, fmt, ap); | |
76 | va_end(ap); | 78 | va_end(ap); | |
77 | } | 79 | } | |
78 | } | 80 | } | |
79 | 81 | |||
80 | static void | 82 | static void | |
81 | thunk_to_timeval(const struct thunk_timeval *ttv, struct timeval *tv) | 83 | thunk_to_timeval(const struct thunk_timeval *ttv, struct timeval *tv) | |
82 | { | 84 | { | |
83 | tv->tv_sec = ttv->tv_sec; | 85 | tv->tv_sec = ttv->tv_sec; | |
84 | tv->tv_usec = ttv->tv_usec; | 86 | tv->tv_usec = ttv->tv_usec; | |
85 | } | 87 | } | |
86 | 88 | |||
87 | static void | 89 | static void | |
88 | thunk_from_timeval(const struct timeval *tv, struct thunk_timeval *ttv) | 90 | thunk_from_timeval(const struct timeval *tv, struct thunk_timeval *ttv) | |
89 | { | 91 | { | |
90 | ttv->tv_sec = tv->tv_sec; | 92 | ttv->tv_sec = tv->tv_sec; | |
91 | ttv->tv_usec = tv->tv_usec; | 93 | ttv->tv_usec = tv->tv_usec; | |
92 | } | 94 | } | |
93 | 95 | |||
94 | static void | 96 | static void | |
95 | thunk_to_itimerval(const struct thunk_itimerval *tit, struct itimerval *it) | 97 | thunk_to_itimerval(const struct thunk_itimerval *tit, struct itimerval *it) | |
96 | { | 98 | { | |
97 | thunk_to_timeval(&tit->it_interval, &it->it_interval); | 99 | thunk_to_timeval(&tit->it_interval, &it->it_interval); | |
98 | thunk_to_timeval(&tit->it_value, &it->it_value); | 100 | thunk_to_timeval(&tit->it_value, &it->it_value); | |
99 | } | 101 | } | |
100 | 102 | |||
101 | static void | 103 | static void | |
102 | thunk_from_itimerval(const struct itimerval *it, struct thunk_itimerval *tit) | 104 | thunk_from_itimerval(const struct itimerval *it, struct thunk_itimerval *tit) | |
103 | { | 105 | { | |
104 | thunk_from_timeval(&it->it_interval, &tit->it_interval); | 106 | thunk_from_timeval(&it->it_interval, &tit->it_interval); | |
105 | thunk_from_timeval(&it->it_value, &tit->it_value); | 107 | thunk_from_timeval(&it->it_value, &tit->it_value); | |
106 | } | 108 | } | |
107 | 109 | |||
108 | static void | 110 | static void | |
109 | thunk_to_termios(const struct thunk_termios *tt, struct termios *t) | 111 | thunk_to_termios(const struct thunk_termios *tt, struct termios *t) | |
110 | { | 112 | { | |
111 | int i; | 113 | int i; | |
112 | 114 | |||
113 | t->c_iflag = tt->c_iflag; | 115 | t->c_iflag = tt->c_iflag; | |
114 | t->c_oflag = tt->c_oflag; | 116 | t->c_oflag = tt->c_oflag; | |
115 | t->c_cflag = tt->c_cflag; | 117 | t->c_cflag = tt->c_cflag; | |
116 | t->c_lflag = tt->c_lflag; | 118 | t->c_lflag = tt->c_lflag; | |
117 | for (i = 0; i < __arraycount(t->c_cc); i++) | 119 | for (i = 0; i < __arraycount(t->c_cc); i++) | |
118 | t->c_cc[i] = tt->c_cc[i]; | 120 | t->c_cc[i] = tt->c_cc[i]; | |
119 | t->c_ispeed = tt->c_ispeed; | 121 | t->c_ispeed = tt->c_ispeed; | |
120 | t->c_ospeed= tt->c_ospeed; | 122 | t->c_ospeed= tt->c_ospeed; | |
121 | } | 123 | } | |
122 | 124 | |||
123 | static void | 125 | static void | |
124 | thunk_from_termios(const struct termios *t, struct thunk_termios *tt) | 126 | thunk_from_termios(const struct termios *t, struct thunk_termios *tt) | |
125 | { | 127 | { | |
126 | int i; | 128 | int i; | |
127 | 129 | |||
128 | tt->c_iflag = t->c_iflag; | 130 | tt->c_iflag = t->c_iflag; | |
129 | tt->c_oflag = t->c_oflag; | 131 | tt->c_oflag = t->c_oflag; | |
130 | tt->c_cflag = t->c_cflag; | 132 | tt->c_cflag = t->c_cflag; | |
131 | tt->c_lflag = t->c_lflag; | 133 | tt->c_lflag = t->c_lflag; | |
132 | for (i = 0; i < __arraycount(tt->c_cc); i++) | 134 | for (i = 0; i < __arraycount(tt->c_cc); i++) | |
133 | tt->c_cc[i] = t->c_cc[i]; | 135 | tt->c_cc[i] = t->c_cc[i]; | |
134 | tt->c_ispeed = t->c_ispeed; | 136 | tt->c_ispeed = t->c_ispeed; | |
135 | tt->c_ospeed= t->c_ospeed; | 137 | tt->c_ospeed= t->c_ospeed; | |
136 | } | 138 | } | |
137 | 139 | |||
138 | static int | 140 | static int | |
139 | thunk_to_native_prot(int prot) | 141 | thunk_to_native_prot(int prot) | |
140 | { | 142 | { | |
141 | int nprot = PROT_NONE; | 143 | int nprot = PROT_NONE; | |
142 | 144 | |||
143 | if (prot & THUNK_PROT_READ) | 145 | if (prot & THUNK_PROT_READ) | |
144 | nprot |= PROT_READ; | 146 | nprot |= PROT_READ; | |
145 | if (prot & THUNK_PROT_WRITE) | 147 | if (prot & THUNK_PROT_WRITE) | |
146 | nprot |= PROT_WRITE; | 148 | nprot |= PROT_WRITE; | |
147 | if (prot & THUNK_PROT_EXEC) | 149 | if (prot & THUNK_PROT_EXEC) | |
148 | nprot |= PROT_EXEC; | 150 | nprot |= PROT_EXEC; | |
149 | 151 | |||
150 | return nprot; | 152 | return nprot; | |
151 | } | 153 | } | |
152 | 154 | |||
153 | static int | 155 | static int | |
154 | thunk_to_native_mapflags(int flags) | 156 | thunk_to_native_mapflags(int flags) | |
155 | { | 157 | { | |
156 | int nflags = 0; | 158 | int nflags = 0; | |
157 | 159 | |||
158 | if (flags & THUNK_MAP_ANON) | 160 | if (flags & THUNK_MAP_ANON) | |
159 | nflags |= MAP_ANON; | 161 | nflags |= MAP_ANON; | |
160 | if (flags & THUNK_MAP_FIXED) | 162 | if (flags & THUNK_MAP_FIXED) | |
161 | nflags |= MAP_FIXED; | 163 | nflags |= MAP_FIXED; | |
162 | if (flags & THUNK_MAP_FILE) | 164 | if (flags & THUNK_MAP_FILE) | |
163 | nflags |= MAP_FILE; | 165 | nflags |= MAP_FILE; | |
164 | if (flags & THUNK_MAP_SHARED) | 166 | if (flags & THUNK_MAP_SHARED) | |
165 | nflags |= MAP_SHARED; | 167 | nflags |= MAP_SHARED; | |
166 | if (flags & THUNK_MAP_PRIVATE) | 168 | if (flags & THUNK_MAP_PRIVATE) | |
167 | nflags |= MAP_PRIVATE; | 169 | nflags |= MAP_PRIVATE; | |
168 | #ifndef MAP_NOSYSCALLS | 170 | #ifndef MAP_NOSYSCALLS | |
169 | #define MAP_NOSYSCALLS (1<<16) /* XXX alias for now XXX */ | 171 | #define MAP_NOSYSCALLS (1<<16) /* XXX alias for now XXX */ | |
170 | #endif | 172 | #endif | |
171 | #ifdef MAP_NOSYSCALLS | 173 | #ifdef MAP_NOSYSCALLS | |
172 | if (flags & THUNK_MAP_NOSYSCALLS) | 174 | if (flags & THUNK_MAP_NOSYSCALLS) | |
173 | nflags |= MAP_NOSYSCALLS; | 175 | nflags |= MAP_NOSYSCALLS; | |
174 | #endif | 176 | #endif | |
175 | 177 | |||
176 | return nflags; | 178 | return nflags; | |
177 | } | 179 | } | |
178 | 180 | |||
179 | int | 181 | int | |
180 | thunk_setitimer(int which, const struct thunk_itimerval *value, | 182 | thunk_setitimer(int which, const struct thunk_itimerval *value, | |
181 | struct thunk_itimerval *ovalue) | 183 | struct thunk_itimerval *ovalue) | |
182 | { | 184 | { | |
183 | struct itimerval it, oit; | 185 | struct itimerval it, oit; | |
184 | int error; | 186 | int error; | |
185 | 187 | |||
186 | thunk_to_itimerval(value, &it); | 188 | thunk_to_itimerval(value, &it); | |
187 | error = setitimer(which, &it, &oit); | 189 | error = setitimer(which, &it, &oit); | |
188 | if (error) | 190 | if (error) | |
189 | return error; | 191 | return error; | |
190 | if (ovalue) | 192 | if (ovalue) | |
191 | thunk_from_itimerval(&oit, ovalue); | 193 | thunk_from_itimerval(&oit, ovalue); | |
192 | 194 | |||
193 | return 0; | 195 | return 0; | |
194 | } | 196 | } | |
195 | 197 | |||
196 | int | 198 | int | |
197 | thunk_gettimeofday(struct thunk_timeval *tp, void *tzp) | 199 | thunk_gettimeofday(struct thunk_timeval *tp, void *tzp) | |
198 | { | 200 | { | |
199 | struct timeval tv; | 201 | struct timeval tv; | |
200 | int error; | 202 | int error; | |
201 | 203 | |||
202 | error = gettimeofday(&tv, tzp); | 204 | error = gettimeofday(&tv, tzp); | |
203 | if (error) | 205 | if (error) | |
204 | return error; | 206 | return error; | |
205 | 207 | |||
206 | thunk_from_timeval(&tv, tp); | 208 | thunk_from_timeval(&tv, tp); | |
207 | 209 | |||
208 | return 0; | 210 | return 0; | |
209 | } | 211 | } | |
210 | 212 | |||
211 | unsigned int | 213 | unsigned int | |
212 | thunk_getcounter(void) | 214 | thunk_getcounter(void) | |
213 | { | 215 | { | |
214 | struct timespec ts; | 216 | struct timespec ts; | |
215 | int error; | 217 | int error; | |
216 | 218 | |||
217 | error = clock_gettime(CLOCK_MONOTONIC, &ts); | 219 | error = clock_gettime(CLOCK_MONOTONIC, &ts); | |
218 | if (error) { | 220 | if (error) { | |
219 | perror("clock_gettime CLOCK_MONOTONIC"); | 221 | perror("clock_gettime CLOCK_MONOTONIC"); | |
220 | abort(); | 222 | abort(); | |
221 | } | 223 | } | |
222 | 224 | |||
223 | return (unsigned int)(ts.tv_nsec % 1000000000ULL); | 225 | return (unsigned int)(ts.tv_nsec % 1000000000ULL); | |
224 | } | 226 | } | |
225 | 227 | |||
226 | long | 228 | long | |
227 | thunk_clock_getres_monotonic(void) | 229 | thunk_clock_getres_monotonic(void) | |
228 | { | 230 | { | |
229 | struct timespec res; | 231 | struct timespec res; | |
230 | int error; | 232 | int error; | |
231 | 233 | |||
232 | error = clock_getres(CLOCK_MONOTONIC, &res); | 234 | error = clock_getres(CLOCK_MONOTONIC, &res); | |
233 | if (error) | 235 | if (error) | |
234 | return -1; | 236 | return -1; | |
235 | 237 | |||
236 | return (long)(res.tv_sec * 1000000000ULL + res.tv_nsec); | 238 | return (long)(res.tv_sec * 1000000000ULL + res.tv_nsec); | |
237 | } | 239 | } | |
238 | 240 | |||
239 | timer_t | 241 | timer_t | |
240 | thunk_timer_attach(void) | 242 | thunk_timer_attach(void) | |
241 | { | 243 | { | |
242 | timer_t timerid; | 244 | timer_t timerid; | |
243 | int error; | 245 | int error; | |
244 | 246 | |||
245 | error = timer_create(CLOCK_MONOTONIC, NULL, &timerid); | 247 | error = timer_create(CLOCK_MONOTONIC, NULL, &timerid); | |
246 | if (error) { | 248 | if (error) { | |
247 | perror("timer_create CLOCK_MONOTONIC"); | 249 | perror("timer_create CLOCK_MONOTONIC"); | |
248 | abort(); | 250 | abort(); | |
249 | } | 251 | } | |
250 | 252 | |||
251 | return timerid; | 253 | return timerid; | |
252 | } | 254 | } | |
253 | 255 | |||
254 | int | 256 | int | |
255 | thunk_timer_start(timer_t timerid, int freq) | 257 | thunk_timer_start(timer_t timerid, int freq) | |
256 | { | 258 | { | |
257 | struct itimerspec tim; | 259 | struct itimerspec tim; | |
258 | 260 | |||
259 | tim.it_interval.tv_sec = 0; | 261 | tim.it_interval.tv_sec = 0; | |
260 | tim.it_interval.tv_nsec = 1000000000 / freq; | 262 | tim.it_interval.tv_nsec = 1000000000 / freq; | |
261 | tim.it_value = tim.it_interval; | 263 | tim.it_value = tim.it_interval; | |
262 | 264 | |||
263 | return timer_settime(timerid, TIMER_RELTIME, &tim, NULL); | 265 | return timer_settime(timerid, TIMER_RELTIME, &tim, NULL); | |
264 | } | 266 | } | |
265 | 267 | |||
266 | int | 268 | int | |
267 | thunk_timer_getoverrun(timer_t timerid) | 269 | thunk_timer_getoverrun(timer_t timerid) | |
268 | { | 270 | { | |
269 | return timer_getoverrun(timerid); | 271 | return timer_getoverrun(timerid); | |
270 | } | 272 | } | |
271 | 273 | |||
272 | int | 274 | int | |
273 | thunk_usleep(useconds_t microseconds) | 275 | thunk_usleep(useconds_t microseconds) | |
274 | { | 276 | { | |
275 | return usleep(microseconds); | 277 | return usleep(microseconds); | |
276 | } | 278 | } | |
277 | 279 | |||
278 | void | 280 | void | |
279 | thunk_exit(int status) | 281 | thunk_exit(int status) | |
280 | { | 282 | { | |
281 | return exit(status); | 283 | return exit(status); | |
282 | } | 284 | } | |
283 | 285 | |||
284 | void | 286 | void | |
285 | thunk_abort(void) | 287 | thunk_abort(void) | |
286 | { | 288 | { | |
287 | abort(); | 289 | abort(); | |
288 | } | 290 | } | |
289 | 291 | |||
290 | int | 292 | int | |
291 | thunk_geterrno(void) | 293 | thunk_geterrno(void) | |
292 | { | 294 | { | |
293 | return errno; | 295 | return errno; | |
294 | } | 296 | } | |
295 | 297 | |||
296 | void | 298 | void | |
297 | thunk_seterrno(int nerrno) | 299 | thunk_seterrno(int nerrno) | |
298 | { | 300 | { | |
299 | errno = nerrno; | 301 | errno = nerrno; | |
300 | } | 302 | } | |
301 | 303 | |||
302 | int | 304 | int | |
303 | thunk_getcontext(ucontext_t *ucp) | 305 | thunk_getcontext(ucontext_t *ucp) | |
304 | { | 306 | { | |
305 | return getcontext(ucp); | 307 | return getcontext(ucp); | |
306 | } | 308 | } | |
307 | 309 | |||
308 | int | 310 | int | |
309 | thunk_setcontext(const ucontext_t *ucp) | 311 | thunk_setcontext(const ucontext_t *ucp) | |
310 | { | 312 | { | |
311 | return setcontext(ucp); | 313 | return setcontext(ucp); | |
312 | } | 314 | } | |
313 | 315 | |||
314 | void | 316 | void | |
315 | thunk_makecontext(ucontext_t *ucp, void (*func)(void), | 317 | thunk_makecontext(ucontext_t *ucp, void (*func)(void), | |
316 | int nargs, void *arg1, void *arg2, void *arg3) | 318 | int nargs, void *arg1, void *arg2, void *arg3) | |
317 | { | 319 | { | |
318 | switch (nargs) { | 320 | switch (nargs) { | |
319 | case 0: | 321 | case 0: | |
320 | makecontext(ucp, func, 0); | 322 | makecontext(ucp, func, 0); | |
321 | break; | 323 | break; | |
322 | case 1: | 324 | case 1: | |
323 | makecontext(ucp, func, 1, arg1); | 325 | makecontext(ucp, func, 1, arg1); | |
324 | break; | 326 | break; | |
325 | case 2: | 327 | case 2: | |
326 | makecontext(ucp, func, 2, arg1, arg2); | 328 | makecontext(ucp, func, 2, arg1, arg2); | |
327 | break; | 329 | break; | |
328 | case 3: | 330 | case 3: | |
329 | makecontext(ucp, func, 3, arg1, arg2, arg3); | 331 | makecontext(ucp, func, 3, arg1, arg2, arg3); | |
330 | break; | 332 | break; | |
331 | default: | 333 | default: | |
332 | printf("%s: nargs (%d) too big\n", __func__, nargs); | 334 | printf("%s: nargs (%d) too big\n", __func__, nargs); | |
333 | abort(); | 335 | abort(); | |
334 | } | 336 | } | |
335 | } | 337 | } | |
336 | 338 | |||
337 | int | 339 | int | |
338 | thunk_swapcontext(ucontext_t *oucp, ucontext_t *ucp) | 340 | thunk_swapcontext(ucontext_t *oucp, ucontext_t *ucp) | |
339 | { | 341 | { | |
340 | return swapcontext(oucp, ucp); | 342 | return swapcontext(oucp, ucp); | |
341 | } | 343 | } | |
342 | 344 | |||
343 | int | 345 | int | |
344 | thunk_tcgetattr(int fd, struct thunk_termios *tt) | 346 | thunk_tcgetattr(int fd, struct thunk_termios *tt) | |
345 | { | 347 | { | |
346 | struct termios t; | 348 | struct termios t; | |
347 | int error; | 349 | int error; | |
348 | 350 | |||
349 | error = tcgetattr(fd, &t); | 351 | error = tcgetattr(fd, &t); | |
350 | if (error) | 352 | if (error) | |
351 | return error; | 353 | return error; | |
352 | thunk_from_termios(&t, tt); | 354 | thunk_from_termios(&t, tt); | |
353 | return 0; | 355 | return 0; | |
354 | } | 356 | } | |
355 | 357 | |||
356 | int | 358 | int | |
357 | thunk_tcsetattr(int fd, int action, const struct thunk_termios *tt) | 359 | thunk_tcsetattr(int fd, int action, const struct thunk_termios *tt) | |
358 | { | 360 | { | |
359 | struct termios t; | 361 | struct termios t; | |
360 | 362 | |||
361 | thunk_to_termios(tt, &t); | 363 | thunk_to_termios(tt, &t); | |
362 | return tcsetattr(fd, action, &t); | 364 | return tcsetattr(fd, action, &t); | |
363 | } | 365 | } | |
364 | 366 | |||
365 | int | 367 | int | |
366 | thunk_set_stdin_sigio(int onoff) | 368 | thunk_set_stdin_sigio(int onoff) | |
367 | { | 369 | { | |
368 | int flags; | 370 | int flags; | |
369 | 371 | |||
370 | flags = fcntl(STDIN_FILENO, F_GETFL, 0); | 372 | flags = fcntl(STDIN_FILENO, F_GETFL, 0); | |
371 | 373 | |||
372 | if (onoff) | 374 | if (onoff) | |
373 | flags |= O_ASYNC; | 375 | flags |= O_ASYNC; | |
374 | else | 376 | else | |
375 | flags &= ~O_ASYNC; | 377 | flags &= ~O_ASYNC; | |
376 | 378 | |||
377 | return fcntl(STDIN_FILENO, F_SETFL, flags); | 379 | return fcntl(STDIN_FILENO, F_SETFL, flags); | |
378 | } | 380 | } | |
379 | 381 | |||
380 | int | 382 | int | |
381 | thunk_pollchar(void) | 383 | thunk_pollchar(void) | |
382 | { | 384 | { | |
383 | struct pollfd fds[1]; | 385 | struct pollfd fds[1]; | |
384 | uint8_t c; | 386 | uint8_t c; | |
385 | 387 | |||
386 | fds[0].fd = STDIN_FILENO; | 388 | fds[0].fd = STDIN_FILENO; | |
387 | fds[0].events = POLLIN; | 389 | fds[0].events = POLLIN; | |
388 | fds[0].revents = 0; | 390 | fds[0].revents = 0; | |
389 | 391 | |||
390 | if (poll(fds, __arraycount(fds), 0) > 0) { | 392 | if (poll(fds, __arraycount(fds), 0) > 0) { | |
391 | if (fds[0].revents & POLLIN) { | 393 | if (fds[0].revents & POLLIN) { | |
392 | if (read(STDIN_FILENO, &c, 1) != 1) | 394 | if (read(STDIN_FILENO, &c, 1) != 1) | |
393 | return EOF; | 395 | return EOF; | |
394 | return c; | 396 | return c; | |
395 | } | 397 | } | |
396 | } | 398 | } | |
397 | 399 | |||
398 | return EOF; | 400 | return EOF; | |
399 | } | 401 | } | |
400 | 402 | |||
401 | int | 403 | int | |
402 | thunk_getchar(void) | 404 | thunk_getchar(void) | |
403 | { | 405 | { | |
404 | return getchar(); | 406 | return getchar(); | |
405 | } | 407 | } | |
406 | 408 | |||
407 | void | 409 | void | |
408 | thunk_putchar(int c) | 410 | thunk_putchar(int c) | |
409 | { | 411 | { | |
410 | char wc = (char) c; | 412 | char wc = (char) c; | |
411 | write(1, &wc, 1); | 413 | write(1, &wc, 1); | |
412 | } | 414 | } | |
413 | 415 | |||
414 | int | 416 | int | |
415 | thunk_execv(const char *path, char * const argv[]) | 417 | thunk_execv(const char *path, char * const argv[]) | |
416 | { | 418 | { | |
417 | return execv(path, argv); | 419 | return execv(path, argv); | |
418 | } | 420 | } | |
419 | 421 | |||
420 | int | 422 | int | |
421 | thunk_open(const char *path, int flags, mode_t mode) | 423 | thunk_open(const char *path, int flags, mode_t mode) | |
422 | { | 424 | { | |
423 | return open(path, flags, mode); | 425 | return open(path, flags, mode); | |
424 | } | 426 | } | |
425 | 427 | |||
426 | int | 428 | int | |
427 | thunk_fstat_getsize(int fd, ssize_t *size, ssize_t *blksize) | 429 | thunk_fstat_getsize(int fd, ssize_t *size, ssize_t *blksize) | |
428 | { | 430 | { | |
429 | struct stat st; | 431 | struct stat st; | |
430 | int error; | 432 | int error; | |
431 | 433 | |||
432 | error = fstat(fd, &st); | 434 | error = fstat(fd, &st); | |
433 | if (error) | 435 | if (error) | |
434 | return -1; | 436 | return -1; | |
435 | 437 | |||
436 | if (size) | 438 | if (size) | |
437 | *size = st.st_size; | 439 | *size = st.st_size; | |
438 | if (blksize) | 440 | if (blksize) | |
439 | *blksize = st.st_blksize; | 441 | *blksize = st.st_blksize; | |
440 | 442 | |||
441 | return 0; | 443 | return 0; | |
442 | } | 444 | } | |
443 | 445 | |||
444 | ssize_t | 446 | ssize_t | |
445 | thunk_pread(int d, void *buf, size_t nbytes, off_t offset) | 447 | thunk_pread(int d, void *buf, size_t nbytes, off_t offset) | |
446 | { | 448 | { | |
447 | return pread(d, buf, nbytes, offset); | 449 | return pread(d, buf, nbytes, offset); | |
448 | } | 450 | } | |
449 | 451 | |||
450 | ssize_t | 452 | ssize_t | |
451 | thunk_pwrite(int d, const void *buf, size_t nbytes, off_t offset) | 453 | thunk_pwrite(int d, const void *buf, size_t nbytes, off_t offset) | |
452 | { | 454 | { | |
453 | return pwrite(d, buf, nbytes, offset); | 455 | return pwrite(d, buf, nbytes, offset); | |
454 | } | 456 | } | |
455 | 457 | |||
456 | ssize_t | 458 | ssize_t | |
457 | thunk_write(int d, const void *buf, size_t nbytes) | 459 | thunk_write(int d, const void *buf, size_t nbytes) | |
458 | { | 460 | { | |
459 | return write(d, buf, nbytes); | 461 | return write(d, buf, nbytes); | |
460 | } | 462 | } | |
461 | 463 | |||
462 | int | 464 | int | |
463 | thunk_fsync(int fd) | 465 | thunk_fsync(int fd) | |
464 | { | 466 | { | |
465 | return fsync(fd); | 467 | return fsync(fd); | |
466 | } | 468 | } | |
467 | 469 | |||
468 | int | 470 | int | |
469 | thunk_mkstemp(char *template) | 471 | thunk_mkstemp(char *template) | |
470 | { | 472 | { | |
471 | return mkstemp(template); | 473 | return mkstemp(template); | |
472 | } | 474 | } | |
473 | 475 | |||
474 | int | 476 | int | |
475 | thunk_unlink(const char *path) | 477 | thunk_unlink(const char *path) | |
476 | { | 478 | { | |
477 | return unlink(path); | 479 | return unlink(path); | |
478 | } | 480 | } | |
479 | 481 | |||
480 | int | 482 | int | |
481 | thunk_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) | 483 | thunk_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) | |
482 | { | 484 | { | |
483 | return sigaction(sig, act, oact); | 485 | return sigaction(sig, act, oact); | |
484 | } | 486 | } | |
485 | 487 | |||
486 | int | 488 | int | |
487 | thunk_sigaltstack(const stack_t *ss, stack_t *oss) | 489 | thunk_sigaltstack(const stack_t *ss, stack_t *oss) | |
488 | { | 490 | { | |
489 | return sigaltstack(ss, oss); | 491 | return sigaltstack(ss, oss); | |
490 | } | 492 | } | |
491 | 493 | |||
492 | void | 494 | void | |
493 | thunk_signal(int sig, void (*func)(int)) | 495 | thunk_signal(int sig, void (*func)(int)) | |
494 | { | 496 | { | |
495 | signal(sig, func); | 497 | signal(sig, func); | |
496 | } | 498 | } | |
497 | 499 | |||
498 | int | 500 | int | |
499 | thunk_sigblock(int sig) | 501 | thunk_sigblock(int sig) | |
500 | { | 502 | { | |
501 | sigset_t set; | 503 | sigset_t set; | |
502 | 504 | |||
503 | sigemptyset(&set); | 505 | sigemptyset(&set); | |
504 | sigaddset(&set, sig); | 506 | sigaddset(&set, sig); | |
505 | return sigprocmask(SIG_BLOCK, &set, NULL); | 507 | return sigprocmask(SIG_BLOCK, &set, NULL); | |
506 | } | 508 | } | |
507 | 509 | |||
508 | int | 510 | int | |
509 | thunk_sigunblock(int sig) | 511 | thunk_sigunblock(int sig) | |
510 | { | 512 | { | |
511 | sigset_t set; | 513 | sigset_t set; | |
512 | 514 | |||
513 | sigemptyset(&set); | 515 | sigemptyset(&set); | |
514 | sigaddset(&set, sig); | 516 | sigaddset(&set, sig); | |
515 | return sigprocmask(SIG_UNBLOCK, &set, NULL); | 517 | return sigprocmask(SIG_UNBLOCK, &set, NULL); | |
516 | } | 518 | } | |
517 | 519 | |||
518 | int | 520 | int | |
519 | thunk_sigemptyset(sigset_t *sa_mask) | 521 | thunk_sigemptyset(sigset_t *sa_mask) | |
520 | { | 522 | { | |
521 | return sigemptyset(sa_mask); | 523 | return sigemptyset(sa_mask); | |
522 | } | 524 | } | |
523 | 525 | |||
524 | 526 | |||
525 | void | 527 | void | |
526 | thunk_sigaddset(sigset_t *sa_mask, int sig) | 528 | thunk_sigaddset(sigset_t *sa_mask, int sig) | |
527 | { | 529 | { | |
528 | int retval; | 530 | int retval; | |
529 | retval = sigaddset(sa_mask, sig); | 531 | retval = sigaddset(sa_mask, sig); | |
530 | if (retval < 0) { | 532 | if (retval < 0) { | |
531 | perror("%s: bad signal added"); | 533 | perror("%s: bad signal added"); | |
532 | abort(); | 534 | abort(); | |
533 | } | 535 | } | |
534 | } | 536 | } | |
535 | 537 | |||
536 | int | 538 | int | |
537 | thunk_sigprocmask(int how, const sigset_t * set, sigset_t *oset) | 539 | thunk_sigprocmask(int how, const sigset_t * set, sigset_t *oset) | |
538 | { | 540 | { | |
539 | return sigprocmask(how, set, oset); | 541 | return sigprocmask(how, set, oset); | |
540 | } | 542 | } | |
541 | 543 | |||
542 | int | 544 | int | |
543 | thunk_atexit(void (*function)(void)) | 545 | thunk_atexit(void (*function)(void)) | |
544 | { | 546 | { | |
545 | return atexit(function); | 547 | return atexit(function); | |
546 | } | 548 | } | |
547 | 549 | |||
548 | int | 550 | int | |
549 | thunk_aio_read(struct aiocb *aiocbp) | 551 | thunk_aio_read(struct aiocb *aiocbp) | |
550 | { | 552 | { | |
551 | return aio_read(aiocbp); | 553 | return aio_read(aiocbp); | |
552 | } | 554 | } | |
553 | 555 | |||
554 | int | 556 | int | |
555 | thunk_aio_write(struct aiocb *aiocbp) | 557 | thunk_aio_write(struct aiocb *aiocbp) | |
556 | { | 558 | { | |
557 | return aio_write(aiocbp); | 559 | return aio_write(aiocbp); | |
558 | } | 560 | } | |
559 | 561 | |||
560 | int | 562 | int | |
561 | thunk_aio_error(const struct aiocb *aiocbp) | 563 | thunk_aio_error(const struct aiocb *aiocbp) | |
562 | { | 564 | { | |
563 | return aio_error(aiocbp); | 565 | return aio_error(aiocbp); | |
564 | } | 566 | } | |
565 | 567 | |||
566 | int | 568 | int | |
567 | thunk_aio_return(struct aiocb *aiocbp) | 569 | thunk_aio_return(struct aiocb *aiocbp) | |
568 | { | 570 | { | |
569 | return aio_return(aiocbp); | 571 | return aio_return(aiocbp); | |
570 | } | 572 | } | |
571 | 573 | |||
572 | void * | 574 | void * | |
573 | thunk_malloc(size_t len) | 575 | thunk_malloc(size_t len) | |
574 | { | 576 | { | |
575 | return malloc(len); | 577 | return malloc(len); | |
576 | } | 578 | } | |
577 | 579 | |||
578 | void | 580 | void | |
579 | thunk_free(void *addr) | 581 | thunk_free(void *addr) | |
580 | { | 582 | { | |
581 | free(addr); | 583 | free(addr); | |
582 | } | 584 | } | |
583 | 585 | |||
584 | void * | 586 | void * | |
585 | thunk_sbrk(intptr_t len) | 587 | thunk_sbrk(intptr_t len) | |
586 | { | 588 | { | |
587 | return sbrk(len); | 589 | return sbrk(len); | |
588 | } | 590 | } | |
589 | 591 | |||
590 | void * | 592 | void * | |
591 | thunk_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) | 593 | thunk_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) | |
592 | { | 594 | { | |
593 | int nflags, nprot; | 595 | int nflags, nprot; | |
594 | void *a; | 596 | void *a; | |
595 | 597 | |||
596 | nprot = thunk_to_native_prot(prot); | 598 | nprot = thunk_to_native_prot(prot); | |
597 | nflags = thunk_to_native_mapflags(flags); | 599 | nflags = thunk_to_native_mapflags(flags); | |
598 | 600 | |||
599 | a = mmap(addr, len, nprot, nflags, fd, offset); | 601 | a = mmap(addr, len, nprot, nflags, fd, offset); | |
600 | if (a == (void *)-1) | 602 | if (a == (void *)-1) | |
601 | perror("mmap"); | 603 | perror("mmap"); | |
602 | return a; | 604 | return a; | |
603 | } | 605 | } | |
604 | 606 | |||
605 | int | 607 | int | |
606 | thunk_munmap(void *addr, size_t len) | 608 | thunk_munmap(void *addr, size_t len) | |
607 | { | 609 | { | |
608 | return munmap(addr, len); | 610 | return munmap(addr, len); | |
609 | } | 611 | } | |
610 | 612 | |||
611 | int | 613 | int | |
612 | thunk_mprotect(void *addr, size_t len, int prot) | 614 | thunk_mprotect(void *addr, size_t len, int prot) | |
613 | { | 615 | { | |
614 | int nprot; | 616 | int nprot; | |
615 | 617 | |||
616 | nprot = thunk_to_native_prot(prot); | 618 | nprot = thunk_to_native_prot(prot); | |
617 | 619 | |||
618 | return mprotect(addr, len, nprot); | 620 | return mprotect(addr, len, nprot); | |
619 | } | 621 | } | |
620 | 622 | |||
621 | int | 623 | int | |
622 | thunk_posix_memalign(void **ptr, size_t alignment, size_t size) | 624 | thunk_posix_memalign(void **ptr, size_t alignment, size_t size) | |
623 | { | 625 | { | |
624 | return posix_memalign(ptr, alignment, size); | 626 | return posix_memalign(ptr, alignment, size); | |
625 | } | 627 | } | |
626 | 628 | |||
627 | char * | 629 | char * | |
628 | thunk_getenv(const char *name) | 630 | thunk_getenv(const char *name) | |
629 | { | 631 | { | |
630 | return getenv(name); | 632 | return getenv(name); | |
631 | } | 633 | } | |
632 | 634 | |||
633 | vaddr_t | 635 | vaddr_t | |
634 | thunk_get_vm_min_address(void) | 636 | thunk_get_vm_min_address(void) | |
635 | { | 637 | { | |
636 | return VM_MIN_ADDRESS; | 638 | return VM_MIN_ADDRESS; | |
637 | } | 639 | } | |
638 | 640 | |||
639 | int | 641 | int | |
640 | thunk_idle(void) | 642 | thunk_idle(void) | |
641 | { | 643 | { | |
642 | sigset_t sigmask; | 644 | sigset_t sigmask; | |
643 | 645 | |||
644 | sigemptyset(&sigmask); | 646 | sigemptyset(&sigmask); | |
645 | 647 | |||
646 | return sigsuspend(&sigmask); | 648 | return sigsuspend(&sigmask); | |
647 | } | 649 | } | |
648 | 650 | |||
649 | int | 651 | int | |
650 | thunk_getcpuinfo(char *cp, int *len) | 652 | thunk_getcpuinfo(char *cp, int *len) | |
651 | { | 653 | { | |
652 | ssize_t rlen; | 654 | ssize_t rlen; | |
653 | int fd; | 655 | int fd; | |
654 | 656 | |||
655 | fd = open("/proc/cpuinfo", O_RDONLY); | 657 | fd = open("/proc/cpuinfo", O_RDONLY); | |
656 | if (fd == -1) | 658 | if (fd == -1) | |
657 | return -1; | 659 | return -1; | |
658 | rlen = read(fd, cp, *len - 1); | 660 | rlen = read(fd, cp, *len - 1); | |
659 | close(fd); | 661 | close(fd); | |
660 | 662 | |||
661 | if (rlen == -1) | 663 | if (rlen == -1) | |
662 | return -1; | 664 | return -1; | |
663 | 665 | |||
664 | *len = rlen; | 666 | *len = rlen; | |
665 | return 0; | 667 | return 0; | |
666 | } | 668 | } | |
669 | ||||
670 | int | |||
671 | thunk_getmachine(char *buf, size_t buflen) | |||
672 | { | |||
673 | #ifdef __NetBSD__ | |||
674 | size_t len = buflen - 1; | |||
675 | ||||
676 | memset(buf, 0, buflen); | |||
677 | if (sysctlbyname("hw.machine_arch", buf, &len, NULL, 0) != 0) { | |||
678 | perror("sysctlbyname hw.machine_arch failed"); | |||
679 | return -1; | |||
680 | } | |||
681 | #else | |||
682 | struct utsname uts; | |||
683 | ||||
684 | if (uname(&uts) != 0) { | |||
685 | perror("uname failed"); | |||
686 | return -1; | |||
687 | } | |||
688 | ||||
689 | strlcpy(buf, uts.machine, buflen); | |||
690 | #endif | |||
691 | return 0; | |||
692 | } |