Print this page
OS-4470 lxbrand unblocking signals in new threads must be atomic
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c
+++ new/usr/src/lib/brand/lx/lx_brand/common/lx_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 /*
23 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27 /*
28 28 * Copyright 2015 Joyent, Inc. All rights reserved.
29 29 */
30 30
31 31 #include <sys/types.h>
32 32 #include <sys/syscall.h>
33 33 #include <sys/utsname.h>
34 34 #include <sys/inttypes.h>
35 35 #include <sys/stat.h>
36 36 #include <sys/mman.h>
37 37 #include <sys/fstyp.h>
38 38 #include <sys/fsid.h>
39 39 #include <sys/systm.h>
40 40 #include <sys/auxv.h>
41 41 #include <sys/frame.h>
42 42 #include <zone.h>
43 43 #include <sys/brand.h>
44 44 #include <sys/epoll.h>
45 45 #include <sys/stack.h>
46 46
47 47 #include <assert.h>
48 48 #include <stdio.h>
49 49 #include <stdarg.h>
50 50 #include <stdlib.h>
51 51 #include <strings.h>
52 52 #include <unistd.h>
53 53 #include <errno.h>
54 54 #include <syslog.h>
55 55 #include <signal.h>
56 56 #include <fcntl.h>
57 57 #include <synch.h>
58 58 #include <libelf.h>
59 59 #include <libgen.h>
60 60 #include <pthread.h>
61 61 #include <utime.h>
62 62 #include <dirent.h>
63 63 #include <ucontext.h>
64 64 #include <libintl.h>
65 65 #include <locale.h>
66 66
67 67 #include <sys/lx_misc.h>
68 68 #include <sys/lx_debug.h>
69 69 #include <sys/lx_brand.h>
70 70 #include <sys/lx_types.h>
71 71 #include <sys/lx_stat.h>
72 72 #include <sys/lx_statfs.h>
73 73 #include <sys/lx_signal.h>
74 74 #include <sys/lx_syscall.h>
75 75 #include <sys/lx_thread.h>
76 76 #include <sys/lx_aio.h>
77 77
78 78 /*
79 79 * There is a block comment in "uts/common/brand/lx/os/lx_brand.c" that
80 80 * describes the functioning of the LX brand in some detail.
81 81 *
82 82 * *** Setting errno
83 83 *
84 84 * This emulation library is loaded onto a seperate link map from the
85 85 * application whose address space we're running in. The Linux libc errno is
86 86 * independent of our native libc errno. To pass back an error the emulation
87 87 * function should return -errno back to the Linux caller.
88 88 */
89 89
90 90 char lx_release[LX_VERS_MAX];
91 91 char lx_cmd_name[MAXNAMLEN];
92 92
93 93 /*
94 94 * Map a linux locale ending string to the solaris equivalent.
95 95 */
96 96 struct lx_locale_ending {
97 97 const char *linux_end; /* linux ending string */
98 98 const char *solaris_end; /* to transform with this string */
99 99 int le_size; /* linux ending string length */
100 100 int se_size; /* solaris ending string length */
101 101 };
102 102
103 103 #define l2s_locale(lname, sname) \
104 104 {(lname), (sname), sizeof ((lname)) - 1, sizeof ((sname)) - 1}
105 105
106 106 #define MAXLOCALENAMELEN 30
107 107 #if !defined(TEXT_DOMAIN) /* should be defined by cc -D */
108 108 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
109 109 #endif
110 110
111 111 /*
112 112 * Most syscalls return an int but some return something else, typically a
113 113 * ssize_t. This can be either an int or a long, depending on if we're compiled
114 114 * for 32-bit or 64-bit. To correctly propagate the -errno return code in the
115 115 * 64-bit case, we declare all emulation wrappers will return a long. Thus,
116 116 * when we save the return value into the %eax or %rax register and return to
117 117 * Linux, we will have the right size value in both the 32 and 64 bit cases.
118 118 */
119 119
120 120 typedef long (*lx_syscall_handler_t)();
121 121
122 122 static lx_syscall_handler_t lx_handlers[LX_NSYSCALLS + 1];
123 123
124 124 static uintptr_t stack_bottom;
125 125
126 126 #if defined(_LP64)
127 127 long lx_fsb;
128 128 long lx_fs;
129 129 #endif
130 130 int lx_install = 0; /* install mode enabled if non-zero */
131 131 int lx_verbose = 0; /* verbose mode enabled if non-zero */
132 132 int lx_debug_enabled = 0; /* debugging output enabled if non-zero */
133 133
134 134 pid_t zoneinit_pid; /* zone init PID */
135 135
136 136 thread_key_t lx_tsd_key;
137 137
138 138 int
139 139 uucopy_unsafe(const void *src, void *dst, size_t n)
140 140 {
141 141 bcopy(src, dst, n);
142 142 return (0);
143 143 }
144 144
145 145 int
146 146 uucopystr_unsafe(const void *src, void *dst, size_t n)
147 147 {
148 148 (void) strncpy((char *)src, dst, n);
149 149 return (0);
150 150 }
151 151
152 152 static void
153 153 i_lx_msg(int fd, char *msg, va_list ap)
154 154 {
155 155 int i;
156 156 char buf[LX_MSG_MAXLEN];
157 157
158 158 /* LINTED [possible expansion issues] */
159 159 i = vsnprintf(buf, sizeof (buf), msg, ap);
160 160 buf[LX_MSG_MAXLEN - 1] = '\0';
161 161 if (i == -1)
162 162 return;
163 163
164 164 /* if debugging is enabled, send this message to debug output */
165 165 if (LX_DEBUG_ISENABLED)
166 166 lx_debug(buf);
167 167
168 168 if (fd == 2) {
169 169 /*
170 170 * We let the user choose whether or not to see these
171 171 * messages on the console.
172 172 */
173 173 if (lx_verbose == 0)
174 174 return;
175 175 }
176 176
177 177 /* we retry in case of EINTR */
178 178 do {
179 179 i = write(fd, buf, strlen(buf));
180 180 } while ((i == -1) && (errno == EINTR));
181 181 }
182 182
183 183 /*PRINTFLIKE1*/
184 184 void
185 185 lx_err(char *msg, ...)
186 186 {
187 187 va_list ap;
188 188
189 189 assert(msg != NULL);
190 190
191 191 va_start(ap, msg);
192 192 i_lx_msg(STDERR_FILENO, msg, ap);
193 193 va_end(ap);
194 194 }
195 195
196 196 /*
197 197 * This is just a non-zero exit value which also isn't one that would allow
198 198 * us to easily detect if a branded process exited because of a recursive
199 199 * fatal error.
200 200 */
201 201 #define LX_ERR_FATAL 42
202 202
203 203 /*
204 204 * Our own custom version of abort(), this routine will be used in place
205 205 * of the one located in libc. The primary difference is that this version
206 206 * will first reset the signal handler for SIGABRT to SIG_DFL, ensuring the
207 207 * SIGABRT sent causes us to dump core and is not caught by a user program.
208 208 */
209 209 void
210 210 abort(void)
211 211 {
212 212 static int aborting = 0;
213 213
214 214 struct sigaction sa;
215 215 sigset_t sigmask;
216 216
217 217 /* watch out for recursive calls to this function */
218 218 if (aborting != 0)
219 219 exit(LX_ERR_FATAL);
220 220
221 221 aborting = 1;
222 222
223 223 /*
224 224 * Block all signals here to avoid taking any signals while exiting
225 225 * in an effort to avoid any strange user interaction with our death.
226 226 */
227 227 (void) sigfillset(&sigmask);
228 228 (void) sigprocmask(SIG_BLOCK, &sigmask, NULL);
229 229
230 230 /*
231 231 * Our own version of abort(3C) that we know will never call
232 232 * a user-installed SIGABRT handler first. We WANT to die.
233 233 *
234 234 * Do this by resetting the handler to SIG_DFL, and releasing any
235 235 * held SIGABRTs.
236 236 *
237 237 * If no SIGABRTs are pending, send ourselves one.
238 238 *
239 239 * The while loop is a bit of overkill, but abort(3C) does it to
240 240 * assure it never returns so we will as well.
241 241 */
242 242 (void) sigemptyset(&sa.sa_mask);
243 243 sa.sa_sigaction = SIG_DFL;
244 244 sa.sa_flags = 0;
245 245
246 246 for (;;) {
247 247 (void) sigaction(SIGABRT, &sa, NULL);
248 248 (void) sigrelse(SIGABRT);
249 249 (void) thr_kill(thr_self(), SIGABRT);
250 250 }
251 251
252 252 /*NOTREACHED*/
253 253 }
254 254
255 255 /*PRINTFLIKE1*/
256 256 void
257 257 lx_msg(char *msg, ...)
258 258 {
259 259 va_list ap;
260 260
261 261 assert(msg != NULL);
262 262 va_start(ap, msg);
263 263 i_lx_msg(STDOUT_FILENO, msg, ap);
264 264 va_end(ap);
265 265 }
266 266
267 267 /*PRINTFLIKE1*/
268 268 void
269 269 lx_err_fatal(char *msg, ...)
270 270 {
271 271 va_list ap;
272 272
273 273 assert(msg != NULL);
274 274
275 275 va_start(ap, msg);
276 276 i_lx_msg(STDERR_FILENO, msg, ap);
277 277 va_end(ap);
278 278 abort();
279 279 }
280 280
281 281 /*
282 282 * See if it is safe to alloca() sz bytes. Return 1 for yes, 0 for no.
283 283 */
284 284 int
285 285 lx_check_alloca(size_t sz)
286 286 {
287 287 uintptr_t sp = (uintptr_t)&sz;
288 288 uintptr_t end = sp - sz;
289 289
290 290 return ((end < sp) && (end >= stack_bottom));
291 291 }
292 292
293 293 /*PRINTFLIKE1*/
294 294 void
295 295 lx_unsupported(char *msg, ...)
296 296 {
297 297 va_list ap;
298 298 char dmsg[256];
299 299 int lastc;
300 300
301 301 assert(msg != NULL);
302 302
303 303 /* make a brand call so we can easily dtrace unsupported actions */
304 304 va_start(ap, msg);
305 305 /* LINTED [possible expansion issues] */
306 306 (void) vsnprintf(dmsg, sizeof (dmsg), msg, ap);
307 307 dmsg[255] = '\0';
308 308 lastc = strlen(dmsg) - 1;
309 309 if (dmsg[lastc] == '\n')
310 310 dmsg[lastc] = '\0';
311 311 (void) syscall(SYS_brand, B_UNSUPPORTED, dmsg);
312 312 va_end(ap);
313 313
314 314 /* send the msg to the error stream */
315 315 va_start(ap, msg);
316 316 i_lx_msg(STDERR_FILENO, msg, ap);
317 317 va_end(ap);
318 318 }
319 319
320 320 int lx_init(int argc, char *argv[], char *envp[]);
321 321
322 322 lx_tsd_t *
323 323 lx_get_tsd(void)
324 324 {
325 325 int ret;
326 326 lx_tsd_t *lx_tsd;
327 327
328 328 if ((ret = thr_getspecific(lx_tsd_key, (void **)&lx_tsd)) != 0) {
329 329 lx_err_fatal("lx_get_tsd: unable to read "
330 330 "thread-specific data: %s", strerror(ret));
331 331 }
332 332
333 333 assert(lx_tsd != 0);
334 334
335 335 return (lx_tsd);
336 336 }
337 337
338 338 /*
339 339 * This function is called from the kernel like a signal handler. Each
340 340 * function call is a request to provide emulation for a system call that, on
341 341 * illumos, is implemented in userland. The system call number selection and
342 342 * argument parsing have already been done by the kernel.
343 343 */
344 344 void
345 345 lx_emulate(ucontext_t *ucp, int syscall_num, uintptr_t *args)
346 346 {
347 347 long emu_ret;
348 348 int emu_errno = 0;
349 349
350 350 LX_EMULATE_ENTER(ucp, syscall_num, args);
351 351 lx_debug("lx_emulate(%p, %d, [%p, %p, %p, %p, %p, %p])\n",
352 352 ucp, syscall_num, args[0], args[1], args[2], args[3], args[4],
353 353 args[5]);
354 354
355 355 /*
356 356 * The kernel should have saved us a context that will not restore the
357 357 * previous signal mask. Some emulated system calls alter the signal
358 358 * mask; restoring it after the emulation would cancel that out.
359 359 */
360 360 assert(!(ucp->uc_flags & UC_SIGMASK));
361 361
362 362 /*
363 363 * The kernel ensures that the syscall_num is sane; Use it as is.
364 364 */
365 365 assert(syscall_num >= 0);
366 366 assert(syscall_num < (sizeof (lx_handlers) / sizeof (lx_handlers[0])));
367 367 if (lx_handlers[syscall_num] == NULL) {
368 368 lx_err_fatal("lx_emulate: kernel sent us a call we cannot "
369 369 "emulate (%d)", syscall_num);
370 370 }
371 371
372 372 /*
373 373 * Call our handler function:
374 374 */
375 375 emu_ret = lx_handlers[syscall_num](args[0], args[1], args[2], args[3],
376 376 args[4], args[5]);
377 377
378 378 /*
379 379 * If the return value is between -1 and -4095 then it's an errno.
380 380 * The kernel will translate it to the Linux equivalent for us.
381 381 */
382 382 if (emu_ret < 0 && emu_ret > -4096) {
383 383 emu_errno = (int)-emu_ret;
384 384 }
385 385
386 386 /*
387 387 * Return to the context we were passed
388 388 */
389 389 LX_EMULATE_RETURN(ucp, syscall_num, emu_ret, emu_errno);
390 390 lx_debug("\tlx_emulate(%d) done (ret %ld / 0x%p ; errno %d)",
391 391 syscall_num, emu_ret, emu_ret, emu_errno);
392 392 (void) syscall(SYS_brand, B_EMULATION_DONE, ucp, syscall_num, emu_ret,
393 393 emu_errno);
394 394
395 395 assert(!"cannot be returned here");
396 396 }
397 397
398 398 static void
399 399 lx_close_fh(FILE *file)
400 400 {
401 401 int fd, fd_new;
402 402
403 403 if (file == NULL)
404 404 return;
405 405
406 406 if ((fd = fileno(file)) < 0)
407 407 return;
408 408
409 409 fd_new = dup(fd);
410 410 if (fd_new == -1)
411 411 return;
412 412
413 413 (void) fclose(file);
414 414 (void) dup2(fd_new, fd);
415 415 (void) close(fd_new);
416 416 }
417 417
418 418
419 419 extern int set_l10n_alternate_root(char *path);
420 420
421 421 #if defined(_LP64)
422 422 static void *
423 423 map_vdso()
424 424 {
425 425 int fd;
426 426 mmapobj_result_t mpp[10]; /* we know the size of our lib */
427 427 mmapobj_result_t *smpp = mpp;
428 428 uint_t mapnum = 10;
429 429
430 430 if ((fd = open("/native/usr/lib/brand/lx/amd64/lx_vdso.so.1",
431 431 O_RDONLY)) == -1)
432 432 lx_err_fatal("couldn't open lx_vdso.so.1");
433 433
434 434 if (mmapobj(fd, MMOBJ_INTERPRET, smpp, &mapnum, NULL) == -1)
435 435 lx_err_fatal("couldn't mmapobj lx_vdso.so.1");
436 436
437 437 (void) close(fd);
438 438
439 439 /* assume first segment is the base of the mapping */
440 440 return (smpp->mr_addr);
441 441 }
442 442 #endif
443 443
444 444 /*
445 445 * Initialize the thread specific data for this thread.
446 446 */
447 447 void
448 448 lx_init_tsd(lx_tsd_t *lxtsd)
449 449 {
450 450 int err;
451 451
452 452 bzero(lxtsd, sizeof (*lxtsd));
453 453 lxtsd->lxtsd_exit = LX_ET_NONE;
454 454
455 455 /*
456 456 * The Linux alternate signal stack is initially disabled:
457 457 */
458 458 lxtsd->lxtsd_sigaltstack.ss_flags = LX_SS_DISABLE;
459 459
460 460 /*
461 461 * Create a per-thread exit context from the current register and
462 462 * native/brand stack state. Replace the saved program counter value
463 463 * with the address of lx_exit_common(); we wish to revector there when
464 464 * the thread or process is exiting.
465 465 */
466 466 if (getcontext(&lxtsd->lxtsd_exit_context) != 0) {
467 467 lx_err_fatal("Unable to initialize thread-specific exit "
468 468 "context: %s", strerror(errno));
469 469 }
470 470 LX_REG(&lxtsd->lxtsd_exit_context, REG_PC) = (uintptr_t)lx_exit_common;
471 471
472 472 /*
473 473 * Align the stack pointer and clear the frame pointer.
474 474 */
475 475 LX_REG(&lxtsd->lxtsd_exit_context, REG_FP) = 0;
476 476 LX_REG(&lxtsd->lxtsd_exit_context, REG_SP) &= ~(STACK_ALIGN - 1UL);
477 477 #if defined(_LP64)
478 478 #if (STACK_ENTRY_ALIGN != 8) && (STACK_ALIGN != 16)
479 479 #error "lx_init_tsd: unexpected STACK_[ENTRY_]ALIGN values"
480 480 #endif
481 481 /*
482 482 * The AMD64 ABI requires that, on entry to a function, the stack
483 483 * pointer must be 8-byte aligned, but _not_ 16-byte aligned. When
484 484 * the frame pointer is pushed, the alignment will then be correct.
485 485 */
486 486 LX_REG(&lxtsd->lxtsd_exit_context, REG_SP) -= STACK_ENTRY_ALIGN;
487 487 #endif
488 488
489 489 /*
490 490 * Block all signals in the exit context to avoid taking any signals
↓ open down ↓ |
490 lines elided |
↑ open up ↑ |
491 491 * (to the degree possible) while exiting.
492 492 */
493 493 (void) sigfillset(&lxtsd->lxtsd_exit_context.uc_sigmask);
494 494
495 495 if ((err = thr_setspecific(lx_tsd_key, lxtsd)) != 0) {
496 496 lx_err_fatal("Unable to initialize thread-specific data: %s",
497 497 strerror(err));
498 498 }
499 499 }
500 500
501 +void
502 +lx_jump_to_linux(ucontext_t *ucp)
503 +{
504 + extern void setcontext_sigmask(ucontext_t *);
505 +
506 + /*
507 + * Call into this private libc interface to allow us to use only the
508 + * signal mask handling part of a regular setcontext() operation.
509 + */
510 + setcontext_sigmask(ucp);
511 +
512 + if (syscall(SYS_brand, B_JUMP_TO_LINUX, ucp) != 0) {
513 + lx_err_fatal("B_JUMP_TO_LINUX failed: %s", strerror(errno));
514 + }
515 +
516 + /*
517 + * This system call should not return.
518 + */
519 + abort();
520 +}
521 +
501 522 static void
502 523 lx_start(uintptr_t sp, uintptr_t entry)
503 524 {
504 525 ucontext_t jump_uc;
505 526
506 527 if (getcontext(&jump_uc) != 0) {
507 528 lx_err_fatal("Unable to getcontext for program start: %s",
508 529 strerror(errno));
509 530 }
510 531
511 532 /*
512 533 * We want to load the general registers from this
513 534 * context, and switch to the BRAND stack.
514 535 */
515 536 jump_uc.uc_flags = UC_CPU;
516 537 jump_uc.uc_brand_data[0] = (void *)LX_UC_STACK_BRAND;
517 538
518 539 LX_REG(&jump_uc, REG_FP) = NULL;
519 540 LX_REG(&jump_uc, REG_SP) = sp;
520 541 LX_REG(&jump_uc, REG_PC) = entry;
521 542
522 543 #if defined(_LP64)
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
523 544 /*
524 545 * The AMD64 ABI states that at process entry, %rdx contains "a
525 546 * function pointer that the application should register with
526 547 * atexit()". We make sure to pass NULL explicitly so that
527 548 * no function is registered.
528 549 */
529 550 LX_REG(&jump_uc, REG_RDX) = NULL;
530 551 #endif
531 552
532 553 lx_debug("starting Linux program sp %p ldentry %p", sp, entry);
533 -
534 - /*
535 - * This system call should not return.
536 - */
537 - if (syscall(SYS_brand, B_JUMP_TO_LINUX, &jump_uc) == -1) {
538 - lx_err_fatal("B_JUMP_TO_LINUX failed: %s",
539 - strerror(errno));
540 - }
541 - abort();
554 + lx_jump_to_linux(&jump_uc);
542 555 }
543 556
544 557 /*ARGSUSED*/
545 558 int
546 559 lx_init(int argc, char *argv[], char *envp[])
547 560 {
548 561 char *r;
549 562 auxv_t *ap;
550 563 long *p;
551 564 int err;
552 565 lx_elf_data_t edp;
553 566 lx_brand_registration_t reg;
554 567 lx_tsd_t *lxtsd;
555 568 #if defined(_LP64)
556 569 void *vdso_hdr;
557 570 #endif
558 571
559 572 bzero(®, sizeof (reg));
560 573
561 574 stack_bottom = 2 * sysconf(_SC_PAGESIZE);
562 575
563 576 /*
564 577 * We need to shutdown all libc stdio. libc stdio normally goes to
565 578 * file descriptors, but since we're actually part of a linux
566 579 * process we don't own these file descriptors and we can't make
567 580 * any assumptions about their state.
568 581 */
569 582 lx_close_fh(stdin);
570 583 lx_close_fh(stdout);
571 584 lx_close_fh(stderr);
572 585
573 586 lx_debug_init();
574 587
575 588 r = getenv("LX_RELEASE");
576 589 if (r == NULL) {
577 590 if (zone_getattr(getzoneid(), LX_KERN_VERSION_NUM, lx_release,
578 591 sizeof (lx_release)) != sizeof (lx_release))
579 592 (void) strlcpy(lx_release, "2.4.21", LX_VERS_MAX);
580 593 } else {
581 594 (void) strlcpy(lx_release, r, 128);
582 595 }
583 596
584 597 lx_debug("lx_release: %s\n", lx_release);
585 598
586 599 /*
587 600 * Should we kill an application that attempts an unimplemented
588 601 * system call?
589 602 */
590 603 if (getenv("LX_STRICT") != NULL) {
591 604 reg.lxbr_flags |= LX_PROC_STRICT_MODE;
592 605 lx_debug("STRICT mode enabled.\n");
593 606 }
594 607
595 608 /*
596 609 * Are we in install mode?
597 610 */
598 611 if (getenv("LX_INSTALL") != NULL) {
599 612 reg.lxbr_flags |= LX_PROC_INSTALL_MODE;
600 613 lx_install = 1;
601 614 lx_debug("INSTALL mode enabled.\n");
602 615 }
603 616
604 617 /*
605 618 * Should we attempt to send messages to the screen?
606 619 */
607 620 if (getenv("LX_VERBOSE") != NULL) {
608 621 lx_verbose = 1;
609 622 lx_debug("VERBOSE mode enabled.\n");
610 623 }
611 624
612 625 (void) strlcpy(lx_cmd_name, basename(argv[0]), sizeof (lx_cmd_name));
613 626 lx_debug("executing linux process: %s", argv[0]);
614 627 lx_debug("branding myself and setting handler to 0x%p",
615 628 (void *)lx_emulate);
616 629
617 630 reg.lxbr_version = LX_VERSION;
618 631 reg.lxbr_handler = (void *)&lx_emulate;
619 632
620 633 /*
621 634 * Register the address of the user-space handler with the lx brand
622 635 * module. As a side-effect this leaves the thread in native syscall
623 636 * mode so that it's ok to continue to make syscalls during setup. We
624 637 * need to switch to Linux mode at the end of initialization.
625 638 */
626 639 if (syscall(SYS_brand, B_REGISTER, ®))
627 640 lx_err_fatal("failed to brand the process");
628 641
629 642 /* Look up the PID that serves as init for this zone */
630 643 if ((err = lx_lpid_to_spid(1, &zoneinit_pid)) < 0)
631 644 lx_err_fatal("Unable to find PID for zone init process: %s",
632 645 strerror(err));
633 646
634 647 /*
635 648 * Upload data about the lx executable from the kernel.
636 649 */
637 650 if (syscall(SYS_brand, B_ELFDATA, (void *)&edp))
638 651 lx_err_fatal("failed to get required ELF data from the kernel");
639 652
640 653 if (lx_stat_init() != 0)
641 654 lx_err_fatal("failed to setup the stat translator");
642 655
643 656 if (lx_statfs_init() != 0)
644 657 lx_err_fatal("failed to setup the statfs translator");
645 658
646 659 lx_ptrace_init();
647 660
648 661 #if defined(_LP64)
649 662 vdso_hdr = map_vdso();
650 663 #endif
651 664
652 665 /*
653 666 * Find the aux vector on the stack.
654 667 */
655 668 p = (long *)envp;
656 669 while (*p != NULL)
657 670 p++;
658 671 /*
659 672 * p is now pointing at the 0 word after the environ pointers. After
660 673 * that is the aux vectors.
661 674 */
662 675 p++;
663 676 for (ap = (auxv_t *)p; ap->a_type != 0; ap++) {
664 677 switch (ap->a_type) {
665 678 case AT_BASE:
666 679 ap->a_un.a_val = edp.ed_base;
667 680 break;
668 681 case AT_ENTRY:
669 682 ap->a_un.a_val = edp.ed_entry;
670 683 break;
671 684 case AT_PHDR:
672 685 ap->a_un.a_val = edp.ed_phdr;
673 686 break;
674 687 case AT_PHENT:
675 688 ap->a_un.a_val = edp.ed_phent;
676 689 break;
677 690 case AT_PHNUM:
678 691 ap->a_un.a_val = edp.ed_phnum;
679 692 break;
680 693 #if defined(_LP64)
681 694 case AT_SUN_BRAND_LX_SYSINFO_EHDR:
682 695 ap->a_type = AT_SYSINFO_EHDR;
683 696 ap->a_un.a_val = (long)vdso_hdr;
684 697 break;
685 698 #endif
686 699 default:
687 700 break;
688 701 }
689 702 }
690 703
691 704 /* Setup signal handler information. */
692 705 if (lx_siginit()) {
693 706 lx_err_fatal("failed to initialize lx signals for the "
694 707 "branded process");
695 708 }
696 709
697 710 /* Setup thread-specific data area for managing linux threads. */
698 711 if ((err = thr_keycreate(&lx_tsd_key, NULL)) != 0) {
699 712 lx_err_fatal("thr_keycreate(lx_tsd_key) failed: %s",
700 713 strerror(err));
701 714 }
702 715
703 716 lx_debug("thr_keycreate created lx_tsd_key (%d)", lx_tsd_key);
704 717
705 718 /*
706 719 * Initialize the thread specific data for this thread.
707 720 */
708 721 if ((lxtsd = malloc(sizeof (*lxtsd))) == NULL) {
709 722 lx_err_fatal("failed to allocate tsd for main thread: %s",
710 723 strerror(errno));
711 724 }
712 725 lx_debug("lx tsd allocated @ %p", lxtsd);
713 726 lx_init_tsd(lxtsd);
714 727
715 728 /*
716 729 * Allocate the brand emulation stack for the main process thread.
717 730 * Register the thread-specific data structure with the stack list so
718 731 * that it may be freed at thread exit or fork(2).
719 732 */
720 733 lx_install_stack(NULL, 0, lxtsd);
721 734
722 735 /*
723 736 * The brand linker expects the stack pointer to point to
724 737 * "argc", which is just before &argv[0].
725 738 */
726 739 lx_start((uintptr_t)argv - sizeof (void *), edp.ed_ldentry);
727 740
728 741 /*NOTREACHED*/
729 742 abort();
730 743 return (0);
731 744 }
732 745
733 746 /*
734 747 * We "return" to this function via a context hand-crafted by
735 748 * "lx_init_tsd()"; see that function for more detail.
736 749 *
737 750 * NOTE: Our call frame is on the main thread stack, not the alternate native
738 751 * stack -- it is safe to release the latter here. The frame does not have a
739 752 * valid return address, so this function MUST NOT return.
740 753 */
741 754 void
742 755 lx_exit_common(void)
743 756 {
744 757 lx_tsd_t *lxtsd = lx_get_tsd();
745 758 int ev = (0xff & lxtsd->lxtsd_exit_status);
746 759
747 760 switch (lxtsd->lxtsd_exit) {
748 761 case LX_ET_EXIT:
749 762 lx_debug("lx_exit_common(LX_ET_EXIT, %d)\n", ev);
750 763
751 764 /*
752 765 * If the thread is exiting, but not the entire process, we
753 766 * must free the stack we allocated for usermode emulation.
754 767 * This is safe to do here because the setcontext() put us
755 768 * back on the BRAND stack for this process. This function
756 769 * also frees the thread-specific data object for this thread.
757 770 */
758 771 lx_free_stack();
759 772
760 773 /*
761 774 * The native thread return value is never seen so we pass
762 775 * NULL.
763 776 */
764 777 thr_exit(NULL);
765 778 break;
766 779
767 780 case LX_ET_EXIT_GROUP:
768 781 lx_debug("lx_exit_common(LX_ET_EXIT_GROUP, %d)\n", ev);
769 782 exit(ev);
770 783 break;
771 784
772 785 default:
773 786 abort();
774 787 }
775 788
776 789 abort();
777 790 }
778 791
779 792 const ucontext_t *
780 793 lx_find_brand_uc(void)
781 794 {
782 795 ucontext_t *ucp = NULL;
783 796
784 797 /*
785 798 * Ask for the current emulation (or signal handling) ucontext_t...
786 799 */
787 800 assert(syscall(SYS_brand, B_GET_CURRENT_CONTEXT, &ucp) == 0);
788 801
789 802 for (;;) {
790 803 uintptr_t flags;
791 804
792 805 lx_debug("lx_find_brand_uc: inspect ucp %p...\n", ucp);
793 806 assert(ucp != NULL);
794 807
795 808 flags = (uintptr_t)ucp->uc_brand_data[0];
796 809
797 810 if (flags & LX_UC_STACK_BRAND) {
798 811 lx_debug("lx_find_brand_uc: ucp %p\n", ucp);
799 812
800 813 return (ucp);
801 814 }
802 815
803 816 lx_debug("lx_find_brand_uc: skip non-BRAND ucp %p\n", ucp);
804 817
805 818 /*
806 819 * Walk up the context chain to find the most recently stored
807 820 * brand register state.
808 821 */
809 822 ucp = ucp->uc_link;
810 823 }
811 824 }
812 825
813 826 uintptr_t
814 827 lx_find_brand_sp(void)
815 828 {
816 829 const ucontext_t *ucp = lx_find_brand_uc();
817 830 uintptr_t sp = LX_REG(ucp, REG_SP);
818 831
819 832 lx_debug("lx_find_brand_sp: ucp %p sp %p\n", ucp, sp);
820 833
821 834 return (sp);
822 835 }
823 836
824 837 ucontext_t *
825 838 lx_syscall_regs(void)
826 839 {
827 840 ucontext_t *ucp = NULL;
828 841 uintptr_t flags;
829 842
830 843 /*
831 844 * Ask for the current emulation (or signal handling) ucontext_t...
832 845 */
833 846 assert(syscall(SYS_brand, B_GET_CURRENT_CONTEXT, &ucp) == 0);
834 847 assert(ucp != NULL);
835 848
836 849 /*
837 850 * Use of the lx_syscall_regs() function implies that the topmost (i.e.
838 851 * current) context is for a system call emulation request from the
839 852 * kernel, rather than a signal handling frame.
840 853 */
841 854 flags = (uintptr_t)ucp->uc_brand_data[0];
842 855 assert(flags & LX_UC_FRAME_IS_SYSCALL);
843 856
844 857 lx_debug("lx_syscall_regs: ucp %p\n", ucp);
845 858
846 859 return (ucp);
847 860 }
848 861
849 862 int
850 863 lx_lpid_to_spair(pid_t lpid, pid_t *spid, lwpid_t *slwp)
851 864 {
852 865 pid_t pid;
853 866 lwpid_t tid;
854 867
855 868 if (lpid == 0) {
856 869 pid = getpid();
857 870 tid = thr_self();
858 871 } else {
859 872 if (syscall(SYS_brand, B_LPID_TO_SPAIR, lpid, &pid, &tid) < 0)
860 873 return (-errno);
861 874
862 875 /*
863 876 * If the returned pid is -1, that indicates we tried to
864 877 * look up the PID for init, but that process no longer
865 878 * exists.
866 879 */
867 880 if (pid == -1)
868 881 return (-ESRCH);
869 882 }
870 883
871 884 if (uucopy(&pid, spid, sizeof (pid_t)) != 0)
872 885 return (-errno);
873 886
874 887 if (uucopy(&tid, slwp, sizeof (lwpid_t)) != 0)
875 888 return (-errno);
876 889
877 890 return (0);
878 891 }
879 892
880 893 int
881 894 lx_lpid_to_spid(pid_t lpid, pid_t *spid)
882 895 {
883 896 lwpid_t slwp;
884 897
885 898 return (lx_lpid_to_spair(lpid, spid, &slwp));
886 899 }
887 900
888 901 char *
889 902 lx_fd_to_path(int fd, char *buf, int buf_size)
890 903 {
891 904 char path_proc[MAXPATHLEN];
892 905 pid_t pid;
893 906 int n;
894 907
895 908 assert((buf != NULL) && (buf_size >= 0));
896 909
897 910 if (fd < 0)
898 911 return (NULL);
899 912
900 913 if ((pid = getpid()) == -1)
901 914 return (NULL);
902 915
903 916 (void) snprintf(path_proc, MAXPATHLEN,
904 917 "/native/proc/%d/path/%d", pid, fd);
905 918
906 919 if ((n = readlink(path_proc, buf, buf_size - 1)) == -1)
907 920 return (NULL);
908 921 buf[n] = '\0';
909 922
910 923 return (buf);
911 924 }
912 925
913 926 #if defined(_LP64)
914 927 /* The following is the 64-bit syscall table */
915 928
916 929 static lx_syscall_handler_t lx_handlers[] = {
917 930 NULL, /* 0: read */
918 931 NULL, /* 1: write */
919 932 NULL, /* 2: open */
920 933 lx_close, /* 3: close */
921 934 lx_stat64, /* 4: stat */
922 935 lx_fstat64, /* 5: fstat */
923 936 lx_lstat64, /* 6: lstat */
924 937 lx_poll, /* 7: poll */
925 938 lx_lseek, /* 8: lseek */
926 939 lx_mmap, /* 9: mmap */
927 940 lx_mprotect, /* 10: mprotect */
928 941 lx_munmap, /* 11: munmap */
929 942 NULL, /* 12: brk */
930 943 lx_rt_sigaction, /* 13: rt_sigaction */
931 944 lx_rt_sigprocmask, /* 14: rt_sigprocmask */
932 945 lx_rt_sigreturn, /* 15: rt_sigreturn */
933 946 NULL, /* 16: ioctl */
934 947 lx_pread, /* 17: pread64 */
935 948 lx_pwrite, /* 18: pwrite64 */
936 949 lx_readv, /* 19: readv */
937 950 lx_writev, /* 20: writev */
938 951 lx_access, /* 21: access */
939 952 NULL, /* 22: pipe */
940 953 lx_select, /* 23: select */
941 954 NULL, /* 24: sched_yield */
942 955 lx_remap, /* 25: mremap */
943 956 lx_msync, /* 26: msync */
944 957 lx_mincore, /* 27: mincore */
945 958 lx_madvise, /* 28: madvise */
946 959 lx_shmget, /* 29: shmget */
947 960 lx_shmat, /* 30: shmat */
948 961 lx_shmctl, /* 31: shmctl */
949 962 lx_dup, /* 32: dup */
950 963 lx_dup2, /* 33: dup2 */
951 964 lx_pause, /* 34: pause */
952 965 lx_nanosleep, /* 35: nanosleep */
953 966 lx_getitimer, /* 36: getitimer */
954 967 lx_alarm, /* 37: alarm */
955 968 lx_setitimer, /* 38: setitimer */
956 969 NULL, /* 39: getpid */
957 970 lx_sendfile64, /* 40: sendfile */
958 971 lx_socket, /* 41: socket */
959 972 NULL, /* 42: connect */
960 973 lx_accept, /* 43: accept */
961 974 NULL, /* 44: sendto */
962 975 NULL, /* 45: recvfrom */
963 976 NULL, /* 46: sendmsg */
964 977 NULL, /* 47: recvmsg */
965 978 lx_shutdown, /* 48: shutdown */
966 979 NULL, /* 49: bind */
967 980 lx_listen, /* 50: listen */
968 981 lx_getsockname, /* 51: getsockname */
969 982 lx_getpeername, /* 52: getpeername */
970 983 lx_socketpair, /* 53: socketpair */
971 984 lx_setsockopt, /* 54: setsockopt */
972 985 lx_getsockopt, /* 55: getsockopt */
973 986 lx_clone, /* 56: clone */
974 987 lx_fork, /* 57: fork */
975 988 lx_vfork, /* 58: vfork */
976 989 lx_execve, /* 59: execve */
977 990 lx_exit, /* 60: exit */
978 991 NULL, /* 61: wait4 */
979 992 NULL, /* 62: kill */
980 993 lx_uname, /* 63: uname */
981 994 lx_semget, /* 64: semget */
982 995 lx_semop, /* 65: semop */
983 996 lx_semctl, /* 66: semctl */
984 997 lx_shmdt, /* 67: shmdt */
985 998 lx_msgget, /* 68: msgget */
986 999 lx_msgsnd, /* 69: msgsnd */
987 1000 lx_msgrcv, /* 70: msgrcv */
988 1001 lx_msgctl, /* 71: msgctl */
989 1002 NULL, /* 72: fcntl */
990 1003 lx_flock, /* 73: flock */
991 1004 lx_fsync, /* 74: fsync */
992 1005 lx_fdatasync, /* 75: fdatasync */
993 1006 lx_truncate, /* 76: truncate */
994 1007 lx_ftruncate, /* 77: ftruncate */
995 1008 NULL, /* 78: getdents */
996 1009 lx_getcwd, /* 79: getcwd */
997 1010 lx_chdir, /* 80: chdir */
998 1011 lx_fchdir, /* 81: fchdir */
999 1012 lx_rename, /* 82: rename */
1000 1013 NULL, /* 83: mkdir */
1001 1014 lx_rmdir, /* 84: rmdir */
1002 1015 lx_creat, /* 85: creat */
1003 1016 lx_link, /* 86: link */
1004 1017 lx_unlink, /* 87: unlink */
1005 1018 lx_symlink, /* 88: symlink */
1006 1019 lx_readlink, /* 89: readlink */
1007 1020 NULL, /* 90: chmod */
1008 1021 NULL, /* 91: fchmod */
1009 1022 NULL, /* 92: chown */
1010 1023 NULL, /* 93: fchown */
1011 1024 NULL, /* 94: lchown */
1012 1025 lx_umask, /* 95: umask */
1013 1026 NULL, /* 96: gettimeofday */
1014 1027 NULL, /* 97: getrlimit */
1015 1028 lx_getrusage, /* 98: getrusage */
1016 1029 NULL, /* 99: sysinfo */
1017 1030 lx_times, /* 100: times */
1018 1031 lx_ptrace, /* 101: ptrace */
1019 1032 lx_getuid, /* 102: getuid */
1020 1033 lx_syslog, /* 103: syslog */
1021 1034 lx_getgid, /* 104: getgid */
1022 1035 lx_setuid, /* 105: setuid */
1023 1036 lx_setgid, /* 106: setgid */
1024 1037 lx_geteuid, /* 107: geteuid */
1025 1038 lx_getegid, /* 108: getegid */
1026 1039 lx_setpgid, /* 109: setpgid */
1027 1040 NULL, /* 110: getppid */
1028 1041 lx_getpgrp, /* 111: getpgrp */
1029 1042 lx_setsid, /* 112: setsid */
1030 1043 lx_setreuid, /* 113: setreuid */
1031 1044 lx_setregid, /* 114: setregid */
1032 1045 lx_getgroups, /* 115: getgroups */
1033 1046 lx_setgroups, /* 116: setgroups */
1034 1047 NULL, /* 117: setresuid */
1035 1048 lx_getresuid, /* 118: getresuid */
1036 1049 NULL, /* 119: setresgid */
1037 1050 lx_getresgid, /* 120: getresgid */
1038 1051 lx_getpgid, /* 121: getpgid */
1039 1052 lx_setfsuid, /* 122: setfsuid */
1040 1053 lx_setfsgid, /* 123: setfsgid */
1041 1054 lx_getsid, /* 124: getsid */
1042 1055 lx_capget, /* 125: capget */
1043 1056 lx_capset, /* 126: capset */
1044 1057 lx_rt_sigpending, /* 127: rt_sigpending */
1045 1058 lx_rt_sigtimedwait, /* 128: rt_sigtimedwait */
1046 1059 lx_rt_sigqueueinfo, /* 129: rt_sigqueueinfo */
1047 1060 lx_rt_sigsuspend, /* 130: rt_sigsuspend */
1048 1061 lx_sigaltstack, /* 131: sigaltstack */
1049 1062 lx_utime, /* 132: utime */
1050 1063 lx_mknod, /* 133: mknod */
1051 1064 NULL, /* 134: uselib */
1052 1065 lx_personality, /* 135: personality */
1053 1066 NULL, /* 136: ustat */
1054 1067 lx_statfs, /* 137: statfs */
1055 1068 lx_fstatfs, /* 138: fstatfs */
1056 1069 lx_sysfs, /* 139: sysfs */
1057 1070 lx_getpriority, /* 140: getpriority */
1058 1071 lx_setpriority, /* 141: setpriority */
1059 1072 lx_sched_setparam, /* 142: sched_setparam */
1060 1073 lx_sched_getparam, /* 143: sched_getparam */
1061 1074 lx_sched_setscheduler, /* 144: sched_setscheduler */
1062 1075 lx_sched_getscheduler, /* 145: sched_getscheduler */
1063 1076 lx_sched_get_priority_max, /* 146: sched_get_priority_max */
1064 1077 lx_sched_get_priority_min, /* 147: sched_get_priority_min */
1065 1078 lx_sched_rr_get_interval, /* 148: sched_rr_get_interval */
1066 1079 lx_mlock, /* 149: mlock */
1067 1080 lx_munlock, /* 150: munlock */
1068 1081 lx_mlockall, /* 151: mlockall */
1069 1082 lx_munlockall, /* 152: munlockall */
1070 1083 lx_vhangup, /* 153: vhangup */
1071 1084 NULL, /* 154: modify_ldt */
1072 1085 NULL, /* 155: pivot_root */
1073 1086 lx_sysctl, /* 156: sysctl */
1074 1087 NULL, /* 157: prctl */
1075 1088 NULL, /* 158: arch_prctl */
1076 1089 lx_adjtimex, /* 159: adjtimex */
1077 1090 NULL, /* 160: setrlimit */
1078 1091 lx_chroot, /* 161: chroot */
1079 1092 lx_sync, /* 162: sync */
1080 1093 NULL, /* 163: acct */
1081 1094 lx_settimeofday, /* 164: settimeofday */
1082 1095 lx_mount, /* 165: mount */
1083 1096 lx_umount2, /* 166: umount2 */
1084 1097 NULL, /* 167: swapon */
1085 1098 NULL, /* 168: swapoff */
1086 1099 lx_reboot, /* 169: reboot */
1087 1100 lx_sethostname, /* 170: sethostname */
1088 1101 lx_setdomainname, /* 171: setdomainname */
1089 1102 NULL, /* 172: iopl */
1090 1103 NULL, /* 173: ioperm */
1091 1104 NULL, /* 174: create_module */
1092 1105 NULL, /* 175: init_module */
1093 1106 NULL, /* 176: delete_module */
1094 1107 NULL, /* 177: get_kernel_syms */
1095 1108 lx_query_module, /* 178: query_module */
1096 1109 NULL, /* 179: quotactl */
1097 1110 NULL, /* 180: nfsservctl */
1098 1111 NULL, /* 181: getpmsg */
1099 1112 NULL, /* 182: putpmsg */
1100 1113 NULL, /* 183: afs_syscall */
1101 1114 NULL, /* 184: tux */
1102 1115 NULL, /* 185: security */
1103 1116 NULL, /* 186: gettid */
1104 1117 NULL, /* 187: readahead */
1105 1118 NULL, /* 188: setxattr */
1106 1119 NULL, /* 189: lsetxattr */
1107 1120 NULL, /* 190: fsetxattr */
1108 1121 NULL, /* 191: getxattr */
1109 1122 NULL, /* 192: lgetxattr */
1110 1123 NULL, /* 193: fgetxattr */
1111 1124 NULL, /* 194: listxattr */
1112 1125 NULL, /* 195: llistxattr */
1113 1126 NULL, /* 196: flistxattr */
1114 1127 NULL, /* 197: removexattr */
1115 1128 NULL, /* 198: lremovexattr */
1116 1129 NULL, /* 199: fremovexattr */
1117 1130 NULL, /* 200: tkill */
1118 1131 NULL, /* 201: time */
1119 1132 NULL, /* 202: futex */
1120 1133 lx_sched_setaffinity, /* 203: sched_setaffinity */
1121 1134 lx_sched_getaffinity, /* 204: sched_getaffinity */
1122 1135 NULL, /* 205: set_thread_area */
1123 1136 lx_io_setup, /* 206: io_setup */
1124 1137 lx_io_destroy, /* 207: io_destroy */
1125 1138 lx_io_getevents, /* 208: io_getevents */
1126 1139 lx_io_submit, /* 209: io_submit */
1127 1140 lx_io_cancel, /* 210: io_cancel */
1128 1141 NULL, /* 211: get_thread_area */
1129 1142 NULL, /* 212: lookup_dcookie */
1130 1143 lx_epoll_create, /* 213: epoll_create */
1131 1144 NULL, /* 214: epoll_ctl_old */
1132 1145 NULL, /* 215: epoll_wait_old */
1133 1146 NULL, /* 216: remap_file_pages */
1134 1147 NULL, /* 217: getdents64 */
1135 1148 NULL, /* 218: set_tid_address */
1136 1149 NULL, /* 219: restart_syscall */
1137 1150 lx_semtimedop, /* 220: semtimedop */
1138 1151 lx_fadvise64_64, /* 221: fadvise64 */
1139 1152 lx_timer_create, /* 222: timer_create */
1140 1153 lx_timer_settime, /* 223: timer_settime */
1141 1154 lx_timer_gettime, /* 224: timer_gettime */
1142 1155 lx_timer_getoverrun, /* 225: timer_getoverrun */
1143 1156 lx_timer_delete, /* 226: timer_delete */
1144 1157 NULL, /* 227: clock_settime */
1145 1158 NULL, /* 228: clock_gettime */
1146 1159 NULL, /* 229: clock_getres */
1147 1160 lx_clock_nanosleep, /* 230: clock_nanosleep */
1148 1161 lx_group_exit, /* 231: exit_group */
1149 1162 lx_epoll_wait, /* 232: epoll_wait */
1150 1163 lx_epoll_ctl, /* 233: epoll_ctl */
1151 1164 NULL, /* 234: tgkill */
1152 1165 lx_utimes, /* 235: utimes */
1153 1166 NULL, /* 236: vserver */
1154 1167 NULL, /* 237: mbind */
1155 1168 NULL, /* 238: set_mempolicy */
1156 1169 NULL, /* 239: get_mempolicy */
1157 1170 NULL, /* 240: mq_open */
1158 1171 NULL, /* 241: mq_unlink */
1159 1172 NULL, /* 242: mq_timedsend */
1160 1173 NULL, /* 243: mq_timedreceive */
1161 1174 NULL, /* 244: mq_notify */
1162 1175 NULL, /* 245: mq_getsetattr */
1163 1176 NULL, /* 246: kexec_load */
1164 1177 NULL, /* 247: waitid */
1165 1178 NULL, /* 248: add_key */
1166 1179 NULL, /* 249: request_key */
1167 1180 NULL, /* 250: keyctl */
1168 1181 NULL, /* 251: ioprio_set */
1169 1182 NULL, /* 252: ioprio_get */
1170 1183 lx_inotify_init, /* 253: inotify_init */
1171 1184 lx_inotify_add_watch, /* 254: inotify_add_watch */
1172 1185 lx_inotify_rm_watch, /* 255: inotify_rm_watch */
1173 1186 NULL, /* 256: migrate_pages */
1174 1187 NULL, /* 257: openat */
1175 1188 NULL, /* 258: mkdirat */
1176 1189 lx_mknodat, /* 259: mknodat */
1177 1190 NULL, /* 260: fchownat */
1178 1191 lx_futimesat, /* 261: futimesat */
1179 1192 lx_fstatat64, /* 262: fstatat64 */
1180 1193 lx_unlinkat, /* 263: unlinkat */
1181 1194 lx_renameat, /* 264: renameat */
1182 1195 lx_linkat, /* 265: linkat */
1183 1196 lx_symlinkat, /* 266: symlinkat */
1184 1197 lx_readlinkat, /* 267: readlinkat */
1185 1198 NULL, /* 268: fchmodat */
1186 1199 lx_faccessat, /* 269: faccessat */
1187 1200 lx_pselect6, /* 270: pselect6 */
1188 1201 lx_ppoll, /* 271: ppoll */
1189 1202 NULL, /* 272: unshare */
1190 1203 NULL, /* 273: set_robust_list */
1191 1204 NULL, /* 274: get_robust_list */
1192 1205 NULL, /* 275: splice */
1193 1206 NULL, /* 276: tee */
1194 1207 NULL, /* 277: sync_file_range */
1195 1208 NULL, /* 278: vmsplice */
1196 1209 NULL, /* 279: move_pages */
1197 1210 lx_utimensat, /* 280: utimensat */
1198 1211 lx_epoll_pwait, /* 281: epoll_pwait */
1199 1212 lx_signalfd, /* 282: signalfd */
1200 1213 lx_timerfd_create, /* 283: timerfd_create */
1201 1214 lx_eventfd, /* 284: eventfd */
1202 1215 NULL, /* 285: fallocate */
1203 1216 lx_timerfd_settime, /* 286: timerfd_settime */
1204 1217 lx_timerfd_gettime, /* 287: timerfd_gettime */
1205 1218 lx_accept4, /* 288: accept4 */
1206 1219 lx_signalfd4, /* 289: signalfd4 */
1207 1220 lx_eventfd2, /* 290: eventfd2 */
1208 1221 lx_epoll_create1, /* 291: epoll_create1 */
1209 1222 lx_dup3, /* 292: dup3 */
1210 1223 NULL, /* 293: pipe2 */
1211 1224 lx_inotify_init1, /* 294: inotify_init1 */
1212 1225 lx_preadv, /* 295: preadv */
1213 1226 lx_pwritev, /* 296: pwritev */
1214 1227 lx_rt_tgsigqueueinfo, /* 297: rt_tgsigqueueinfo */
1215 1228 NULL, /* 298: perf_event_open */
1216 1229 NULL, /* 299: recvmmsg */
1217 1230 NULL, /* 300: fanotify_init */
1218 1231 NULL, /* 301: fanotify_mark */
1219 1232 NULL, /* 302: prlimit64 */
1220 1233 NULL, /* 303: name_to_handle_at */
1221 1234 NULL, /* 304: open_by_handle_at */
1222 1235 NULL, /* 305: clock_adjtime */
1223 1236 NULL, /* 306: syncfs */
1224 1237 NULL, /* 307: sendmmsg */
1225 1238 NULL, /* 309: setns */
1226 1239 NULL, /* 309: getcpu */
1227 1240 NULL, /* 310: process_vm_readv */
1228 1241 NULL, /* 311: process_vm_writev */
1229 1242 NULL, /* 312: kcmp */
1230 1243 NULL, /* 313: finit_module */
1231 1244 NULL, /* 314: sched_setattr */
1232 1245 NULL, /* 315: sched_getattr */
1233 1246 NULL, /* 316: renameat2 */
1234 1247 NULL, /* 317: seccomp */
1235 1248 NULL, /* 318: getrandom */
1236 1249 NULL, /* 319: memfd_create */
1237 1250 NULL, /* 320: kexec_file_load */
1238 1251 NULL, /* 321: bpf */
1239 1252 NULL, /* 322: execveat */
1240 1253
1241 1254 /* XXX TBD gap then x32 syscalls from 512 - 544 */
1242 1255 };
1243 1256
1244 1257 #else
1245 1258 /* The following is the 32-bit syscall table */
1246 1259
1247 1260 static lx_syscall_handler_t lx_handlers[] = {
1248 1261 NULL, /* 0: nosys */
1249 1262 lx_exit, /* 1: exit */
1250 1263 lx_fork, /* 2: fork */
1251 1264 NULL, /* 3: read */
1252 1265 NULL, /* 4: write */
1253 1266 NULL, /* 5: open */
1254 1267 lx_close, /* 6: close */
1255 1268 NULL, /* 7: waitpid */
1256 1269 lx_creat, /* 8: creat */
1257 1270 lx_link, /* 9: link */
1258 1271 lx_unlink, /* 10: unlink */
1259 1272 lx_execve, /* 11: execve */
1260 1273 lx_chdir, /* 12: chdir */
1261 1274 NULL, /* 13: time */
1262 1275 lx_mknod, /* 14: mknod */
1263 1276 NULL, /* 15: chmod */
1264 1277 NULL, /* 16: lchown16 */
1265 1278 NULL, /* 17: break */
1266 1279 NULL, /* 18: stat */
1267 1280 lx_lseek, /* 19: lseek */
1268 1281 NULL, /* 20: getpid */
1269 1282 lx_mount, /* 21: mount */
1270 1283 lx_umount, /* 22: umount */
1271 1284 lx_setuid16, /* 23: setuid16 */
1272 1285 lx_getuid16, /* 24: getuid16 */
1273 1286 lx_stime, /* 25: stime */
1274 1287 lx_ptrace, /* 26: ptrace */
1275 1288 lx_alarm, /* 27: alarm */
1276 1289 NULL, /* 28: fstat */
1277 1290 lx_pause, /* 29: pause */
1278 1291 lx_utime, /* 30: utime */
1279 1292 NULL, /* 31: stty */
1280 1293 NULL, /* 32: gtty */
1281 1294 lx_access, /* 33: access */
1282 1295 lx_nice, /* 34: nice */
1283 1296 NULL, /* 35: ftime */
1284 1297 lx_sync, /* 36: sync */
1285 1298 NULL, /* 37: kill */
1286 1299 lx_rename, /* 38: rename */
1287 1300 NULL, /* 39: mkdir */
1288 1301 lx_rmdir, /* 40: rmdir */
1289 1302 lx_dup, /* 41: dup */
1290 1303 NULL, /* 42: pipe */
1291 1304 lx_times, /* 43: times */
1292 1305 NULL, /* 44: prof */
1293 1306 NULL, /* 45: brk */
1294 1307 lx_setgid16, /* 46: setgid16 */
1295 1308 lx_getgid16, /* 47: getgid16 */
1296 1309 lx_signal, /* 48: signal */
1297 1310 lx_geteuid16, /* 49: geteuid16 */
1298 1311 lx_getegid16, /* 50: getegid16 */
1299 1312 NULL, /* 51: acct */
1300 1313 lx_umount2, /* 52: umount2 */
1301 1314 NULL, /* 53: lock */
1302 1315 NULL, /* 54: ioctl */
1303 1316 NULL, /* 55: fcntl */
1304 1317 NULL, /* 56: mpx */
1305 1318 lx_setpgid, /* 57: setpgid */
1306 1319 NULL, /* 58: ulimit */
1307 1320 NULL, /* 59: olduname */
1308 1321 lx_umask, /* 60: umask */
1309 1322 lx_chroot, /* 61: chroot */
1310 1323 NULL, /* 62: ustat */
1311 1324 lx_dup2, /* 63: dup2 */
1312 1325 NULL, /* 64: getppid */
1313 1326 lx_getpgrp, /* 65: getpgrp */
1314 1327 lx_setsid, /* 66: setsid */
1315 1328 lx_sigaction, /* 67: sigaction */
1316 1329 NULL, /* 68: sgetmask */
1317 1330 NULL, /* 69: ssetmask */
1318 1331 lx_setreuid16, /* 70: setreuid16 */
1319 1332 lx_setregid16, /* 71: setregid16 */
1320 1333 lx_sigsuspend, /* 72: sigsuspend */
1321 1334 lx_sigpending, /* 73: sigpending */
1322 1335 lx_sethostname, /* 74: sethostname */
1323 1336 NULL, /* 75: setrlimit */
1324 1337 NULL, /* 76: getrlimit */
1325 1338 lx_getrusage, /* 77: getrusage */
1326 1339 NULL, /* 78: gettimeofday */
1327 1340 lx_settimeofday, /* 79: settimeofday */
1328 1341 lx_getgroups16, /* 80: getgroups16 */
1329 1342 lx_setgroups16, /* 81: setgroups16 */
1330 1343 NULL, /* 82: select */
1331 1344 lx_symlink, /* 83: symlink */
1332 1345 NULL, /* 84: oldlstat */
1333 1346 lx_readlink, /* 85: readlink */
1334 1347 NULL, /* 86: uselib */
1335 1348 NULL, /* 87: swapon */
1336 1349 lx_reboot, /* 88: reboot */
1337 1350 lx_readdir, /* 89: readdir */
1338 1351 lx_mmap, /* 90: mmap */
1339 1352 lx_munmap, /* 91: munmap */
1340 1353 lx_truncate, /* 92: truncate */
1341 1354 lx_ftruncate, /* 93: ftruncate */
1342 1355 NULL, /* 94: fchmod */
1343 1356 NULL, /* 95: fchown16 */
1344 1357 lx_getpriority, /* 96: getpriority */
1345 1358 lx_setpriority, /* 97: setpriority */
1346 1359 NULL, /* 98: profil */
1347 1360 lx_statfs, /* 99: statfs */
1348 1361 lx_fstatfs, /* 100: fstatfs */
1349 1362 NULL, /* 101: ioperm */
1350 1363 lx_socketcall, /* 102: socketcall */
1351 1364 lx_syslog, /* 103: syslog */
1352 1365 lx_setitimer, /* 104: setitimer */
1353 1366 lx_getitimer, /* 105: getitimer */
1354 1367 lx_stat, /* 106: stat */
1355 1368 lx_lstat, /* 107: lstat */
1356 1369 lx_fstat, /* 108: fstat */
1357 1370 NULL, /* 109: uname */
1358 1371 NULL, /* 110: oldiopl */
1359 1372 lx_vhangup, /* 111: vhangup */
1360 1373 NULL, /* 112: idle */
1361 1374 NULL, /* 113: vm86old */
1362 1375 NULL, /* 114: wait4 */
1363 1376 NULL, /* 115: swapoff */
1364 1377 NULL, /* 116: sysinfo */
1365 1378 lx_ipc, /* 117: ipc */
1366 1379 lx_fsync, /* 118: fsync */
1367 1380 lx_sigreturn, /* 119: sigreturn */
1368 1381 lx_clone, /* 120: clone */
1369 1382 lx_setdomainname, /* 121: setdomainname */
1370 1383 lx_uname, /* 122: uname */
1371 1384 NULL, /* 123: modify_ldt */
1372 1385 lx_adjtimex, /* 124: adjtimex */
1373 1386 lx_mprotect, /* 125: mprotect */
1374 1387 lx_sigprocmask, /* 126: sigprocmask */
1375 1388 NULL, /* 127: create_module */
1376 1389 NULL, /* 128: init_module */
1377 1390 NULL, /* 129: delete_module */
1378 1391 NULL, /* 130: get_kernel_syms */
1379 1392 NULL, /* 131: quotactl */
1380 1393 lx_getpgid, /* 132: getpgid */
1381 1394 lx_fchdir, /* 133: fchdir */
1382 1395 NULL, /* 134: bdflush */
1383 1396 lx_sysfs, /* 135: sysfs */
1384 1397 lx_personality, /* 136: personality */
1385 1398 NULL, /* 137: afs_syscall */
1386 1399 lx_setfsuid16, /* 138: setfsuid16 */
1387 1400 lx_setfsgid16, /* 139: setfsgid16 */
1388 1401 lx_llseek, /* 140: llseek */
1389 1402 NULL, /* 141: getdents */
1390 1403 lx_select, /* 142: select */
1391 1404 lx_flock, /* 143: flock */
1392 1405 lx_msync, /* 144: msync */
1393 1406 lx_readv, /* 145: readv */
1394 1407 lx_writev, /* 146: writev */
1395 1408 lx_getsid, /* 147: getsid */
1396 1409 lx_fdatasync, /* 148: fdatasync */
1397 1410 lx_sysctl, /* 149: sysctl */
1398 1411 lx_mlock, /* 150: mlock */
1399 1412 lx_munlock, /* 151: munlock */
1400 1413 lx_mlockall, /* 152: mlockall */
1401 1414 lx_munlockall, /* 153: munlockall */
1402 1415 lx_sched_setparam, /* 154: sched_setparam */
1403 1416 lx_sched_getparam, /* 155: sched_getparam */
1404 1417 lx_sched_setscheduler, /* 156: sched_setscheduler */
1405 1418 lx_sched_getscheduler, /* 157: sched_getscheduler */
1406 1419 NULL, /* 158: sched_yield */
1407 1420 lx_sched_get_priority_max, /* 159: sched_get_priority_max */
1408 1421 lx_sched_get_priority_min, /* 160: sched_get_priority_min */
1409 1422 lx_sched_rr_get_interval, /* 161: sched_rr_get_interval */
1410 1423 lx_nanosleep, /* 162: nanosleep */
1411 1424 lx_remap, /* 163: mremap */
1412 1425 NULL, /* 164: setresuid16 */
1413 1426 lx_getresuid16, /* 165: getresuid16 */
1414 1427 NULL, /* 166: vm86 */
1415 1428 lx_query_module, /* 167: query_module */
1416 1429 lx_poll, /* 168: poll */
1417 1430 NULL, /* 169: nfsservctl */
1418 1431 NULL, /* 170: setresgid16 */
1419 1432 lx_getresgid16, /* 171: getresgid16 */
1420 1433 NULL, /* 172: prctl */
1421 1434 lx_rt_sigreturn, /* 173: rt_sigreturn */
1422 1435 lx_rt_sigaction, /* 174: rt_sigaction */
1423 1436 lx_rt_sigprocmask, /* 175: rt_sigprocmask */
1424 1437 lx_rt_sigpending, /* 176: rt_sigpending */
1425 1438 lx_rt_sigtimedwait, /* 177: rt_sigtimedwait */
1426 1439 lx_rt_sigqueueinfo, /* 178: rt_sigqueueinfo */
1427 1440 lx_rt_sigsuspend, /* 179: rt_sigsuspend */
1428 1441 lx_pread64, /* 180: pread64 */
1429 1442 lx_pwrite64, /* 181: pwrite64 */
1430 1443 NULL, /* 182: chown16 */
1431 1444 lx_getcwd, /* 183: getcwd */
1432 1445 lx_capget, /* 184: capget */
1433 1446 lx_capset, /* 185: capset */
1434 1447 lx_sigaltstack, /* 186: sigaltstack */
1435 1448 lx_sendfile, /* 187: sendfile */
1436 1449 NULL, /* 188: getpmsg */
1437 1450 NULL, /* 189: putpmsg */
1438 1451 lx_vfork, /* 190: vfork */
1439 1452 NULL, /* 191: getrlimit */
1440 1453 lx_mmap2, /* 192: mmap2 */
1441 1454 lx_truncate64, /* 193: truncate64 */
1442 1455 lx_ftruncate64, /* 194: ftruncate64 */
1443 1456 lx_stat64, /* 195: stat64 */
1444 1457 lx_lstat64, /* 196: lstat64 */
1445 1458 lx_fstat64, /* 197: fstat64 */
1446 1459 NULL, /* 198: lchown */
1447 1460 lx_getuid, /* 199: getuid */
1448 1461 lx_getgid, /* 200: getgid */
1449 1462 lx_geteuid, /* 201: geteuid */
1450 1463 lx_getegid, /* 202: getegid */
1451 1464 lx_setreuid, /* 203: setreuid */
1452 1465 lx_setregid, /* 204: setregid */
1453 1466 lx_getgroups, /* 205: getgroups */
1454 1467 lx_setgroups, /* 206: setgroups */
1455 1468 NULL, /* 207: fchown */
1456 1469 NULL, /* 208: setresuid */
1457 1470 lx_getresuid, /* 209: getresuid */
1458 1471 NULL, /* 210: setresgid */
1459 1472 lx_getresgid, /* 211: getresgid */
1460 1473 NULL, /* 212: chown */
1461 1474 lx_setuid, /* 213: setuid */
1462 1475 lx_setgid, /* 214: setgid */
1463 1476 lx_setfsuid, /* 215: setfsuid */
1464 1477 lx_setfsgid, /* 216: setfsgid */
1465 1478 NULL, /* 217: pivot_root */
1466 1479 lx_mincore, /* 218: mincore */
1467 1480 lx_madvise, /* 219: madvise */
1468 1481 NULL, /* 220: getdents64 */
1469 1482 NULL, /* 221: fcntl64 */
1470 1483 NULL, /* 222: tux */
1471 1484 NULL, /* 223: security */
1472 1485 NULL, /* 224: gettid */
1473 1486 NULL, /* 225: readahead */
1474 1487 NULL, /* 226: setxattr */
1475 1488 NULL, /* 227: lsetxattr */
1476 1489 NULL, /* 228: fsetxattr */
1477 1490 NULL, /* 229: getxattr */
1478 1491 NULL, /* 230: lgetxattr */
1479 1492 NULL, /* 231: fgetxattr */
1480 1493 NULL, /* 232: listxattr */
1481 1494 NULL, /* 233: llistxattr */
1482 1495 NULL, /* 234: flistxattr */
1483 1496 NULL, /* 235: removexattr */
1484 1497 NULL, /* 236: lremovexattr */
1485 1498 NULL, /* 237: fremovexattr */
1486 1499 NULL, /* 238: tkill */
1487 1500 lx_sendfile64, /* 239: sendfile64 */
1488 1501 NULL, /* 240: futex */
1489 1502 lx_sched_setaffinity, /* 241: sched_setaffinity */
1490 1503 lx_sched_getaffinity, /* 242: sched_getaffinity */
1491 1504 NULL, /* 243: set_thread_area */
1492 1505 NULL, /* 244: get_thread_area */
1493 1506 lx_io_setup, /* 245: io_setup */
1494 1507 lx_io_destroy, /* 246: io_destroy */
1495 1508 lx_io_getevents, /* 247: io_getevents */
1496 1509 lx_io_submit, /* 248: io_submit */
1497 1510 lx_io_cancel, /* 249: io_cancel */
1498 1511 lx_fadvise64, /* 250: fadvise64 */
1499 1512 NULL, /* 251: nosys */
1500 1513 lx_group_exit, /* 252: group_exit */
1501 1514 NULL, /* 253: lookup_dcookie */
1502 1515 lx_epoll_create, /* 254: epoll_create */
1503 1516 lx_epoll_ctl, /* 255: epoll_ctl */
1504 1517 lx_epoll_wait, /* 256: epoll_wait */
1505 1518 NULL, /* 257: remap_file_pages */
1506 1519 NULL, /* 258: set_tid_address */
1507 1520 lx_timer_create, /* 259: timer_create */
1508 1521 lx_timer_settime, /* 260: timer_settime */
1509 1522 lx_timer_gettime, /* 261: timer_gettime */
1510 1523 lx_timer_getoverrun, /* 262: timer_getoverrun */
1511 1524 lx_timer_delete, /* 263: timer_delete */
1512 1525 NULL, /* 264: clock_settime */
1513 1526 NULL, /* 265: clock_gettime */
1514 1527 NULL, /* 266: clock_getres */
1515 1528 lx_clock_nanosleep, /* 267: clock_nanosleep */
1516 1529 lx_statfs64, /* 268: statfs64 */
1517 1530 lx_fstatfs64, /* 269: fstatfs64 */
1518 1531 NULL, /* 270: tgkill */
1519 1532 lx_utimes, /* 271: utimes */
1520 1533 lx_fadvise64_64, /* 272: fadvise64_64 */
1521 1534 NULL, /* 273: vserver */
1522 1535 NULL, /* 274: mbind */
1523 1536 NULL, /* 275: get_mempolicy */
1524 1537 NULL, /* 276: set_mempolicy */
1525 1538 NULL, /* 277: mq_open */
1526 1539 NULL, /* 278: mq_unlink */
1527 1540 NULL, /* 279: mq_timedsend */
1528 1541 NULL, /* 280: mq_timedreceive */
1529 1542 NULL, /* 281: mq_notify */
1530 1543 NULL, /* 282: mq_getsetattr */
1531 1544 NULL, /* 283: kexec_load */
1532 1545 NULL, /* 284: waitid */
1533 1546 NULL, /* 285: sys_setaltroot */
1534 1547 NULL, /* 286: add_key */
1535 1548 NULL, /* 287: request_key */
1536 1549 NULL, /* 288: keyctl */
1537 1550 NULL, /* 289: ioprio_set */
1538 1551 NULL, /* 290: ioprio_get */
1539 1552 lx_inotify_init, /* 291: inotify_init */
1540 1553 lx_inotify_add_watch, /* 292: inotify_add_watch */
1541 1554 lx_inotify_rm_watch, /* 293: inotify_rm_watch */
1542 1555 NULL, /* 294: migrate_pages */
1543 1556 NULL, /* 295: openat */
1544 1557 NULL, /* 296: mkdirat */
1545 1558 lx_mknodat, /* 297: mknodat */
1546 1559 NULL, /* 298: fchownat */
1547 1560 lx_futimesat, /* 299: futimesat */
1548 1561 lx_fstatat64, /* 300: fstatat64 */
1549 1562 lx_unlinkat, /* 301: unlinkat */
1550 1563 lx_renameat, /* 302: renameat */
1551 1564 lx_linkat, /* 303: linkat */
1552 1565 lx_symlinkat, /* 304: symlinkat */
1553 1566 lx_readlinkat, /* 305: readlinkat */
1554 1567 NULL, /* 306: fchmodat */
1555 1568 lx_faccessat, /* 307: faccessat */
1556 1569 lx_pselect6, /* 308: pselect6 */
1557 1570 lx_ppoll, /* 309: ppoll */
1558 1571 NULL, /* 310: unshare */
1559 1572 NULL, /* 311: set_robust_list */
1560 1573 NULL, /* 312: get_robust_list */
1561 1574 NULL, /* 313: splice */
1562 1575 NULL, /* 314: sync_file_range */
1563 1576 NULL, /* 315: tee */
1564 1577 NULL, /* 316: vmsplice */
1565 1578 NULL, /* 317: move_pages */
1566 1579 NULL, /* 318: getcpu */
1567 1580 lx_epoll_pwait, /* 319: epoll_pwait */
1568 1581 lx_utimensat, /* 320: utimensat */
1569 1582 lx_signalfd, /* 321: signalfd */
1570 1583 lx_timerfd_create, /* 322: timerfd_create */
1571 1584 lx_eventfd, /* 323: eventfd */
1572 1585 NULL, /* 324: fallocate */
1573 1586 lx_timerfd_settime, /* 325: timerfd_settime */
1574 1587 lx_timerfd_gettime, /* 326: timerfd_gettime */
1575 1588 lx_signalfd4, /* 327: signalfd4 */
1576 1589 lx_eventfd2, /* 328: eventfd2 */
1577 1590 lx_epoll_create1, /* 329: epoll_create1 */
1578 1591 lx_dup3, /* 330: dup3 */
1579 1592 NULL, /* 331: pipe2 */
1580 1593 lx_inotify_init1, /* 332: inotify_init1 */
1581 1594 lx_preadv, /* 333: preadv */
1582 1595 lx_pwritev, /* 334: pwritev */
1583 1596 lx_rt_tgsigqueueinfo, /* 335: rt_tgsigqueueinfo */
1584 1597 NULL, /* 336: perf_event_open */
1585 1598 NULL, /* 337: recvmmsg */
1586 1599 NULL, /* 338: fanotify_init */
1587 1600 NULL, /* 339: fanotify_mark */
1588 1601 NULL, /* 340: prlimit64 */
1589 1602 NULL, /* 341: name_to_handle_at */
1590 1603 NULL, /* 342: open_by_handle_at */
1591 1604 NULL, /* 343: clock_adjtime */
1592 1605 NULL, /* 344: syncfs */
1593 1606 NULL, /* 345: sendmmsg */
1594 1607 NULL, /* 346: setns */
1595 1608 NULL, /* 347: process_vm_readv */
1596 1609 NULL, /* 348: process_vm_writev */
1597 1610 NULL, /* 349: kcmp */
1598 1611 NULL, /* 350: finit_module */
1599 1612 NULL, /* 351: sched_setattr */
1600 1613 NULL, /* 352: sched_getattr */
1601 1614 NULL, /* 353: renameat2 */
1602 1615 NULL, /* 354: seccomp */
1603 1616 NULL, /* 355: getrandom */
1604 1617 NULL, /* 356: memfd_create */
1605 1618 NULL, /* 357: bpf */
1606 1619 NULL, /* 358: execveat */
1607 1620 };
1608 1621 #endif
↓ open down ↓ |
1057 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX