diff options
| author | Po Lu | 2023-05-01 13:12:44 +0800 |
|---|---|---|
| committer | Po Lu | 2023-05-01 13:12:44 +0800 |
| commit | 6a30a74cb2ac2cba69aa01da12caf1eac7134f43 (patch) | |
| tree | ccefc5b34446ec15fbc7362af0ae924c4d0ddc35 /exec | |
| parent | ddc16de86964d445309dd38175a85221c14f05ab (diff) | |
| download | emacs-6a30a74cb2ac2cba69aa01da12caf1eac7134f43.tar.gz emacs-6a30a74cb2ac2cba69aa01da12caf1eac7134f43.zip | |
Fix syscall error reporting on aarch64
* exec/trace.c (process_system_call): Save and restore x0, x1
and x2 regs after replacing them with an invalid file
descriptor.
Diffstat (limited to 'exec')
| -rw-r--r-- | exec/trace.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/exec/trace.c b/exec/trace.c index cef699e8526..df5deacd9bb 100644 --- a/exec/trace.c +++ b/exec/trace.c | |||
| @@ -627,6 +627,9 @@ process_system_call (struct exec_tracee *tracee) | |||
| 627 | USER_REGS_STRUCT regs; | 627 | USER_REGS_STRUCT regs; |
| 628 | int rc, wstatus; | 628 | int rc, wstatus; |
| 629 | USER_WORD callno, sp; | 629 | USER_WORD callno, sp; |
| 630 | #ifdef __aarch64__ | ||
| 631 | USER_WORD old_w0, old_w1, old_w2; | ||
| 632 | #endif /* __aarch64__ */ | ||
| 630 | 633 | ||
| 631 | #ifdef __aarch64__ | 634 | #ifdef __aarch64__ |
| 632 | rc = aarch64_get_regs (tracee->pid, ®s); | 635 | rc = aarch64_get_regs (tracee->pid, ®s); |
| @@ -692,7 +695,20 @@ process_system_call (struct exec_tracee *tracee) | |||
| 692 | Make sure that the stack pointer is restored to its original | 695 | Make sure that the stack pointer is restored to its original |
| 693 | position upon exit, or bad things can happen. */ | 696 | position upon exit, or bad things can happen. */ |
| 694 | 697 | ||
| 698 | #ifndef __aarch64__ | ||
| 695 | regs.SYSCALL_NUM_REG = -1; | 699 | regs.SYSCALL_NUM_REG = -1; |
| 700 | #else /* __aarch64__ */ | ||
| 701 | /* ARM also requires the system call number to be valid. However, I | ||
| 702 | can't find any unused system call, so use fcntl instead, with | ||
| 703 | invalid arguments. */ | ||
| 704 | regs.SYSCALL_NUM_REG = 72; | ||
| 705 | old_w0 = regs.regs[0]; | ||
| 706 | old_w1 = regs.regs[1]; | ||
| 707 | old_w2 = regs.regs[2]; | ||
| 708 | regs.regs[0] = -1; | ||
| 709 | regs.regs[1] = -1; | ||
| 710 | regs.regs[2] = -1; | ||
| 711 | #endif /* !__aarch64__ */ | ||
| 696 | regs.STACK_POINTER = sp; | 712 | regs.STACK_POINTER = sp; |
| 697 | 713 | ||
| 698 | #ifdef __aarch64__ | 714 | #ifdef __aarch64__ |
| @@ -714,7 +730,6 @@ process_system_call (struct exec_tracee *tracee) | |||
| 714 | return; | 730 | return; |
| 715 | #endif /* __aarch64__ */ | 731 | #endif /* __aarch64__ */ |
| 716 | 732 | ||
| 717 | |||
| 718 | /* Do this invalid system call. */ | 733 | /* Do this invalid system call. */ |
| 719 | if (ptrace (PTRACE_SYSCALL, tracee->pid, NULL, NULL)) | 734 | if (ptrace (PTRACE_SYSCALL, tracee->pid, NULL, NULL)) |
| 720 | return; | 735 | return; |
| @@ -740,6 +755,10 @@ process_system_call (struct exec_tracee *tracee) | |||
| 740 | 755 | ||
| 741 | /* Report errno. */ | 756 | /* Report errno. */ |
| 742 | #ifdef __aarch64__ | 757 | #ifdef __aarch64__ |
| 758 | /* Restore x0, x1 and x2. */ | ||
| 759 | regs.regs[0] = old_w0; | ||
| 760 | regs.regs[1] = old_w1; | ||
| 761 | regs.regs[2] = old_w2; | ||
| 743 | aarch64_set_regs (tracee->pid, ®s, false); | 762 | aarch64_set_regs (tracee->pid, ®s, false); |
| 744 | #else /* !__aarch64__ */ | 763 | #else /* !__aarch64__ */ |
| 745 | ptrace (PTRACE_SETREGS, tracee->pid, NULL, ®s); | 764 | ptrace (PTRACE_SETREGS, tracee->pid, NULL, ®s); |