481 /*
482 * The AMD64 ABI requires that, on entry to a function, the stack
483 * pointer must be 8-byte aligned, but _not_ 16-byte aligned. When
484 * the frame pointer is pushed, the alignment will then be correct.
485 */
486 LX_REG(&lxtsd->lxtsd_exit_context, REG_SP) -= STACK_ENTRY_ALIGN;
487 #endif
488
489 /*
490 * Block all signals in the exit context to avoid taking any signals
491 * (to the degree possible) while exiting.
492 */
493 (void) sigfillset(&lxtsd->lxtsd_exit_context.uc_sigmask);
494
495 if ((err = thr_setspecific(lx_tsd_key, lxtsd)) != 0) {
496 lx_err_fatal("Unable to initialize thread-specific data: %s",
497 strerror(err));
498 }
499 }
500
501 static void
502 lx_start(uintptr_t sp, uintptr_t entry)
503 {
504 ucontext_t jump_uc;
505
506 if (getcontext(&jump_uc) != 0) {
507 lx_err_fatal("Unable to getcontext for program start: %s",
508 strerror(errno));
509 }
510
511 /*
512 * We want to load the general registers from this
513 * context, and switch to the BRAND stack.
514 */
515 jump_uc.uc_flags = UC_CPU;
516 jump_uc.uc_brand_data[0] = (void *)LX_UC_STACK_BRAND;
517
518 LX_REG(&jump_uc, REG_FP) = NULL;
519 LX_REG(&jump_uc, REG_SP) = sp;
520 LX_REG(&jump_uc, REG_PC) = entry;
521
522 #if defined(_LP64)
523 /*
524 * The AMD64 ABI states that at process entry, %rdx contains "a
525 * function pointer that the application should register with
526 * atexit()". We make sure to pass NULL explicitly so that
527 * no function is registered.
528 */
529 LX_REG(&jump_uc, REG_RDX) = NULL;
530 #endif
531
532 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();
542 }
543
544 /*ARGSUSED*/
545 int
546 lx_init(int argc, char *argv[], char *envp[])
547 {
548 char *r;
549 auxv_t *ap;
550 long *p;
551 int err;
552 lx_elf_data_t edp;
553 lx_brand_registration_t reg;
554 lx_tsd_t *lxtsd;
555 #if defined(_LP64)
556 void *vdso_hdr;
557 #endif
558
559 bzero(®, sizeof (reg));
560
561 stack_bottom = 2 * sysconf(_SC_PAGESIZE);
|
481 /*
482 * The AMD64 ABI requires that, on entry to a function, the stack
483 * pointer must be 8-byte aligned, but _not_ 16-byte aligned. When
484 * the frame pointer is pushed, the alignment will then be correct.
485 */
486 LX_REG(&lxtsd->lxtsd_exit_context, REG_SP) -= STACK_ENTRY_ALIGN;
487 #endif
488
489 /*
490 * Block all signals in the exit context to avoid taking any signals
491 * (to the degree possible) while exiting.
492 */
493 (void) sigfillset(&lxtsd->lxtsd_exit_context.uc_sigmask);
494
495 if ((err = thr_setspecific(lx_tsd_key, lxtsd)) != 0) {
496 lx_err_fatal("Unable to initialize thread-specific data: %s",
497 strerror(err));
498 }
499 }
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
522 static void
523 lx_start(uintptr_t sp, uintptr_t entry)
524 {
525 ucontext_t jump_uc;
526
527 if (getcontext(&jump_uc) != 0) {
528 lx_err_fatal("Unable to getcontext for program start: %s",
529 strerror(errno));
530 }
531
532 /*
533 * We want to load the general registers from this
534 * context, and switch to the BRAND stack.
535 */
536 jump_uc.uc_flags = UC_CPU;
537 jump_uc.uc_brand_data[0] = (void *)LX_UC_STACK_BRAND;
538
539 LX_REG(&jump_uc, REG_FP) = NULL;
540 LX_REG(&jump_uc, REG_SP) = sp;
541 LX_REG(&jump_uc, REG_PC) = entry;
542
543 #if defined(_LP64)
544 /*
545 * The AMD64 ABI states that at process entry, %rdx contains "a
546 * function pointer that the application should register with
547 * atexit()". We make sure to pass NULL explicitly so that
548 * no function is registered.
549 */
550 LX_REG(&jump_uc, REG_RDX) = NULL;
551 #endif
552
553 lx_debug("starting Linux program sp %p ldentry %p", sp, entry);
554 lx_jump_to_linux(&jump_uc);
555 }
556
557 /*ARGSUSED*/
558 int
559 lx_init(int argc, char *argv[], char *envp[])
560 {
561 char *r;
562 auxv_t *ap;
563 long *p;
564 int err;
565 lx_elf_data_t edp;
566 lx_brand_registration_t reg;
567 lx_tsd_t *lxtsd;
568 #if defined(_LP64)
569 void *vdso_hdr;
570 #endif
571
572 bzero(®, sizeof (reg));
573
574 stack_bottom = 2 * sysconf(_SC_PAGESIZE);
|