]> git.saurik.com Git - apple/xnu.git/blob - bsd/kern/bsd_stubs.c
cc8e42431c09565efe290d42180f5e567a357053
[apple/xnu.git] / bsd / kern / bsd_stubs.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 #include <sys/time.h>
29 #include <kern/task.h>
30 #include <kern/thread.h>
31 #include <mach/mach_types.h>
32 #include <mach/vm_prot.h>
33 #include <vm/vm_kern.h>
34 #include <vm/vm_map.h>
35 #include <sys/systm.h>
36 #include <sys/conf.h>
37 #include <sys/proc_internal.h>
38 #include <sys/buf.h> /* for SET */
39 #include <sys/user.h>
40 #include <sys/sysent.h>
41 #include <sys/sysproto.h>
42
43 /* Just to satisfy pstat command */
44 int dmmin, dmmax, dmtext;
45
46 vm_offset_t
47 kmem_mb_alloc(vm_map_t mbmap, int size)
48 {
49 vm_offset_t addr;
50 if (kernel_memory_allocate(mbmap, &addr, size,
51 0,
52 KMA_NOPAGEWAIT|KMA_KOBJECT|KMA_LOMEM) == KERN_SUCCESS)
53 return(addr);
54 else
55 return(0);
56
57 }
58
59 /*
60 * XXX this function only exists to be exported and do nothing.
61 */
62 void
63 pcb_synch(void)
64 {
65 }
66
67 struct proc *
68 current_proc(void)
69 {
70 /* Never returns a NULL */
71 struct uthread * ut;
72 struct proc *p;
73 thread_t thr_act = current_thread();
74
75 ut = (struct uthread *)get_bsdthread_info(thr_act);
76 if (ut && (ut->uu_flag & UT_VFORK) && ut->uu_proc) {
77 p = ut->uu_proc;
78 if ((p->p_flag & P_INVFORK) == 0)
79 panic("returning child proc not under vfork");
80 if (p->p_vforkact != (void *)thr_act)
81 panic("returning child proc which is not cur_act");
82 return(p);
83 }
84
85 p = (struct proc *)get_bsdtask_info(current_task());
86
87 if (p == NULL)
88 return (kernproc);
89
90 return (p);
91 }
92
93 /* Device switch add delete routines */
94
95 extern int nblkdev, nchrdev;
96
97 struct bdevsw nobdev = NO_BDEVICE;
98 struct cdevsw nocdev = NO_CDEVICE;
99 /*
100 * if index is -1, return a free slot if avaliable
101 * else see whether the index is free
102 * return the major number that is free else -1
103 *
104 */
105 int
106 bdevsw_isfree(int index)
107 {
108 struct bdevsw *devsw;
109 if (index == -1) {
110 devsw = bdevsw;
111 for(index=0; index < nblkdev; index++, devsw++) {
112 if(memcmp((char *)devsw,
113 (char *)&nobdev,
114 sizeof(struct bdevsw)) == 0)
115 break;
116 }
117 } else {
118 /* NB: Not used below unless index is in range */
119 devsw = &bdevsw[index];
120 }
121
122 if ((index < 0) || (index >= nblkdev) ||
123 (memcmp((char *)devsw,
124 (char *)&nobdev,
125 sizeof(struct bdevsw)) != 0)) {
126 return(-1);
127 }
128 return(index);
129 }
130
131 /*
132 * if index is -1, find a free slot to add
133 * else see whether the slot is free
134 * return the major number that is used else -1
135 */
136 int
137 bdevsw_add(int index, struct bdevsw * bsw)
138 {
139 struct bdevsw *devsw;
140
141 if (index == -1) {
142 devsw = &bdevsw[1]; /* Start at slot 1 - this is a hack to fix the index=1 hack */
143 /* yes, start at 1 to avoid collision with volfs (Radar 2842228) */
144 for(index=1; index < nblkdev; index++, devsw++) {
145 if(memcmp((char *)devsw,
146 (char *)&nobdev,
147 sizeof(struct bdevsw)) == 0)
148 break;
149 }
150 }
151 devsw = &bdevsw[index];
152 if ((index < 0) || (index >= nblkdev) ||
153 (memcmp((char *)devsw,
154 (char *)&nobdev,
155 sizeof(struct bdevsw)) != 0)) {
156 return(-1);
157 }
158 bdevsw[index] = *bsw;
159 return(index);
160 }
161 /*
162 * if the slot has the same bsw, then remove
163 * else -1
164 */
165 int
166 bdevsw_remove(int index, struct bdevsw * bsw)
167 {
168 struct bdevsw *devsw;
169
170 devsw = &bdevsw[index];
171 if ((index < 0) || (index >= nblkdev) ||
172 (memcmp((char *)devsw,
173 (char *)bsw,
174 sizeof(struct bdevsw)) != 0)) {
175 return(-1);
176 }
177 bdevsw[index] = nobdev;
178 return(index);
179 }
180
181 /*
182 * if index is -1, return a free slot if avaliable
183 * else see whether the index is free
184 * return the major number that is free else -1
185 */
186 int
187 cdevsw_isfree(int index)
188 {
189 struct cdevsw *devsw;
190
191 if (index == -1) {
192 devsw = cdevsw;
193 for(index=0; index < nchrdev; index++, devsw++) {
194 if(memcmp((char *)devsw,
195 (char *)&nocdev,
196 sizeof(struct cdevsw)) == 0)
197 break;
198 }
199 }
200 devsw = &cdevsw[index];
201 if ((index < 0) || (index >= nchrdev) ||
202 (memcmp((char *)devsw,
203 (char *)&nocdev,
204 sizeof(struct cdevsw)) != 0)) {
205 return(-1);
206 }
207 return(index);
208 }
209
210 /*
211 * if index is -1, find a free slot to add
212 * else see whether the slot is free
213 * return the major number that is used else -1
214 */
215 int
216 cdevsw_add(int index, struct cdevsw * csw)
217 {
218 struct cdevsw *devsw;
219
220 if (index == -1) {
221 devsw = cdevsw;
222 for(index=0; index < nchrdev; index++, devsw++) {
223 if(memcmp((char *)devsw,
224 (char *)&nocdev,
225 sizeof(struct cdevsw)) == 0)
226 break;
227 }
228 }
229 devsw = &cdevsw[index];
230 if ((index < 0) || (index >= nchrdev) ||
231 (memcmp((char *)devsw,
232 (char *)&nocdev,
233 sizeof(struct cdevsw)) != 0)) {
234 return(-1);
235 }
236 cdevsw[index] = *csw;
237 return(index);
238 }
239 /*
240 * if the index has the same bsw, then remove
241 * else -1
242 */
243 int
244 cdevsw_remove(int index, struct cdevsw * csw)
245 {
246 struct cdevsw *devsw;
247
248 devsw = &cdevsw[index];
249 if ((index < 0) || (index >= nchrdev) ||
250 (memcmp((char *)devsw,
251 (char *)csw,
252 sizeof(struct cdevsw)) != 0)) {
253 return(-1);
254 }
255 cdevsw[index] = nocdev;
256 return(index);
257 }
258
259 static int
260 cdev_set_bdev(int cdev, int bdev)
261 {
262 extern int chrtoblk_add(int cdev, int bdev);
263
264 return (chrtoblk_set(cdev, bdev));
265 }
266
267 int
268 cdevsw_add_with_bdev(int index, struct cdevsw * csw, int bdev)
269 {
270 index = cdevsw_add(index, csw);
271 if (index < 0) {
272 return (index);
273 }
274 if (cdev_set_bdev(index, bdev) < 0) {
275 cdevsw_remove(index, csw);
276 return (-1);
277 }
278 return (index);
279 }
280
281 issingleuser(void)
282 {
283 char namep[16];
284
285
286 if (PE_parse_boot_arg("-s", namep)) {
287 return(1);
288 } else {
289 return(0);
290 }
291 }
292
293 void *
294 tbeproc(void *procp)
295 {
296 struct proc *p = procp;
297
298 if (p)
299 SET(p->p_flag, P_TBE);
300 return;
301 }
302
303
304 /*
305 * WARNING - this is a temporary workaround for binary compatibility issues
306 * with anti-piracy software that relies on patching ptrace (3928003).
307 * This KPI will be removed in the system release after Tiger.
308 */
309 uintptr_t temp_patch_ptrace(uintptr_t new_ptrace)
310 {
311 struct sysent * callp;
312 sy_call_t * old_ptrace;
313 #ifndef __ppc__
314 boolean_t funnel_state;
315 #endif
316
317 if (new_ptrace == 0)
318 return(0);
319
320 #ifdef __ppc__
321 enter_funnel_section(kernel_flock);
322 #else
323 funnel_state = thread_funnel_set(kernel_flock, TRUE);
324 #endif
325 callp = &sysent[26];
326 old_ptrace = callp->sy_call;
327
328 /* only allow one patcher of ptrace */
329 if (old_ptrace == (sy_call_t *) ptrace) {
330 callp->sy_call = (sy_call_t *) new_ptrace;
331 }
332 else {
333 old_ptrace = NULL;
334 }
335 #ifdef __ppc__
336 exit_funnel_section( );
337 #else
338 (void)thread_funnel_set(kernel_flock, funnel_state);
339 #endif
340
341 return((uintptr_t)old_ptrace);
342 }
343
344 void temp_unpatch_ptrace(void)
345 {
346 struct sysent * callp;
347 #ifndef __ppc__
348 boolean_t funnel_state;
349 #endif
350
351 #ifdef __ppc__
352 enter_funnel_section(kernel_flock);
353 #else
354 funnel_state = thread_funnel_set(kernel_flock, TRUE);
355 #endif
356 callp = &sysent[26];
357 callp->sy_call = (sy_call_t *) ptrace;
358 #ifdef __ppc__
359 exit_funnel_section( );
360 #else
361 (void)thread_funnel_set(kernel_flock, funnel_state);
362 #endif
363
364 return;
365 }