1/*-
2 * Copyright (c) 2016 Antti Kantee.  All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
14 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26/*
27 * Syscall wrappers for memory management routines (not provided by
28 * standard rump kernels).  These are handwritten libc-level wrappers.
29 * We should maybe try to autogenerate them some fine day ...
30 */
31
32#define mmap _mmap
33
34#include <sys/cdefs.h>
35
36#include <sys/param.h>
37#include <sys/mman.h>
38#include <sys/syscall.h>
39#include <sys/syscallargs.h>
40
41#include <errno.h>
42#include <string.h>
43
44/* XXX */
45int	rump_syscall(int, void *, size_t, register_t *);
46
47#if     BYTE_ORDER == BIG_ENDIAN
48#define SPARG(p,k)      ((p)->k.be.datum)
49#else /* LITTLE_ENDIAN, I hope dearly */
50#define SPARG(p,k)      ((p)->k.le.datum)
51#endif
52
53void *
54mmap(void *addr, size_t len, int prot, int flags, int fd, off_t pos)
55{
56	struct sys_mmap_args callarg;
57	register_t retval[2];
58	int error;
59
60	memset(&callarg, 0, sizeof(callarg));
61	SPARG(&callarg, addr) = addr;
62	SPARG(&callarg, len) = len;
63	SPARG(&callarg, prot) = prot;
64	SPARG(&callarg, flags) = flags;
65	SPARG(&callarg, fd) = fd;
66	SPARG(&callarg, pos) = pos;
67
68	error = rump_syscall(SYS_mmap, &callarg, sizeof(callarg), retval);
69	errno = error;
70	if (error == 0) {
71		return (void *)retval[0];
72	}
73	return MAP_FAILED;
74}
75#undef mmap
76__weak_alias(mmap,_mmap);
77
78int
79munmap(void *addr, size_t len)
80{
81	struct sys_munmap_args callarg;
82	register_t retval[2];
83	int error;
84
85	memset(&callarg, 0, sizeof(callarg));
86	SPARG(&callarg, addr) = addr;
87	SPARG(&callarg, len) = len;
88
89	error = rump_syscall(SYS_munmap, &callarg, sizeof(callarg), retval);
90	errno = error;
91	if (error == 0) {
92		return (int)retval[0];
93	}
94	return -1;
95}
96
97int _sys___msync13(void *, size_t, int);
98int
99_sys___msync13(void *addr, size_t len, int flags)
100{
101	struct sys___msync13_args callarg;
102	register_t retval[2];
103	int error;
104
105	memset(&callarg, 0, sizeof(callarg));
106	SPARG(&callarg, addr) = addr;
107	SPARG(&callarg, len) = len;
108
109	error = rump_syscall(SYS___msync13, &callarg, sizeof(callarg), retval);
110	errno = error;
111	if (error == 0) {
112		return 0;
113	}
114	return -1;
115}
116__weak_alias(___msync13,_sys___msync13);
117__weak_alias(__msync13,_sys___msync13);
118
119int
120mincore(void *addr, size_t len, char *vec)
121{
122	struct sys_mincore_args callarg;
123	register_t retval[2];
124	int error;
125
126	memset(&callarg, 0, sizeof(callarg));
127	SPARG(&callarg, addr) = addr;
128	SPARG(&callarg, len) = len;
129	SPARG(&callarg, vec) = vec;
130
131	error = rump_syscall(SYS_mincore, &callarg, sizeof(callarg), retval);
132	errno = error;
133	if (error == 0) {
134		return 0;
135	}
136	return -1;
137}
138
139int
140mprotect(void *addr, size_t len, int prot)
141{
142	struct sys_mprotect_args callarg;
143	register_t retval[2];
144	int error;
145
146	memset(&callarg, 0, sizeof(callarg));
147	SPARG(&callarg, addr) = addr;
148	SPARG(&callarg, len) = len;
149	SPARG(&callarg, prot) = prot;
150
151	error = rump_syscall(SYS_mprotect, &callarg, sizeof(callarg), retval);
152	errno = error;
153	if (error == 0) {
154		return 0;
155	}
156	return -1;
157}
158
159/*
160 * We "know" that the following are stubs also in the kernel.  Risk of
161 * them going out-of-sync is quite minimal ...
162 */
163
164int
165madvise(void *addr, size_t len, int adv)
166{
167
168	return 0;
169}
170__strong_alias(minherit,madvise);
171__strong_alias(mlock,madvise);
172__strong_alias(mlockall,madvise);
173__strong_alias(munlock,madvise);
174__strong_alias(munlockall,madvise);
175