Tue Dec 20 21:26:37 2011 UTC ()
set machine_arch to that of the host


(jmcneill)
diff -r1.42 -r1.43 src/sys/arch/usermode/include/thunk.h
diff -r1.39 -r1.40 src/sys/arch/usermode/usermode/machdep.c
diff -r1.49 -r1.50 src/sys/arch/usermode/usermode/thunk.c

cvs diff -r1.42 -r1.43 src/sys/arch/usermode/include/thunk.h (switch to unified diff)

--- 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
39struct thunk_timeval { 39struct 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
44struct thunk_itimerval { 44struct 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
49struct thunk_termios { 49struct 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
71struct aiocb; 71struct aiocb;
72 72
73void dprintf_debug(const char *fmt, ...) __attribute__((__format__(__printf__, 1, 2))); 73void dprintf_debug(const char *fmt, ...) __attribute__((__format__(__printf__, 1, 2)));
74 74
75int thunk_setitimer(int, const struct thunk_itimerval *, struct thunk_itimerval *); 75int thunk_setitimer(int, const struct thunk_itimerval *, struct thunk_itimerval *);
76int thunk_gettimeofday(struct thunk_timeval *, void *); 76int thunk_gettimeofday(struct thunk_timeval *, void *);
77unsigned int thunk_getcounter(void); 77unsigned int thunk_getcounter(void);
78long thunk_clock_getres_monotonic(void); 78long thunk_clock_getres_monotonic(void);
79int thunk_usleep(useconds_t); 79int thunk_usleep(useconds_t);
80 80
81timer_t thunk_timer_attach(void); 81timer_t thunk_timer_attach(void);
82int thunk_timer_start(timer_t, int); 82int thunk_timer_start(timer_t, int);
83int thunk_timer_getoverrun(timer_t); 83int thunk_timer_getoverrun(timer_t);
84 84
85void thunk_exit(int); 85void thunk_exit(int);
86void thunk_abort(void); 86void thunk_abort(void);
87 87
88int thunk_geterrno(void); 88int thunk_geterrno(void);
89void thunk_seterrno(int err); 89void thunk_seterrno(int err);
90 90
91int thunk_getcontext(ucontext_t *); 91int thunk_getcontext(ucontext_t *);
92int thunk_setcontext(const ucontext_t *); 92int thunk_setcontext(const ucontext_t *);
93void thunk_makecontext(ucontext_t *ucp, void (*func)(void),  93void 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);
95int thunk_swapcontext(ucontext_t *, ucontext_t *); 95int thunk_swapcontext(ucontext_t *, ucontext_t *);
96 96
97int thunk_tcgetattr(int, struct thunk_termios *); 97int thunk_tcgetattr(int, struct thunk_termios *);
98int thunk_tcsetattr(int, int, const struct thunk_termios *); 98int thunk_tcsetattr(int, int, const struct thunk_termios *);
99 99
100int thunk_set_stdin_sigio(int); 100int thunk_set_stdin_sigio(int);
101int thunk_pollchar(void); 101int thunk_pollchar(void);
102int thunk_getchar(void); 102int thunk_getchar(void);
103void thunk_putchar(int); 103void thunk_putchar(int);
104 104
105int thunk_execv(const char *, char * const []); 105int thunk_execv(const char *, char * const []);
106 106
107int thunk_open(const char *, int, mode_t); 107int thunk_open(const char *, int, mode_t);
108int thunk_fstat_getsize(int, ssize_t *, ssize_t *); 108int thunk_fstat_getsize(int, ssize_t *, ssize_t *);
109ssize_t thunk_pread(int, void *, size_t, off_t); 109ssize_t thunk_pread(int, void *, size_t, off_t);
110ssize_t thunk_pwrite(int, const void *, size_t, off_t); 110ssize_t thunk_pwrite(int, const void *, size_t, off_t);
111ssize_t thunk_write(int, const void *, size_t); 111ssize_t thunk_write(int, const void *, size_t);
112int thunk_fsync(int); 112int thunk_fsync(int);
113int thunk_mkstemp(char *); 113int thunk_mkstemp(char *);
114int thunk_unlink(const char *); 114int thunk_unlink(const char *);
115 115
116int thunk_sigaction(int, const struct sigaction *, struct sigaction *); 116int thunk_sigaction(int, const struct sigaction *, struct sigaction *);
117int thunk_sigaltstack(const stack_t *, stack_t *); 117int thunk_sigaltstack(const stack_t *, stack_t *);
118void thunk_signal(int, void (*)(int)); 118void thunk_signal(int, void (*)(int));
119int thunk_sigblock(int); 119int thunk_sigblock(int);
120int thunk_sigunblock(int); 120int thunk_sigunblock(int);
121int thunk_sigemptyset(sigset_t *sa_mask); 121int thunk_sigemptyset(sigset_t *sa_mask);
122void thunk_sigaddset(sigset_t *sa_mask, int sig); 122void thunk_sigaddset(sigset_t *sa_mask, int sig);
123int thunk_sigprocmask(int how, const sigset_t * set, sigset_t *oset); 123int thunk_sigprocmask(int how, const sigset_t * set, sigset_t *oset);
124int thunk_atexit(void (*function)(void)); 124int thunk_atexit(void (*function)(void));
125 125
126int thunk_aio_read(struct aiocb *); 126int thunk_aio_read(struct aiocb *);
127int thunk_aio_write(struct aiocb *); 127int thunk_aio_write(struct aiocb *);
128int thunk_aio_error(const struct aiocb *); 128int thunk_aio_error(const struct aiocb *);
129int thunk_aio_return(struct aiocb *); 129int thunk_aio_return(struct aiocb *);
130 130
131void * thunk_malloc(size_t len); 131void * thunk_malloc(size_t len);
132void thunk_free(void *addr); 132void thunk_free(void *addr);
133void * thunk_sbrk(intptr_t len); 133void * thunk_sbrk(intptr_t len);
134void * thunk_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset); 134void * thunk_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
135int thunk_munmap(void *addr, size_t len); 135int thunk_munmap(void *addr, size_t len);
136int thunk_mprotect(void *addr, size_t len, int prot); 136int thunk_mprotect(void *addr, size_t len, int prot);
137int thunk_posix_memalign(void **, size_t, size_t); 137int thunk_posix_memalign(void **, size_t, size_t);
138 138
139int thunk_idle(void); 139int thunk_idle(void);
140 140
141char * thunk_getenv(const char *); 141char * thunk_getenv(const char *);
142vaddr_t thunk_get_vm_min_address(void); 142vaddr_t thunk_get_vm_min_address(void);
143 143
144int thunk_getcpuinfo(char *, int *); 144int thunk_getcpuinfo(char *, int *);
145 145
 146int thunk_getmachine(char *, size_t);
 147
146int thunk_sdl_init(unsigned int, unsigned int, unsigned short); 148int thunk_sdl_init(unsigned int, unsigned int, unsigned short);
147void * thunk_sdl_getfb(size_t); 149void * thunk_sdl_getfb(size_t);
148int thunk_sdl_getchar(void); 150int thunk_sdl_getchar(void);
149 151
150#endif /* !_ARCH_USERMODE_INCLUDE_THUNK_H */ 152#endif /* !_ARCH_USERMODE_INCLUDE_THUNK_H */

cvs diff -r1.39 -r1.40 src/sys/arch/usermode/usermode/machdep.c (switch to unified diff)

--- 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
53char machine[] = "usermode"; 54char machine[] = "usermode";
54char machine_arch[] = "usermode"; 55char machine_arch[_SYS_NMLN] = "";
55 56
56static char **saved_argv; 57static char **saved_argv;
57char *usermode_root_image_path = NULL; 58char *usermode_root_image_path = NULL;
58 59
59void main(int argc, char *argv[]); 60void main(int argc, char *argv[]);
60void usermode_reboot(void); 61void usermode_reboot(void);
61 62
62void 63void
63main(int argc, char *argv[]) 64main(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
110void 113void
111usermode_reboot(void) 114usermode_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
124void 127void
125setstatclockrate(int arg) 128setstatclockrate(int arg)
126{ 129{
127} 130}
128 131
129void 132void
130consinit(void) 133consinit(void)
131{ 134{
132 printf("NetBSD/usermode startup\n"); 135 printf("NetBSD/usermode startup\n");
133} 136}
134 137
135void 138void
136sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask) 139sendsig_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
151int 154int
152mm_md_physacc(paddr_t pa, vm_prot_t prog) 155mm_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
161static void dump_regs(register_t *reg);; 164static void dump_regs(register_t *reg);;
162 165
163static void 166static void
164dump_regs(register_t *reg) 167dump_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
178void 181void
179setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack) 182setregs(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
228void 231void
229md_syscall_get_syscallnumber(ucontext_t *ucp, uint32_t *code) 232md_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
235int 238int
236md_syscall_getargs(lwp_t *l, ucontext_t *ucp, int nargs, int argsize, 239md_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
249void 252void
250md_syscall_set_returnargs(lwp_t *l, ucontext_t *ucp, 253md_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
269int 272int
270md_syscall_check_opcode(ucontext_t *ucp) 273md_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
287void 290void
288md_syscall_get_opcode(ucontext_t *ucp, uint32_t *opcode) 291md_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
306void 309void
307md_syscall_inc_pc(ucontext_t *ucp, uint32_t opcode) 310md_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
325void 328void
326md_syscall_dec_pc(ucontext_t *ucp, uint32_t opcode) 329md_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

cvs diff -r1.49 -r1.50 src/sys/arch/usermode/usermode/thunk.c (switch to unified diff)

--- 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
66extern int boothowto; 68extern int boothowto;
67 69
68void 70void
69dprintf_debug(const char *fmt, ...) 71dprintf_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
80static void 82static void
81thunk_to_timeval(const struct thunk_timeval *ttv, struct timeval *tv) 83thunk_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
87static void 89static void
88thunk_from_timeval(const struct timeval *tv, struct thunk_timeval *ttv) 90thunk_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
94static void 96static void
95thunk_to_itimerval(const struct thunk_itimerval *tit, struct itimerval *it) 97thunk_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
101static void 103static void
102thunk_from_itimerval(const struct itimerval *it, struct thunk_itimerval *tit) 104thunk_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
108static void 110static void
109thunk_to_termios(const struct thunk_termios *tt, struct termios *t) 111thunk_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
123static void 125static void
124thunk_from_termios(const struct termios *t, struct thunk_termios *tt) 126thunk_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
138static int 140static int
139thunk_to_native_prot(int prot) 141thunk_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
153static int 155static int
154thunk_to_native_mapflags(int flags) 156thunk_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
179int 181int
180thunk_setitimer(int which, const struct thunk_itimerval *value, 182thunk_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
196int 198int
197thunk_gettimeofday(struct thunk_timeval *tp, void *tzp) 199thunk_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
211unsigned int 213unsigned int
212thunk_getcounter(void) 214thunk_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
226long 228long
227thunk_clock_getres_monotonic(void) 229thunk_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
239timer_t 241timer_t
240thunk_timer_attach(void) 242thunk_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
254int 256int
255thunk_timer_start(timer_t timerid, int freq) 257thunk_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
266int 268int
267thunk_timer_getoverrun(timer_t timerid) 269thunk_timer_getoverrun(timer_t timerid)
268{ 270{
269 return timer_getoverrun(timerid); 271 return timer_getoverrun(timerid);
270} 272}
271 273
272int 274int
273thunk_usleep(useconds_t microseconds) 275thunk_usleep(useconds_t microseconds)
274{ 276{
275 return usleep(microseconds); 277 return usleep(microseconds);
276} 278}
277 279
278void 280void
279thunk_exit(int status) 281thunk_exit(int status)
280{ 282{
281 return exit(status); 283 return exit(status);
282} 284}
283 285
284void 286void
285thunk_abort(void) 287thunk_abort(void)
286{ 288{
287 abort(); 289 abort();
288} 290}
289 291
290int 292int
291thunk_geterrno(void) 293thunk_geterrno(void)
292{ 294{
293 return errno; 295 return errno;
294} 296}
295 297
296void 298void
297thunk_seterrno(int nerrno) 299thunk_seterrno(int nerrno)
298{ 300{
299 errno = nerrno; 301 errno = nerrno;
300} 302}
301 303
302int 304int
303thunk_getcontext(ucontext_t *ucp) 305thunk_getcontext(ucontext_t *ucp)
304{ 306{
305 return getcontext(ucp); 307 return getcontext(ucp);
306} 308}
307 309
308int 310int
309thunk_setcontext(const ucontext_t *ucp) 311thunk_setcontext(const ucontext_t *ucp)
310{ 312{
311 return setcontext(ucp); 313 return setcontext(ucp);
312} 314}
313 315
314void 316void
315thunk_makecontext(ucontext_t *ucp, void (*func)(void),  317thunk_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
337int 339int
338thunk_swapcontext(ucontext_t *oucp, ucontext_t *ucp) 340thunk_swapcontext(ucontext_t *oucp, ucontext_t *ucp)
339{ 341{
340 return swapcontext(oucp, ucp); 342 return swapcontext(oucp, ucp);
341} 343}
342 344
343int 345int
344thunk_tcgetattr(int fd, struct thunk_termios *tt) 346thunk_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
356int 358int
357thunk_tcsetattr(int fd, int action, const struct thunk_termios *tt) 359thunk_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
365int 367int
366thunk_set_stdin_sigio(int onoff) 368thunk_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
380int 382int
381thunk_pollchar(void) 383thunk_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
401int 403int
402thunk_getchar(void) 404thunk_getchar(void)
403{ 405{
404 return getchar(); 406 return getchar();
405} 407}
406 408
407void 409void
408thunk_putchar(int c) 410thunk_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
414int 416int
415thunk_execv(const char *path, char * const argv[]) 417thunk_execv(const char *path, char * const argv[])
416{ 418{
417 return execv(path, argv); 419 return execv(path, argv);
418} 420}
419 421
420int 422int
421thunk_open(const char *path, int flags, mode_t mode) 423thunk_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
426int 428int
427thunk_fstat_getsize(int fd, ssize_t *size, ssize_t *blksize) 429thunk_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
444ssize_t 446ssize_t
445thunk_pread(int d, void *buf, size_t nbytes, off_t offset) 447thunk_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
450ssize_t 452ssize_t
451thunk_pwrite(int d, const void *buf, size_t nbytes, off_t offset) 453thunk_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
456ssize_t 458ssize_t
457thunk_write(int d, const void *buf, size_t nbytes) 459thunk_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
462int 464int
463thunk_fsync(int fd) 465thunk_fsync(int fd)
464{ 466{
465 return fsync(fd); 467 return fsync(fd);
466} 468}
467 469
468int 470int
469thunk_mkstemp(char *template) 471thunk_mkstemp(char *template)
470{ 472{
471 return mkstemp(template); 473 return mkstemp(template);
472} 474}
473 475
474int 476int
475thunk_unlink(const char *path) 477thunk_unlink(const char *path)
476{ 478{
477 return unlink(path); 479 return unlink(path);
478} 480}
479 481
480int 482int
481thunk_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) 483thunk_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
486int 488int
487thunk_sigaltstack(const stack_t *ss, stack_t *oss) 489thunk_sigaltstack(const stack_t *ss, stack_t *oss)
488{ 490{
489 return sigaltstack(ss, oss); 491 return sigaltstack(ss, oss);
490} 492}
491 493
492void 494void
493thunk_signal(int sig, void (*func)(int)) 495thunk_signal(int sig, void (*func)(int))
494{ 496{
495 signal(sig, func); 497 signal(sig, func);
496} 498}
497 499
498int 500int
499thunk_sigblock(int sig) 501thunk_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
508int 510int
509thunk_sigunblock(int sig) 511thunk_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
518int 520int
519thunk_sigemptyset(sigset_t *sa_mask) 521thunk_sigemptyset(sigset_t *sa_mask)
520{ 522{
521 return sigemptyset(sa_mask); 523 return sigemptyset(sa_mask);
522} 524}
523 525
524 526
525void 527void
526thunk_sigaddset(sigset_t *sa_mask, int sig) 528thunk_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
536int 538int
537thunk_sigprocmask(int how, const sigset_t * set, sigset_t *oset) 539thunk_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
542int 544int
543thunk_atexit(void (*function)(void)) 545thunk_atexit(void (*function)(void))
544{ 546{
545 return atexit(function); 547 return atexit(function);
546} 548}
547 549
548int 550int
549thunk_aio_read(struct aiocb *aiocbp) 551thunk_aio_read(struct aiocb *aiocbp)
550{ 552{
551 return aio_read(aiocbp); 553 return aio_read(aiocbp);
552} 554}
553 555
554int 556int
555thunk_aio_write(struct aiocb *aiocbp) 557thunk_aio_write(struct aiocb *aiocbp)
556{ 558{
557 return aio_write(aiocbp); 559 return aio_write(aiocbp);
558} 560}
559 561
560int 562int
561thunk_aio_error(const struct aiocb *aiocbp) 563thunk_aio_error(const struct aiocb *aiocbp)
562{ 564{
563 return aio_error(aiocbp); 565 return aio_error(aiocbp);
564} 566}
565 567
566int 568int
567thunk_aio_return(struct aiocb *aiocbp) 569thunk_aio_return(struct aiocb *aiocbp)
568{ 570{
569 return aio_return(aiocbp); 571 return aio_return(aiocbp);
570} 572}
571 573
572void * 574void *
573thunk_malloc(size_t len) 575thunk_malloc(size_t len)
574{ 576{
575 return malloc(len); 577 return malloc(len);
576} 578}
577 579
578void 580void
579thunk_free(void *addr) 581thunk_free(void *addr)
580{ 582{
581 free(addr); 583 free(addr);
582} 584}
583 585
584void * 586void *
585thunk_sbrk(intptr_t len) 587thunk_sbrk(intptr_t len)
586{ 588{
587 return sbrk(len); 589 return sbrk(len);
588} 590}
589 591
590void * 592void *
591thunk_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) 593thunk_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
605int 607int
606thunk_munmap(void *addr, size_t len) 608thunk_munmap(void *addr, size_t len)
607{ 609{
608 return munmap(addr, len); 610 return munmap(addr, len);
609} 611}
610 612
611int 613int
612thunk_mprotect(void *addr, size_t len, int prot) 614thunk_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
621int 623int
622thunk_posix_memalign(void **ptr, size_t alignment, size_t size) 624thunk_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
627char * 629char *
628thunk_getenv(const char *name) 630thunk_getenv(const char *name)
629{ 631{
630 return getenv(name); 632 return getenv(name);
631} 633}
632 634
633vaddr_t 635vaddr_t
634thunk_get_vm_min_address(void) 636thunk_get_vm_min_address(void)
635{ 637{
636 return VM_MIN_ADDRESS; 638 return VM_MIN_ADDRESS;
637} 639}
638 640
639int 641int
640thunk_idle(void) 642thunk_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
649int 651int
650thunk_getcpuinfo(char *cp, int *len) 652thunk_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
 670int
 671thunk_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}