Print this page
sysinfo emulation
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/brand/solaris10/s10_brand/common/s10_brand.c
+++ new/usr/src/lib/brand/solaris10/s10_brand/common/s10_brand.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 #include <errno.h>
27 27 #include <fcntl.h>
28 28 #include <stdio.h>
29 29 #include <stdlib.h>
|
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
30 30 #include <strings.h>
31 31 #include <unistd.h>
32 32 #include <sys/auxv.h>
33 33 #include <sys/bitmap.h>
34 34 #include <sys/brand.h>
35 35 #include <sys/inttypes.h>
36 36 #include <sys/lwp.h>
37 37 #include <sys/syscall.h>
38 38 #include <sys/systm.h>
39 39 #include <sys/utsname.h>
40 +#include <sys/systeminfo.h>
40 41 #include <sys/zone.h>
41 42 #include <sys/stat.h>
42 43 #include <sys/mntent.h>
43 44 #include <sys/ctfs.h>
44 45 #include <sys/priv.h>
45 46 #include <sys/acctctl.h>
46 47 #include <libgen.h>
47 48
48 49 #include <s10_brand.h>
49 50 #include <s10_misc.h>
50 51
51 52 /*
52 53 * Principles of emulation 101.
53 54 *
54 55 *
55 56 * *** Setting errno
56 57 *
57 58 * Just don't do it. This emulation library is loaded onto a
58 59 * seperate link map from the application who's address space we're
59 60 * running in. We have our own private copy of libc, so there for,
60 61 * the errno value accessible from here is is also private and changing
61 62 * it will not affect any errno value that the processes who's address
62 63 * space we are running in will see. To return an error condition we
63 64 * should return the negated errno value we'd like the system to return.
64 65 * For more information about this see the comment in s10_handler().
65 66 * Basically, when we return to the caller that initiated the system
66 67 * call it's their responsibility to set errno.
67 68 *
68 69 *
69 70 * *** Recursion Considerations
70 71 *
71 72 * When emulating system calls we need to be very careful about what
72 73 * library calls we invoke. Library calls should be kept to a minimum.
73 74 * One issue is that library calls can invoke system calls, so if we're
74 75 * emulating a system call and we invoke a library call that depends on
75 76 * that system call we will probably enter a recursive loop, which would
76 77 * be bad.
77 78 *
78 79 *
79 80 * *** Return Values.
80 81 *
81 82 * When declaring new syscall emulation functions, it is very important
82 83 * to to set the proper RV_* flags in the s10_sysent_table. Upon failure,
83 84 * syscall emulation fuctions should return an errno value. Upon success
84 85 * syscall emulation functions should return 0 and set the sysret_t return
85 86 * value parameters accordingly.
86 87 *
87 88 *
88 89 * *** Agent lwp considerations
89 90 *
90 91 * It is currently impossible to do any emulation for these system call
91 92 * when they are being invoked on behalf of an agent lwp. To understand why
92 93 * it's impossible you have to understand how agent lwp syscalls work.
93 94 *
94 95 * The agent lwp syscall process works as follows:
95 96 * 1 The controlling process stops the target.
96 97 * 2 The controlling process injects an agent lwp which is also stopped.
97 98 * This agent lwp assumes the userland stack and register values
98 99 * of another stopped lwp in the current process.
99 100 * 3 The controlling process configures the agent lwp to start
100 101 * executing the requested system call.
101 102 * 4 The controlling process configure /proc to stop the agent lwp when
102 103 * it enters the requested system call.
103 104 * 5 The controlling processes allows the agent lwp to start executing.
104 105 * 6 The agent lwp traps into the kernel to perform the requested system
105 106 * call and immediately stop.
106 107 * 7 The controlling process copies all the arguments for the requested
107 108 * system call onto the agent lwp's stack.
108 109 * 8 The controlling process configures /proc to stop the agent lwp
109 110 * when it completes the requested system call.
110 111 * 9 The controlling processes allows the agent lwp to start executing.
111 112 * 10 The agent lwp executes the system call and then stop before returning
112 113 * to userland.
113 114 * 11 The controlling process copies the return value and return arguments
114 115 * back from the agent lwps stack.
115 116 * 12 The controlling process destroys the agent lwp and restarts
116 117 * the target process.
117 118 *
118 119 * The fundamental problem is that when the agent executes the request
119 120 * system call in step 5, if we're emulating that system call then the
120 121 * lwp is redirected back to our emulation layer without blocking
121 122 * in the kernel. But our emulation layer can't access the arguments
122 123 * for the system call because they haven't been copied to the stack
123 124 * yet and they still only exist in the controlling processes address
124 125 * space. This prevents us from being able to do any emulation of
125 126 * agent lwp system calls. Hence, currently our brand trap interposition
126 127 * callback (s10_brand_syscall_callback_common) will detect if a system
127 128 * call is being made by an agent lwp, and if this is the case it will
128 129 * never redirect the system call to this emulation library.
129 130 *
130 131 * In the future, if this proves to be a problem the the easiest solution
131 132 * would probably be to replace the branded versions of these application
132 133 * with their native counterparts. Ie, truss, plimit, and pfiles could be
133 134 * replace with wrapper scripts that execute the native versions of these
134 135 * applications. In the case of plimit and pfiles this should be pretty
135 136 * strait forward. Truss would probably be more tricky since it can
136 137 * execute applications which would be branded applications, so in that
137 138 * case it might be necessary to create a loadable library which could
138 139 * be LD_PRELOADed into truss and this library would interpose on the
139 140 * exec() system call to allow truss to correctly execute branded
140 141 * processes. It should be pointed out that this solution could work
141 142 * because "native agent lwps" (ie, agent lwps created by native
142 143 * processes) can be treated differently from "branded aged lwps" (ie,
143 144 * agent lwps created by branded processes), since native agent lwps
144 145 * would presumably be making native system calls and hence not need
145 146 * any interposition.
146 147 *
147 148 *
148 149 * *** s10 brand emulation scope considerations
149 150 *
150 151 * One of the differences between the lx brand and the s8 and s9
151 152 * brands, is that the s8 and s9 brands only interpose on syscalls
152 153 * that need some kind of emulation, where as the lx brand interposes
153 154 * on _all_ system calls. Lx branded system calls that don't need
154 155 * any emulation are then redirected back to the kernel from the
155 156 * userland library via the IN_KERNEL_SYSCALL macro. The lx-syscall
156 157 * dtrace provider depends on this behavior.
157 158 *
158 159 */
159 160
160 161 static zoneid_t zoneid;
161 162 static boolean_t ipshared;
162 163 static boolean_t emul_global_zone = B_FALSE;
163 164 static int emul_vers;
164 165 pid_t zone_init_pid;
165 166
166 167 #define EMULATE(cb, args) { (sysent_cb_t)(cb), (args) }
167 168 #define NOSYS EMULATE(s10_unimpl, (0 | RV_DEFAULT))
168 169
169 170 typedef long (*sysent_cb_t)();
170 171 typedef struct s10_sysent_table {
171 172 sysent_cb_t st_callc;
172 173 uintptr_t st_args;
173 174 } s10_sysent_table_t;
174 175 s10_sysent_table_t s10_sysent_table[];
175 176
176 177 #define S10_UTS_RELEASE "5.10"
177 178 #define S10_UTS_VERSION "Generic_Virtual"
178 179
179 180 /*LINTED: static unused*/
180 181 static volatile int s10_abort_err;
181 182 /*LINTED: static unused*/
182 183 static volatile const char *s10_abort_msg;
183 184 /*LINTED: static unused*/
184 185 static volatile const char *s10_abort_file;
185 186 /*LINTED: static unused*/
186 187 static volatile int s10_abort_line;
187 188
188 189 extern int errno;
189 190
190 191 /*ARGSUSED*/
191 192 void
192 193 _s10_abort(int err, const char *msg, const char *file, int line)
193 194 {
194 195 sysret_t rval;
195 196
196 197 /* Save the error message into convenient globals */
197 198 s10_abort_err = err;
198 199 s10_abort_msg = msg;
199 200 s10_abort_file = file;
200 201 s10_abort_line = line;
201 202
202 203 /* kill ourselves */
203 204 abort();
204 205
205 206 /* If abort() didn't work, try something stronger. */
206 207 (void) __systemcall(&rval, SYS_lwp_kill + 1024, _lwp_self(), SIGKILL);
207 208 }
208 209
209 210 static int
210 211 s10_uucopy(const void *from, void *to, size_t size)
211 212 {
212 213 sysret_t rval;
213 214 int err;
214 215
215 216 err = __systemcall(&rval, SYS_uucopy + 1024, from, to, size);
216 217 if (err == 0)
217 218 return (0);
218 219 return (EFAULT);
219 220 }
220 221
221 222 /*
222 223 * ATTENTION: uucopystr() does NOT ensure that string are null terminated!
223 224 */
224 225 static int
225 226 s10_uucopystr(const void *from, void *to, size_t size)
226 227 {
227 228 sysret_t rval;
228 229 int err;
229 230
230 231 err = __systemcall(&rval, SYS_uucopystr + 1024, from, to, size);
231 232 if (err == 0)
232 233 return (0);
233 234 return (EFAULT);
234 235 }
235 236
236 237 /*
237 238 * Figures out the PID of init for the zone. Also returns a boolean
238 239 * indicating whether this process currently has that pid: if so,
239 240 * then at this moment, we are init.
240 241 */
241 242 static boolean_t
242 243 get_initpid_info(void)
243 244 {
244 245 pid_t pid;
245 246 sysret_t rval;
246 247 int err;
247 248
248 249 /*
249 250 * Determine the current process PID and the PID of the zone's init.
250 251 * We use care not to call getpid() here, because we're not supposed
251 252 * to call getpid() until after the program is fully linked-- the
252 253 * first call to getpid() is a signal from the linker to debuggers
253 254 * that linking has been completed.
254 255 */
255 256 if ((err = __systemcall(&rval, SYS_brand,
256 257 B_S10_PIDINFO, &pid, &zone_init_pid)) != 0) {
257 258 s10_abort(err, "Failed to get init's pid");
258 259 }
259 260
260 261 /*
261 262 * Note that we need to be cautious with the pid we get back--
262 263 * it should not be stashed and used in place of getpid(), since
263 264 * we might fork(2). So we keep zone_init_pid and toss the pid
264 265 * we otherwise got.
265 266 */
266 267 if (pid == zone_init_pid)
267 268 return (B_TRUE);
268 269
269 270 return (B_FALSE);
270 271 }
271 272
272 273 /*
273 274 * This function is defined to be NOSYS but it won't be called from the
274 275 * the kernel since the NOSYS system calls are not enabled in the kernel.
275 276 * Thus, the only time this function is called is directly from within the
276 277 * indirect system call path.
277 278 */
278 279 /*ARGSUSED*/
279 280 static long
280 281 s10_unimpl(sysret_t *rv, uintptr_t p1)
281 282 {
282 283 sysret_t rval;
283 284
284 285 /*
285 286 * We'd like to print out some kind of error message here like
286 287 * "unsupported syscall", but we can't because it's not safe to
287 288 * assume that stderr or STDERR_FILENO actually points to something
288 289 * that is a terminal, and if we wrote to those files we could
289 290 * inadvertantly write to some applications open files, which would
290 291 * be bad.
291 292 *
292 293 * Normally, if an application calls an invalid system call
293 294 * it get a SIGSYS sent to it. So we'll just go ahead and send
294 295 * ourselves a signal here. Note that this is far from ideal since
295 296 * if the application has registered a signal handler, that signal
296 297 * handler may recieve a ucontext_t as the third parameter to
297 298 * indicate the context of the process when the signal was
298 299 * generated, and in this case that context will not be what the
299 300 * application is expecting. Hence, we should probably create a
300 301 * brandsys() kernel function that can deliver the signal to us
301 302 * with the correct ucontext_t.
302 303 */
303 304 (void) __systemcall(&rval, SYS_lwp_kill + 1024, _lwp_self(), SIGSYS);
304 305 return (ENOSYS);
305 306 }
306 307
307 308 #if defined(__sparc) && !defined(__sparcv9)
308 309 /*
309 310 * Yuck. For 32-bit sparc applications, handle indirect system calls.
310 311 * Note that we declare this interface to use the maximum number of
311 312 * system call arguments. If we recieve a system call that uses less
312 313 * arguments, then the additional arguments will be garbage, but they
313 314 * will also be ignored so that should be ok.
314 315 */
315 316 static long
316 317 s10_indir(sysret_t *rv, int code,
317 318 uintptr_t a0, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4,
318 319 uintptr_t a5, uintptr_t a6, uintptr_t a7)
319 320 {
320 321 s10_sysent_table_t *sst = &(s10_sysent_table[code]);
321 322
322 323 s10_assert(code < NSYSCALL);
323 324 switch (sst->st_args & NARGS_MASK) {
324 325 case 0:
325 326 return ((sst->st_callc)(rv));
326 327 case 1:
327 328 return ((sst->st_callc)(rv, a0));
328 329 case 2:
329 330 return ((sst->st_callc)(rv, a0, a1));
330 331 case 3:
331 332 return ((sst->st_callc)(rv, a0, a1, a2));
332 333 case 4:
333 334 return ((sst->st_callc)(rv, a0, a1, a2, a3));
334 335 case 5:
335 336 return ((sst->st_callc)(rv, a0, a1, a2, a3, a4));
336 337 case 6:
337 338 return ((sst->st_callc)(rv, rv, a0, a1, a2, a3, a4, a5));
338 339 case 7:
339 340 return ((sst->st_callc)(rv, a0, a1, a2, a3, a4, a5, a6));
340 341 case 8:
341 342 return ((sst->st_callc)(rv, a0, a1, a2, a3, a4, a5, a6, a7));
342 343 }
343 344 s10_abort(0, "invalid entry in s10_sysent_table");
344 345 return (EINVAL);
345 346 }
346 347 #endif /* __sparc && !__sparcv9 */
347 348
348 349 /*
349 350 * The process contract CT_TGET and CT_TSET parameter structure ct_param_t
350 351 * changed between S10 and Nevada, so we have to emulate the old S10
351 352 * ct_param_t structure when interposing on the ioctl syscall.
352 353 */
353 354 typedef struct s10_ct_param {
354 355 uint32_t ctpm_id;
355 356 uint32_t ctpm_pad;
356 357 uint64_t ctpm_value;
357 358 } s10_ct_param_t;
358 359
359 360 /*
360 361 * New first arg "legacy" should be set to 1.
361 362 */
362 363 static int
363 364 s10_getpagesizes(sysret_t *rval, size_t *buf, int nelem)
364 365 {
365 366 int err;
366 367
367 368 if ((err = __systemcall(rval, SYS_getpagesizes + 1024, 1, buf, nelem))
368 369 != 0)
369 370 return (err);
370 371 return (0);
371 372 }
372 373
373 374 int
374 375 s10_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg)
375 376 {
376 377 int err;
377 378 s10_ct_param_t s10param;
378 379 ct_param_t param;
379 380 struct stat statbuf;
380 381
381 382 /*
382 383 * We have to emulate process contract ioctls for init(1M) because the
383 384 * ioctl parameter structure changed between S10 and Nevada. This is
384 385 * a relatively simple process of filling Nevada structure fields,
385 386 * shuffling values, and initiating a native system call.
386 387 *
387 388 * For now, we'll assume that all consumers of CT_TGET and CT_TSET will
388 389 * need emulation. We'll issue a stat to make sure that the ioctl
389 390 * is meant for the contract file system.
390 391 *
391 392 */
392 393 switch (cmd) {
393 394 case CT_TGET:
394 395 if ((err = __systemcall(rval, SYS_fstat + 1024, fdes,
395 396 &statbuf)) != 0)
396 397 return (err);
397 398 if (strcmp(statbuf.st_fstype, MNTTYPE_CTFS) != 0)
398 399 goto nonemuioctl;
399 400 if (s10_uucopy((const void *)arg, &s10param,
400 401 sizeof (s10param)) != 0)
401 402 return (EFAULT);
402 403 param.ctpm_id = s10param.ctpm_id;
403 404 param.ctpm_size = sizeof (uint64_t);
404 405 param.ctpm_value = &s10param.ctpm_value;
405 406 if ((err = __systemcall(rval, SYS_ioctl + 1024, fdes,
406 407 cmd, ¶m)) != 0)
407 408 return (err);
408 409 if (s10_uucopy(&s10param, (void *)arg,
409 410 sizeof (s10param)) != 0)
410 411 return (EFAULT);
411 412 return (0);
412 413 case CT_TSET:
413 414 if ((err = __systemcall(rval, SYS_fstat + 1024, fdes,
414 415 &statbuf)) != 0)
415 416 return (err);
416 417 if (strcmp(statbuf.st_fstype, MNTTYPE_CTFS) != 0)
417 418 goto nonemuioctl;
418 419 if (s10_uucopy((const void *)arg, &s10param,
419 420 sizeof (s10param)) != 0)
420 421 return (EFAULT);
421 422 param.ctpm_id = s10param.ctpm_id;
422 423 param.ctpm_size = sizeof (uint64_t);
423 424 param.ctpm_value = &s10param.ctpm_value;
424 425 if ((err = __systemcall(rval, SYS_ioctl + 1024, fdes,
425 426 cmd, ¶m)) != 0)
426 427 return (err);
427 428 return (0);
428 429 }
429 430
430 431 nonemuioctl:
431 432 if ((err = __systemcall(rval, SYS_ioctl + 1024, fdes, cmd, arg)) != 0)
432 433 return (err);
433 434 return (0);
434 435 }
435 436
436 437 /*
437 438 * Unfortunately, pwrite()'s behavior differs between S10 and Nevada when
438 439 * applied to files opened with O_APPEND. The offset argument is ignored and
439 440 * the buffer is appended to the target file in S10, whereas the current file
440 441 * position is ignored in Nevada (i.e., pwrite() acts as though the target file
441 442 * wasn't opened with O_APPEND). This is a result of the fix for CR 6655660
442 443 * (pwrite() must ignore the O_APPEND/FAPPEND flag).
443 444 *
444 445 * We emulate the old S10 pwrite() behavior by checking whether the target file
445 446 * was opened with O_APPEND. If it was, then invoke the write() system call
446 447 * instead of pwrite(); otherwise, invoke the pwrite() system call as usual.
447 448 */
448 449 static int
449 450 s10_pwrite(sysret_t *rval, int fd, const void *bufferp, size_t num_bytes,
450 451 off_t offset)
451 452 {
452 453 int err;
453 454
454 455 if ((err = __systemcall(rval, SYS_fcntl + 1024, fd, F_GETFL)) != 0)
455 456 return (err);
456 457 if (rval->sys_rval1 & O_APPEND)
457 458 return (__systemcall(rval, SYS_write + 1024, fd, bufferp,
458 459 num_bytes));
459 460 return (__systemcall(rval, SYS_pwrite + 1024, fd, bufferp, num_bytes,
460 461 offset));
461 462 }
462 463
463 464 #ifndef _LP64
464 465 /*
465 466 * This is the large file version of the pwrite() system call for 32-bit
466 467 * processes. This exists for the same reason that s10_pwrite() exists; see
467 468 * the comment above s10_pwrite().
468 469 */
469 470 static int
470 471 s10_pwrite64(sysret_t *rval, int fd, const void *bufferp, size32_t num_bytes,
471 472 uint32_t offset_1, uint32_t offset_2)
472 473 {
473 474 int err;
474 475
475 476 if ((err = __systemcall(rval, SYS_fcntl + 1024, fd, F_GETFL)) != 0)
476 477 return (err);
477 478 if (rval->sys_rval1 & O_APPEND)
478 479 return (__systemcall(rval, SYS_write + 1024, fd, bufferp,
479 480 num_bytes));
480 481 return (__systemcall(rval, SYS_pwrite64 + 1024, fd, bufferp,
481 482 num_bytes, offset_1, offset_2));
482 483 }
483 484 #endif /* !_LP64 */
484 485
485 486 #define S10_AC_PROC (0x1 << 28)
486 487 #define S10_AC_TASK (0x2 << 28)
487 488 #define S10_AC_FLOW (0x4 << 28)
488 489 #define S10_AC_MODE(x) ((x) & 0xf0000000)
489 490 #define S10_AC_OPTION(x) ((x) & 0x0fffffff)
490 491
491 492 /*
492 493 * The mode shift, mode mask and option mask for acctctl have changed. The
493 494 * mode is currently the top full byte and the option is the lower 3 full bytes.
494 495 */
495 496 int
496 497 s10_acctctl(sysret_t *rval, int cmd, void *buf, size_t bufsz)
497 498 {
498 499 int mode = S10_AC_MODE(cmd);
499 500 int option = S10_AC_OPTION(cmd);
500 501
501 502 switch (mode) {
502 503 case S10_AC_PROC:
503 504 mode = AC_PROC;
504 505 break;
505 506 case S10_AC_TASK:
506 507 mode = AC_TASK;
507 508 break;
508 509 case S10_AC_FLOW:
509 510 mode = AC_FLOW;
510 511 break;
511 512 default:
512 513 return (S10_TRUSS_POINT_3(rval, SYS_acctctl, EINVAL, cmd, buf,
513 514 bufsz));
514 515 }
515 516
516 517 return (__systemcall(rval, SYS_acctctl + 1024, mode | option, buf,
517 518 bufsz));
518 519 }
519 520
520 521 /*
521 522 * Determine whether the executable passed to SYS_exec or SYS_execve is a
522 523 * wrapper around a native executable. If so, then fudge the executable's
523 524 * name and parameters to eliminate any trace of the wrapper. This will make
524 525 * pgrep and other commands that examine process' executable names and
525 526 * command-line parameters work properly.
526 527 */
527 528 static int
528 529 s10_exec_native(sysret_t *rval, const char *fname, const char **argp,
529 530 const char **envp)
530 531 {
531 532 const char *filename = fname;
532 533 char path[64];
533 534 int err;
534 535
535 536 /* Get a copy of the executable we're trying to run */
536 537 path[0] = '\0';
537 538 (void) s10_uucopystr(filename, path, sizeof (path));
538 539
539 540 /* Check if we're trying to run a native binary */
540 541 if (strncmp(path, "/.SUNWnative/usr/lib/brand/solaris10/s10_native",
541 542 sizeof (path)) != 0)
542 543 return (0);
543 544
544 545 /* Skip the first element in the argv array */
545 546 argp++;
546 547
547 548 /*
548 549 * The name of the new program to execute was the second parameter
549 550 * passed to s10_exec_native().
550 551 */
551 552 if (s10_uucopy(argp, &filename, sizeof (char *)) != 0)
552 553 return (EFAULT);
553 554
554 555 /* If an exec call succeeds, it never returns */
555 556 err = __systemcall(rval, SYS_brand + 1024, B_EXEC_NATIVE, filename,
556 557 argp, envp, NULL, NULL, NULL);
557 558 s10_assert(err != 0);
558 559 return (err);
559 560 }
560 561
561 562 /*
562 563 * Interpose on the SYS_exec syscall to detect native wrappers.
563 564 */
564 565 int
565 566 s10_exec(sysret_t *rval, const char *fname, const char **argp)
566 567 {
567 568 int err;
568 569
569 570 if ((err = s10_exec_native(rval, fname, argp, NULL)) != 0)
570 571 return (err);
571 572
572 573 /* If an exec call succeeds, it never returns */
573 574 err = __systemcall(rval, SYS_exec + 1024, fname, argp);
574 575 s10_assert(err != 0);
575 576 return (err);
576 577 }
577 578
578 579 /*
579 580 * Interpose on the SYS_execve syscall to detect native wrappers.
580 581 */
581 582 int
582 583 s10_execve(sysret_t *rval, const char *fname, const char **argp,
583 584 const char **envp)
584 585 {
585 586 int err;
586 587
587 588 if ((err = s10_exec_native(rval, fname, argp, envp)) != 0)
588 589 return (err);
589 590
590 591 /* If an exec call succeeds, it never returns */
591 592 err = __systemcall(rval, SYS_execve + 1024, fname, argp, envp);
592 593 s10_assert(err != 0);
593 594 return (err);
594 595 }
595 596
596 597 /*
597 598 * S10's issetugid() syscall is now a subcode to privsys().
598 599 */
599 600 static int
600 601 s10_issetugid(sysret_t *rval)
601 602 {
602 603 int err;
603 604
604 605 if ((err = __systemcall(rval, SYS_privsys + 1024, PRIVSYS_ISSETUGID,
605 606 0, 0, 0, 0, 0)) != 0)
606 607 return (err);
607 608 return (0);
608 609 }
609 610
610 611 /*
611 612 * New last arg "block" flag should be zero. The block flag is used by
612 613 * the Opensolaris AIO implementation, which is now part of libc.
613 614 */
614 615 static int
615 616 s10_sigqueue(sysret_t *rval, pid_t pid, int signo, void *value, int si_code)
616 617 {
617 618 int err;
618 619
619 620 if ((err = __systemcall(rval, SYS_sigqueue + 1024, pid, signo, value,
620 621 si_code, 0)) != 0)
621 622 return (err);
622 623 return (0);
623 624 }
624 625
625 626 static long
626 627 s10_uname(sysret_t *rv, uintptr_t p1)
627 628 {
628 629 struct utsname un, *unp = (struct utsname *)p1;
629 630 int rev, err;
630 631
631 632 if ((err = __systemcall(rv, SYS_uname + 1024, &un)) != 0)
632 633 return (err);
633 634
634 635 rev = atoi(&un.release[2]);
635 636 s10_assert(rev >= 11);
636 637 bzero(un.release, _SYS_NMLN);
637 638 (void) strlcpy(un.release, S10_UTS_RELEASE, _SYS_NMLN);
|
↓ open down ↓ |
588 lines elided |
↑ open up ↑ |
638 639 bzero(un.version, _SYS_NMLN);
639 640 (void) strlcpy(un.version, S10_UTS_VERSION, _SYS_NMLN);
640 641
641 642 /* copy out the modified uname info */
642 643 if (s10_uucopy(&un, unp, sizeof (un)) != 0)
643 644 return (EFAULT);
644 645
645 646 return (0);
646 647 }
647 648
649 +int
650 +s10_sysinfo(sysret_t *rv, int command, char *buf, long count)
651 +{
652 + char *value;
653 + int err, len;
654 +
655 + /*
656 + * We must interpose on the sysinfo(2) commands SI_RELEASE and
657 + * SI_VERSION; all others get passed to the native sysinfo(2)
658 + * command.
659 + */
660 + switch (command) {
661 + case SI_RELEASE:
662 + value = S10_UTS_RELEASE;
663 + break;
664 +
665 + case SI_VERSION:
666 + value = S10_UTS_VERSION;
667 + break;
668 +
669 + default:
670 + /*
671 + * The default action is to pass the command to the
672 + * native sysinfo(2) syscall.
673 + */
674 + if ((err = __systemcall(rv, SYS_systeminfo + 1024,
675 + command, buf, count)) != 0)
676 + return (err);
677 +
678 + return (0);
679 + }
680 +
681 + len = strlen(value) + 1;
682 + if (count > 0) {
683 + if (s10_uucopystr(value, buf, count) != 0)
684 + return (EFAULT);
685 +
686 + /* Assure NULL termination of buf as s10_uucopystr() doesn't. */
687 + if (len > count && s10_uucopy("\0", buf + (count - 1), 1) != 0)
688 + return (EFAULT);
689 + }
690 +
691 + /*
692 + * On success, sysinfo(2) returns the size of buffer required to hold
693 + * the complete value plus its terminating NULL byte.
694 + */
695 + rv->sys_rval1 = len;
696 + rv->sys_rval2 = 0;
697 + S10_TRUSS_POINT_3(rv, SYS_systeminfo, 0, command, buf, count);
698 + return (0);
699 +}
700 +
648 701 /*
649 702 * If the emul_global_zone flag is set then emulate some aspects of the
650 703 * zone system call. In particular, emulate the global zone ID on the
651 704 * ZONE_LOOKUP subcommand and emulate some of the global zone attributes
652 705 * on the ZONE_GETATTR subcommand. If the flag is not set or we're performing
653 706 * some other operation, simply pass the calls through.
654 707 */
655 708 int
656 709 s10_zone(sysret_t *rval, int cmd, void *arg1, void *arg2, void *arg3,
657 710 void *arg4)
658 711 {
659 712 char *aval;
660 713 int len;
661 714 zoneid_t zid;
662 715 int attr;
663 716 char *buf;
664 717 size_t bufsize;
665 718
666 719 /*
667 720 * We only emulate the zone syscall for a subset of specific commands,
668 721 * otherwise we just pass the call through.
669 722 */
670 723 if (!emul_global_zone)
671 724 return (__systemcall(rval, SYS_zone + 1024, cmd, arg1, arg2,
672 725 arg3, arg4));
673 726
674 727 switch (cmd) {
675 728 case ZONE_LOOKUP:
676 729 (void) S10_TRUSS_POINT_1(rval, SYS_zone, 0, cmd);
677 730 rval->sys_rval1 = GLOBAL_ZONEID;
678 731 rval->sys_rval2 = 0;
679 732 return (0);
680 733
681 734 case ZONE_GETATTR:
682 735 zid = (zoneid_t)(uintptr_t)arg1;
683 736 attr = (int)(uintptr_t)arg2;
684 737 buf = (char *)arg3;
685 738 bufsize = (size_t)arg4;
686 739
687 740 /*
688 741 * If the request is for the global zone then we're emulating
689 742 * that, otherwise pass this thru.
690 743 */
691 744 if (zid != GLOBAL_ZONEID)
692 745 goto passthru;
693 746
694 747 (void) S10_TRUSS_POINT_3(rval, SYS_zone, 0, cmd, zid, attr);
695 748
696 749 switch (attr) {
697 750 case ZONE_ATTR_NAME:
698 751 aval = GLOBAL_ZONENAME;
699 752 break;
700 753
701 754 case ZONE_ATTR_BRAND:
702 755 aval = NATIVE_BRAND_NAME;
703 756 break;
704 757 default:
705 758 /*
706 759 * We only emulate a subset of the attrs, use the
707 760 * real zone id to pass thru the rest.
708 761 */
709 762 arg1 = (void *)(uintptr_t)zoneid;
710 763 goto passthru;
711 764 }
712 765
713 766 len = strlen(aval) + 1;
714 767 if (len > bufsize)
715 768 return (ENAMETOOLONG);
716 769
717 770 if (buf != NULL) {
718 771 if (len == 1) {
719 772 if (s10_uucopy("\0", buf, 1) != 0)
720 773 return (EFAULT);
721 774 } else {
722 775 if (s10_uucopystr(aval, buf, len) != 0)
723 776 return (EFAULT);
724 777
725 778 /*
726 779 * Assure NULL termination of "buf" as
727 780 * s10_uucopystr() does NOT.
728 781 */
729 782 if (s10_uucopy("\0", buf + (len - 1), 1) != 0)
730 783 return (EFAULT);
731 784 }
732 785 }
733 786
734 787 rval->sys_rval1 = len;
735 788 rval->sys_rval2 = 0;
736 789 return (0);
737 790
738 791 default:
739 792 break;
740 793 }
741 794
742 795 passthru:
743 796 return (__systemcall(rval, SYS_zone + 1024, cmd, arg1, arg2, arg3,
744 797 arg4));
745 798 }
746 799
747 800 /*
748 801 * This routine is run only when the init daemon starts up, in order
749 802 * to do any pre-initialization needed before the environment boots.
750 803 */
751 804 static void
752 805 s10_init1m_handler()
753 806 {
754 807 /*
755 808 * Take special actions in advance of starting init(1m).
756 809 *
757 810 * XXX Nothing to do (yet).
758 811 */
759 812 }
760 813
761 814 /*
762 815 * Close a libc file handle, but don't actually close the underlying
763 816 * file descriptor.
764 817 */
765 818 static void
766 819 s10_close_fh(FILE *file)
767 820 {
768 821 int fd, fd_new;
769 822
770 823 if (file == NULL)
771 824 return;
772 825
773 826 if ((fd = fileno(file)) < 0)
774 827 return;
775 828
776 829 fd_new = dup(fd);
777 830 if (fd_new == -1)
778 831 return;
779 832
780 833 (void) fclose(file);
781 834 (void) dup2(fd_new, fd);
782 835 (void) close(fd_new);
783 836 }
784 837
785 838 /*ARGSUSED*/
786 839 int
787 840 s10_init(int argc, char *argv[], char *envp[])
788 841 {
789 842 sysret_t rval;
790 843 s10_brand_reg_t reg;
791 844 s10_elf_data_t sed;
792 845 auxv_t *ap;
793 846 uintptr_t *p;
794 847 int i, err;
795 848 ushort_t flags;
796 849 char *bname;
797 850
798 851 /* Sanity check our translation table return value codes */
799 852 for (i = 0; i < NSYSCALL; i++) {
800 853 s10_sysent_table_t *est = &(s10_sysent_table[i]);
801 854 s10_assert(BIT_ONLYONESET(est->st_args & RV_MASK));
802 855 }
803 856
804 857 /*
805 858 * We need to shutdown all libc stdio. libc stdio normally goes to
806 859 * file descriptors, but since we're actually part of a another
807 860 * process we don't own these file descriptors and we can't make
808 861 * any assumptions about their state.
809 862 */
810 863 s10_close_fh(stdin);
811 864 s10_close_fh(stdout);
812 865 s10_close_fh(stderr);
813 866
814 867 /*
815 868 * Cache the pid of the zone's init process and determine if
816 869 * we're init(1m) for the zone. Remember: we might be init
817 870 * now, but as soon as we fork(2) we won't be.
818 871 */
819 872 if (get_initpid_info()) {
820 873 s10_init1m_handler();
821 874 }
822 875
823 876 /* get the current zoneid */
824 877 err = __systemcall(&rval, SYS_zone, ZONE_LOOKUP, NULL);
825 878 s10_assert(err == 0);
826 879 zoneid = (zoneid_t)rval.sys_rval1;
827 880
828 881 /* Get the emulation version number. */
829 882 if ((err = __systemcall(&rval, SYS_zone, ZONE_GETATTR, zoneid,
830 883 S10_EMUL_VERSION_NUM, &emul_vers, sizeof (emul_vers))) != 0 ||
831 884 emul_vers != 0) {
832 885 s10_abort(err, "The zone's patch level is unsupported");
833 886 /*NOTREACHED*/
834 887 }
835 888
836 889 /* Figure out if this zone has a shared ip */
837 890 err = __systemcall(&rval, SYS_zone, ZONE_GETATTR, zoneid,
838 891 ZONE_ATTR_FLAGS, &flags, sizeof (flags));
839 892 s10_assert(err == 0);
840 893 ipshared = ((flags & ZF_NET_EXCL) == 0);
841 894
842 895 bname = basename(argv[0]);
843 896
844 897 /*
845 898 * In general we want the S10 commands that are zone-aware to continue
846 899 * to behave as they normally do within a zone. Since these commands
847 900 * are zone-aware, they should continue to "do the right thing".
848 901 * However, some zone-aware commands aren't going to work the way
849 902 * we expect them to inside the branded zone. In particular, the pkg
850 903 * and patch commands will not properly manage all pkgs/patches
851 904 * unless the commands think they are running in the global zone. For
852 905 * these commands we want to emulate the global zone.
853 906 *
854 907 * XXX One issue is the handling of hollow pkgs. This is not normally
855 908 * a problem since the p2v/v2v process handles those. However, if
856 909 * the user attempts to install a hollow pkg after the zone is running,
857 910 * the pkg code will do the wrong thing. Luckily, most of the hollow
858 911 * pkgs are core pkgs which will already be installed in the image
859 912 * before we p2v/v2v it into the zone and there should be little need
860 913 * to pkgadd these later.
861 914 */
862 915 if (strcmp("pkgadd", bname) == 0 || strcmp("pkgrm", bname) == 0 ||
863 916 strcmp("pkgcond", bname) == 0 ||
864 917 strcmp("patchadd", bname) == 0 || strcmp("patchrm", bname) == 0)
865 918 emul_global_zone = B_TRUE;
866 919
867 920 /*
868 921 * Register our syscall emulation table with the kernel.
869 922 * Note that we don't have to do invoke (syscall_number + 1024)
870 923 * until we've actually establised a syscall emulation callback
871 924 * handler address, which is what we're doing with this brand
872 925 * syscall.
873 926 */
874 927 reg.sbr_version = S10_VERSION;
875 928 reg.sbr_handler = (caddr_t)s10_handler;
876 929 if ((err = __systemcall(&rval, SYS_brand, B_REGISTER, ®)) != 0) {
877 930 s10_abort(err, "Failed to brand current process");
878 931 /*NOTREACHED*/
879 932 }
880 933
881 934 /* Get data about the executable we're running from the kernel. */
882 935 if ((err = __systemcall(&rval, SYS_brand + 1024,
883 936 B_ELFDATA, (void *)&sed)) != 0) {
884 937 s10_abort(err,
885 938 "Failed to get required brand ELF data from the kernel");
886 939 /*NOTREACHED*/
887 940 }
888 941
889 942 /*
890 943 * Find the aux vector on the stack.
891 944 */
892 945 p = (uintptr_t *)envp;
893 946 while (*p != NULL)
894 947 p++;
895 948
896 949 /*
897 950 * p is now pointing at the 0 word after the environ pointers.
898 951 * After that is the aux vectors.
899 952 *
900 953 * The aux vectors are currently pointing to the brand emulation
901 954 * library and associated linker. We're going to change them to
902 955 * point to the brand executable and associated linker (or to no
903 956 * linker for static binaries). This matches the process data
904 957 * stored within the kernel and visible from /proc, which was
905 958 * all setup in s10_elfexec(). We do this so that when a debugger
906 959 * attaches to the process it sees the process as a normal solaris
907 960 * process, this brand emulation library and everything on it's
908 961 * link map will not be visible, unless our librtld_db plugin
909 962 * is used. Note that this is very different from how Linux
910 963 * branded processes are implemented within lx branded zones.
911 964 * In that situation, the primary linkmap of the process is the
912 965 * brand emulation libraries linkmap, not the Linux applications
913 966 * linkmap.
914 967 *
915 968 * We also need to clear the AF_SUN_NOPLM flag from the AT_SUN_AUXFLAGS
916 969 * aux vector. This flag told our linker that we don't have a
917 970 * primary link map. Now that our linker is done initializing, we
918 971 * want to clear this flag before we transfer control to the
919 972 * applications copy of the linker, since we want that linker to have
920 973 * a primary link map which will be the link map for the application
921 974 * we're running.
922 975 */
923 976 p++;
924 977 for (ap = (auxv_t *)p; ap->a_type != AT_NULL; ap++) {
925 978 switch (ap->a_type) {
926 979 case AT_BASE:
927 980 /* Hide AT_BASE if static binary */
928 981 if (sed.sed_base == NULL) {
929 982 ap->a_type = AT_IGNORE;
930 983 ap->a_un.a_val = NULL;
931 984 } else {
932 985 ap->a_un.a_val = sed.sed_base;
933 986 }
934 987 break;
935 988 case AT_ENTRY:
936 989 ap->a_un.a_val = sed.sed_entry;
937 990 break;
938 991 case AT_PHDR:
939 992 ap->a_un.a_val = sed.sed_phdr;
940 993 break;
941 994 case AT_PHENT:
942 995 ap->a_un.a_val = sed.sed_phent;
943 996 break;
944 997 case AT_PHNUM:
945 998 ap->a_un.a_val = sed.sed_phnum;
946 999 break;
947 1000 case AT_SUN_AUXFLAGS:
948 1001 ap->a_un.a_val &= ~AF_SUN_NOPLM;
949 1002 break;
950 1003 case AT_SUN_EMULATOR:
951 1004 /*
952 1005 * ld.so.1 inspects AT_SUN_EMULATOR to see if
953 1006 * if it is the linker for the brand emulation
954 1007 * library. Hide AT_SUN_EMULATOR, as the
955 1008 * linker we are about to jump to is the linker
956 1009 * for the binary.
957 1010 */
958 1011 ap->a_type = AT_IGNORE;
959 1012 ap->a_un.a_val = NULL;
960 1013 break;
961 1014 case AT_SUN_LDDATA:
962 1015 /* Hide AT_SUN_LDDATA if static binary */
963 1016 if (sed.sed_lddata == NULL) {
964 1017 ap->a_type = AT_IGNORE;
965 1018 ap->a_un.a_val = NULL;
966 1019 } else {
967 1020 ap->a_un.a_val = sed.sed_lddata;
968 1021 }
969 1022 break;
970 1023 default:
971 1024 break;
972 1025 }
973 1026 }
974 1027
975 1028 s10_runexe(argv, sed.sed_ldentry);
976 1029 /*NOTREACHED*/
977 1030 s10_abort(0, "s10_runexe() returned");
978 1031 return (-1);
979 1032 }
980 1033
981 1034 /*
982 1035 * This table must have at least NSYSCALL entries in it.
983 1036 *
984 1037 * The second parameter of each entry in the s10_sysent_table
985 1038 * contains the number of parameters and flags that describe the
986 1039 * syscall return value encoding. See the block comments at the
987 1040 * top of this file for more information about the syscall return
988 1041 * value flags and when they should be used.
989 1042 */
990 1043 s10_sysent_table_t s10_sysent_table[] = {
991 1044 #if defined(__sparc) && !defined(__sparcv9)
992 1045 EMULATE(s10_indir, 9 | RV_64RVAL), /* 0 */
993 1046 #else /* !__sparc || __sparcv9 */
994 1047 NOSYS, /* 0 */
995 1048 #endif /* !__sparc || __sparcv9 */
996 1049 NOSYS, /* 1 */
997 1050 NOSYS, /* 2 */
998 1051 NOSYS, /* 3 */
999 1052 NOSYS, /* 4 */
1000 1053 NOSYS, /* 5 */
1001 1054 NOSYS, /* 6 */
1002 1055 NOSYS, /* 7 */
1003 1056 NOSYS, /* 8 */
1004 1057 NOSYS, /* 9 */
1005 1058 NOSYS, /* 10 */
1006 1059 EMULATE(s10_exec, 2 | RV_DEFAULT), /* 11 */
1007 1060 NOSYS, /* 12 */
1008 1061 NOSYS, /* 13 */
1009 1062 NOSYS, /* 14 */
1010 1063 NOSYS, /* 15 */
1011 1064 NOSYS, /* 16 */
1012 1065 NOSYS, /* 17 */
1013 1066 NOSYS, /* 18 */
1014 1067 NOSYS, /* 19 */
1015 1068 NOSYS, /* 20 */
1016 1069 NOSYS, /* 21 */
1017 1070 NOSYS, /* 22 */
1018 1071 NOSYS, /* 23 */
1019 1072 NOSYS, /* 24 */
1020 1073 NOSYS, /* 25 */
1021 1074 NOSYS, /* 26 */
1022 1075 NOSYS, /* 27 */
1023 1076 NOSYS, /* 28 */
1024 1077 NOSYS, /* 29 */
1025 1078 NOSYS, /* 30 */
1026 1079 NOSYS, /* 31 */
1027 1080 NOSYS, /* 32 */
1028 1081 NOSYS, /* 33 */
1029 1082 NOSYS, /* 34 */
1030 1083 NOSYS, /* 35 */
1031 1084 NOSYS, /* 36 */
1032 1085 NOSYS, /* 37 */
1033 1086 NOSYS, /* 38 */
1034 1087 NOSYS, /* 39 */
1035 1088 NOSYS, /* 40 */
1036 1089 NOSYS, /* 41 */
1037 1090 NOSYS, /* 42 */
1038 1091 NOSYS, /* 43 */
1039 1092 NOSYS, /* 44 */
1040 1093 NOSYS, /* 45 */
1041 1094 NOSYS, /* 46 */
1042 1095 NOSYS, /* 47 */
1043 1096 NOSYS, /* 48 */
1044 1097 NOSYS, /* 49 */
1045 1098 NOSYS, /* 50 */
1046 1099 NOSYS, /* 51 */
1047 1100 NOSYS, /* 52 */
1048 1101 NOSYS, /* 53 */
1049 1102 EMULATE(s10_ioctl, 3 | RV_DEFAULT), /* 54 */
1050 1103 NOSYS, /* 55 */
1051 1104 NOSYS, /* 56 */
1052 1105 NOSYS, /* 57 */
1053 1106 NOSYS, /* 58 */
1054 1107 EMULATE(s10_execve, 3 | RV_DEFAULT), /* 59 */
1055 1108 NOSYS, /* 60 */
1056 1109 NOSYS, /* 61 */
1057 1110 NOSYS, /* 62 */
1058 1111 NOSYS, /* 63 */
1059 1112 NOSYS, /* 64 */
1060 1113 NOSYS, /* 65 */
1061 1114 NOSYS, /* 66 */
1062 1115 NOSYS, /* 67 */
1063 1116 NOSYS, /* 68 */
1064 1117 NOSYS, /* 69 */
1065 1118 NOSYS, /* 70 */
1066 1119 EMULATE(s10_acctctl, 3 | RV_DEFAULT), /* 71 */
1067 1120 NOSYS, /* 72 */
1068 1121 EMULATE(s10_getpagesizes, 2 | RV_DEFAULT), /* 73 */
1069 1122 NOSYS, /* 74 */
1070 1123 EMULATE(s10_issetugid, 0 | RV_DEFAULT), /* 75 */
1071 1124 NOSYS, /* 76 */
1072 1125 NOSYS, /* 77 */
1073 1126 NOSYS, /* 78 */
1074 1127 NOSYS, /* 79 */
1075 1128 NOSYS, /* 80 */
1076 1129 NOSYS, /* 81 */
1077 1130 NOSYS, /* 82 */
1078 1131 NOSYS, /* 83 */
1079 1132 NOSYS, /* 84 */
1080 1133 NOSYS, /* 85 */
1081 1134 NOSYS, /* 86 */
1082 1135 NOSYS, /* 87 */
1083 1136 NOSYS, /* 88 */
1084 1137 NOSYS, /* 89 */
1085 1138 NOSYS, /* 90 */
1086 1139 NOSYS, /* 91 */
1087 1140 NOSYS, /* 92 */
1088 1141 NOSYS, /* 93 */
1089 1142 NOSYS, /* 94 */
1090 1143 NOSYS, /* 95 */
1091 1144 NOSYS, /* 96 */
1092 1145 NOSYS, /* 97 */
1093 1146 NOSYS, /* 98 */
1094 1147 NOSYS, /* 99 */
1095 1148 NOSYS, /* 100 */
1096 1149 NOSYS, /* 101 */
1097 1150 NOSYS, /* 102 */
1098 1151 NOSYS, /* 103 */
1099 1152 NOSYS, /* 104 */
1100 1153 NOSYS, /* 105 */
1101 1154 NOSYS, /* 106 */
1102 1155 NOSYS, /* 107 */
1103 1156 NOSYS, /* 108 */
1104 1157 NOSYS, /* 109 */
1105 1158 NOSYS, /* 110 */
1106 1159 NOSYS, /* 111 */
1107 1160 NOSYS, /* 112 */
1108 1161 NOSYS, /* 113 */
1109 1162 NOSYS, /* 114 */
1110 1163 NOSYS, /* 115 */
1111 1164 NOSYS, /* 116 */
1112 1165 NOSYS, /* 117 */
1113 1166 NOSYS, /* 118 */
1114 1167 NOSYS, /* 119 */
1115 1168 NOSYS, /* 120 */
1116 1169 NOSYS, /* 121 */
1117 1170 NOSYS, /* 122 */
1118 1171 NOSYS, /* 123 */
1119 1172 NOSYS, /* 124 */
1120 1173 NOSYS, /* 125 */
1121 1174 NOSYS, /* 126 */
1122 1175 NOSYS, /* 127 */
1123 1176 NOSYS, /* 128 */
|
↓ open down ↓ |
466 lines elided |
↑ open up ↑ |
1124 1177 NOSYS, /* 129 */
1125 1178 NOSYS, /* 130 */
1126 1179 NOSYS, /* 131 */
1127 1180 NOSYS, /* 132 */
1128 1181 NOSYS, /* 133 */
1129 1182 NOSYS, /* 134 */
1130 1183 EMULATE(s10_uname, 1 | RV_DEFAULT), /* 135 */
1131 1184 NOSYS, /* 136 */
1132 1185 NOSYS, /* 137 */
1133 1186 NOSYS, /* 138 */
1134 - NOSYS, /* 139 */
1187 + EMULATE(s10_sysinfo, 3 | RV_DEFAULT), /* 139 */
1135 1188 NOSYS, /* 140 */
1136 1189 NOSYS, /* 141 */
1137 1190 NOSYS, /* 142 */
1138 1191 NOSYS, /* 143 */
1139 1192 NOSYS, /* 144 */
1140 1193 NOSYS, /* 145 */
1141 1194 NOSYS, /* 146 */
1142 1195 NOSYS, /* 147 */
1143 1196 NOSYS, /* 148 */
1144 1197 NOSYS, /* 149 */
1145 1198 NOSYS, /* 150 */
1146 1199 NOSYS, /* 151 */
1147 1200 NOSYS, /* 152 */
1148 1201 NOSYS, /* 153 */
1149 1202 NOSYS, /* 154 */
1150 1203 NOSYS, /* 155 */
1151 1204 NOSYS, /* 156 */
1152 1205 NOSYS, /* 157 */
1153 1206 NOSYS, /* 158 */
1154 1207 NOSYS, /* 159 */
1155 1208 NOSYS, /* 160 */
1156 1209 NOSYS, /* 161 */
1157 1210 NOSYS, /* 162 */
1158 1211 NOSYS, /* 163 */
1159 1212 NOSYS, /* 164 */
1160 1213 NOSYS, /* 165 */
1161 1214 NOSYS, /* 166 */
1162 1215 NOSYS, /* 167 */
1163 1216 NOSYS, /* 168 */
1164 1217 NOSYS, /* 169 */
1165 1218 NOSYS, /* 170 */
1166 1219 NOSYS, /* 171 */
1167 1220 NOSYS, /* 172 */
1168 1221 NOSYS, /* 173 */
1169 1222 EMULATE(s10_pwrite, 4 | RV_DEFAULT), /* 174 */
1170 1223 NOSYS, /* 175 */
1171 1224 NOSYS, /* 176 */
1172 1225 NOSYS, /* 177 */
1173 1226 NOSYS, /* 178 */
1174 1227 NOSYS, /* 179 */
1175 1228 NOSYS, /* 180 */
1176 1229 NOSYS, /* 181 */
1177 1230 NOSYS, /* 182 */
1178 1231 NOSYS, /* 183 */
1179 1232 NOSYS, /* 184 */
1180 1233 NOSYS, /* 185 */
1181 1234 NOSYS, /* 186 */
1182 1235 NOSYS, /* 187 */
1183 1236 NOSYS, /* 188 */
1184 1237 NOSYS, /* 189 */
1185 1238 EMULATE(s10_sigqueue, 4 | RV_DEFAULT), /* 190 */
1186 1239 NOSYS, /* 191 */
1187 1240 NOSYS, /* 192 */
1188 1241 NOSYS, /* 193 */
1189 1242 NOSYS, /* 194 */
1190 1243 NOSYS, /* 195 */
1191 1244 NOSYS, /* 196 */
1192 1245 NOSYS, /* 197 */
1193 1246 NOSYS, /* 198 */
1194 1247 NOSYS, /* 199 */
1195 1248 NOSYS, /* 200 */
1196 1249 NOSYS, /* 201 */
1197 1250 NOSYS, /* 202 */
1198 1251 NOSYS, /* 203 */
1199 1252 NOSYS, /* 204 */
1200 1253 NOSYS, /* 205 */
1201 1254 NOSYS, /* 206 */
1202 1255 NOSYS, /* 207 */
1203 1256 NOSYS, /* 208 */
1204 1257 NOSYS, /* 209 */
1205 1258 NOSYS, /* 210 */
1206 1259 NOSYS, /* 211 */
1207 1260 NOSYS, /* 212 */
1208 1261 NOSYS, /* 213 */
1209 1262 NOSYS, /* 214 */
1210 1263 NOSYS, /* 215 */
1211 1264 NOSYS, /* 216 */
1212 1265 NOSYS, /* 217 */
1213 1266 NOSYS, /* 218 */
1214 1267 NOSYS, /* 219 */
1215 1268 NOSYS, /* 220 */
1216 1269 NOSYS, /* 221 */
1217 1270 NOSYS, /* 222 */
1218 1271 #ifdef _LP64
1219 1272 NOSYS, /* 223 */
1220 1273 #else /* !_LP64 */
1221 1274 EMULATE(s10_pwrite64, 5 | RV_DEFAULT), /* 223 */
1222 1275 #endif /* !_LP64 */
1223 1276 NOSYS, /* 224 */
1224 1277 NOSYS, /* 225 */
1225 1278 NOSYS, /* 226 */
1226 1279 EMULATE(s10_zone, 5 | RV_DEFAULT), /* 227 */
1227 1280 NOSYS, /* 228 */
1228 1281 NOSYS, /* 229 */
1229 1282 NOSYS, /* 230 */
1230 1283 NOSYS, /* 231 */
1231 1284 NOSYS, /* 232 */
1232 1285 NOSYS, /* 233 */
1233 1286 NOSYS, /* 234 */
1234 1287 NOSYS, /* 235 */
1235 1288 NOSYS, /* 236 */
1236 1289 NOSYS, /* 237 */
1237 1290 NOSYS, /* 238 */
1238 1291 NOSYS, /* 239 */
1239 1292 NOSYS, /* 240 */
1240 1293 NOSYS, /* 241 */
1241 1294 NOSYS, /* 242 */
1242 1295 NOSYS, /* 243 */
1243 1296 NOSYS, /* 244 */
1244 1297 NOSYS, /* 245 */
1245 1298 NOSYS, /* 246 */
1246 1299 NOSYS, /* 247 */
1247 1300 NOSYS, /* 248 */
1248 1301 NOSYS, /* 249 */
1249 1302 NOSYS, /* 250 */
1250 1303 NOSYS, /* 251 */
1251 1304 NOSYS, /* 252 */
1252 1305 NOSYS, /* 253 */
1253 1306 NOSYS, /* 254 */
1254 1307 NOSYS /* 255 */
1255 1308 };
|
↓ open down ↓ |
111 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX