aboutsummaryrefslogtreecommitdiffstats
path: root/exec/trace.c
diff options
context:
space:
mode:
authorPo Lu2023-05-01 21:23:12 +0800
committerPo Lu2023-05-01 21:23:12 +0800
commitb9de6e35b79cbc10909a856df6b1caa770bd4ac4 (patch)
tree6cfbd5ef7419bcd80f26443b134cc1b3e5754780 /exec/trace.c
parentda6f0d9c6fd4b2a097f02a6e8f1b2aa33a6bf307 (diff)
downloademacs-b9de6e35b79cbc10909a856df6b1caa770bd4ac4.tar.gz
emacs-b9de6e35b79cbc10909a856df6b1caa770bd4ac4.zip
Fix cwd relative process execution on Android
* exec/exec.c (format_pid): New function. (exec_0): Make cwd relative file names relative to /proc/pid/cwd. * exec/trace.c (handle_exec): Handle EINTR. (process_system_call): Report failure without clobbering x0.
Diffstat (limited to 'exec/trace.c')
-rw-r--r--exec/trace.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/exec/trace.c b/exec/trace.c
index df5deacd9bb..d9e8673ba71 100644
--- a/exec/trace.c
+++ b/exec/trace.c
@@ -457,10 +457,17 @@ handle_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs)
457 memcpy (&original, regs, sizeof *regs); 457 memcpy (&original, regs, sizeof *regs);
458 458
459 /* Figure out what the loader needs to do. */ 459 /* Figure out what the loader needs to do. */
460 again1:
460 area = exec_0 (buffer, tracee, &size, regs); 461 area = exec_0 (buffer, tracee, &size, regs);
461 462
462 if (!area) 463 if (!area)
463 return 1; 464 {
465 /* Handle SIGINTR errors caused by IO. */
466 if (errno == EINTR)
467 goto again1;
468
469 return 1;
470 }
464 471
465 /* Rewrite the first argument to point to the loader. */ 472 /* Rewrite the first argument to point to the loader. */
466 473
@@ -516,10 +523,7 @@ handle_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs)
516 goto again; 523 goto again;
517 524
518 if (rc < 0) 525 if (rc < 0)
519 { 526 return 1;
520 errno = EIO;
521 return 1;
522 }
523 527
524 if (!WIFSTOPPED (wstatus)) 528 if (!WIFSTOPPED (wstatus))
525 /* The process has been killed in response to a signal. 529 /* The process has been killed in response to a signal.
@@ -608,13 +612,14 @@ handle_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs)
608 612
609#endif /* STACK_GROWS_DOWNWARDS */ 613#endif /* STACK_GROWS_DOWNWARDS */
610 614
611 exec_failure:
612
613 /* Continue. */ 615 /* Continue. */
614 if (ptrace (PTRACE_SYSCALL, tracee->pid, 0, 0)) 616 if (ptrace (PTRACE_SYSCALL, tracee->pid, 0, 0))
615 return 3; 617 return 3;
616 618
617 return 0; 619 return 0;
620
621 exec_failure:
622 return 3;
618} 623}
619 624
620/* Process the system call at which TRACEE is stopped. If the system 625/* Process the system call at which TRACEE is stopped. If the system
@@ -625,10 +630,10 @@ static void
625process_system_call (struct exec_tracee *tracee) 630process_system_call (struct exec_tracee *tracee)
626{ 631{
627 USER_REGS_STRUCT regs; 632 USER_REGS_STRUCT regs;
628 int rc, wstatus; 633 int rc, wstatus, save_errno;
629 USER_WORD callno, sp; 634 USER_WORD callno, sp;
630#ifdef __aarch64__ 635#ifdef __aarch64__
631 USER_WORD old_w0, old_w1, old_w2; 636 USER_WORD old_w1, old_w2;
632#endif /* __aarch64__ */ 637#endif /* __aarch64__ */
633 638
634#ifdef __aarch64__ 639#ifdef __aarch64__
@@ -695,6 +700,9 @@ process_system_call (struct exec_tracee *tracee)
695 Make sure that the stack pointer is restored to its original 700 Make sure that the stack pointer is restored to its original
696 position upon exit, or bad things can happen. */ 701 position upon exit, or bad things can happen. */
697 702
703 /* First, save errno; system calls below will clobber it. */
704 save_errno = errno;
705
698#ifndef __aarch64__ 706#ifndef __aarch64__
699 regs.SYSCALL_NUM_REG = -1; 707 regs.SYSCALL_NUM_REG = -1;
700#else /* __aarch64__ */ 708#else /* __aarch64__ */
@@ -702,7 +710,6 @@ process_system_call (struct exec_tracee *tracee)
702 can't find any unused system call, so use fcntl instead, with 710 can't find any unused system call, so use fcntl instead, with
703 invalid arguments. */ 711 invalid arguments. */
704 regs.SYSCALL_NUM_REG = 72; 712 regs.SYSCALL_NUM_REG = 72;
705 old_w0 = regs.regs[0];
706 old_w1 = regs.regs[1]; 713 old_w1 = regs.regs[1];
707 old_w2 = regs.regs[2]; 714 old_w2 = regs.regs[2];
708 regs.regs[0] = -1; 715 regs.regs[0] = -1;
@@ -739,6 +746,11 @@ process_system_call (struct exec_tracee *tracee)
739 if (rc == -1 && errno == EINTR) 746 if (rc == -1 && errno == EINTR)
740 goto again1; 747 goto again1;
741 748
749 /* Return if waitpid fails. */
750
751 if (rc == -1)
752 return;
753
742 if (!WIFSTOPPED (wstatus)) 754 if (!WIFSTOPPED (wstatus))
743 /* The process has been killed in response to a signal. In this 755 /* The process has been killed in response to a signal. In this
744 case, simply unlink the tracee and return. */ 756 case, simply unlink the tracee and return. */
@@ -747,16 +759,15 @@ process_system_call (struct exec_tracee *tracee)
747 { 759 {
748#ifdef __mips__ 760#ifdef __mips__
749 /* MIPS systems place errno in v0 and set a3 to 1. */ 761 /* MIPS systems place errno in v0 and set a3 to 1. */
750 regs.gregs[2] = errno; 762 regs.gregs[2] = save_errno;
751 regs.gregs[7] = 1; 763 regs.gregs[7] = 1;
752#else /* !__mips__ */ 764#else /* !__mips__ */
753 regs.SYSCALL_RET_REG = -errno; 765 regs.SYSCALL_RET_REG = -save_errno;
754#endif /* __mips__ */ 766#endif /* __mips__ */
755 767
756 /* Report errno. */ 768 /* Report errno. */
757#ifdef __aarch64__ 769#ifdef __aarch64__
758 /* Restore x0, x1 and x2. */ 770 /* Restore x1 and x2. x0 is clobbered by errno. */
759 regs.regs[0] = old_w0;
760 regs.regs[1] = old_w1; 771 regs.regs[1] = old_w1;
761 regs.regs[2] = old_w2; 772 regs.regs[2] = old_w2;
762 aarch64_set_regs (tracee->pid, &regs, false); 773 aarch64_set_regs (tracee->pid, &regs, false);