aboutsummaryrefslogtreecommitdiffstats
path: root/exec/trace.c
diff options
context:
space:
mode:
authorPo Lu2023-05-02 20:45:57 +0800
committerPo Lu2023-05-02 20:45:57 +0800
commitc47716f95b8fda9438047d2683a415a65c18ecbd (patch)
tree947c45293556f41ce02426889890b3442f2b7b36 /exec/trace.c
parentf4512cca0b996e5343ebe57511f45a29f64c4a8e (diff)
downloademacs-c47716f95b8fda9438047d2683a415a65c18ecbd.tar.gz
emacs-c47716f95b8fda9438047d2683a415a65c18ecbd.zip
Update Android port
* exec/config.h.in (__bool_true_false_are_defined): * exec/configure.ac (REENTRANT): New definition. (READLINKAT_SYSCALL, READLINK_SYSCALL): New defines. Set on all hosts. * exec/exec.c (MIN, MAX): Remove redundant declarations. Move to config.h. (exec_0): Copy name of executable into NAME when !REENTRANT. * exec/exec.h (struct exec_tracee): New struct `exec_file'. * exec/trace.c (remove_tracee, handle_exec, handle_readlinkat) (process_system_call, after_fork): Handle readlinkat system calls.
Diffstat (limited to 'exec/trace.c')
-rw-r--r--exec/trace.c168
1 files changed, 164 insertions, 4 deletions
diff --git a/exec/trace.c b/exec/trace.c
index d9e8673ba71..cb0839c9cd9 100644
--- a/exec/trace.c
+++ b/exec/trace.c
@@ -315,6 +315,13 @@ remove_tracee (struct exec_tracee *tracee)
315 315
316 /* Link the tracee onto the list of free tracees. */ 316 /* Link the tracee onto the list of free tracees. */
317 tracee->next = free_tracees; 317 tracee->next = free_tracees;
318
319#ifndef REENTRANT
320 /* Free the exec file, if any. */
321 free (tracee->exec_file);
322 tracee->exec_file = NULL;
323#endif /* REENTRANT */
324
318 free_tracees = tracee; 325 free_tracees = tracee;
319 326
320 return; 327 return;
@@ -431,7 +438,7 @@ syscall_trap_p (siginfo_t *signal)
431static int 438static int
432handle_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs) 439handle_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs)
433{ 440{
434 char buffer[PATH_MAX], *area; 441 char buffer[PATH_MAX + 80], *area;
435 USER_REGS_STRUCT original; 442 USER_REGS_STRUCT original;
436 size_t size, loader_size; 443 size_t size, loader_size;
437 USER_WORD loader, size1, sp; 444 USER_WORD loader, size1, sp;
@@ -517,6 +524,17 @@ handle_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs)
517 return 1; 524 return 1;
518 } 525 }
519 526
527#ifndef REENTRANT
528 /* Now that the loader has started, record the value to use for
529 /proc/self/exe. Don't give up just because strdup fails.
530
531 Note that exec_0 copies the absolute file name into buffer. */
532
533 if (tracee->exec_file)
534 free (tracee->exec_file);
535 tracee->exec_file = strdup (buffer);
536#endif /* REENTRANT */
537
520 again: 538 again:
521 rc = waitpid (tracee->pid, &wstatus, __WALL); 539 rc = waitpid (tracee->pid, &wstatus, __WALL);
522 if (rc == -1 && errno == EINTR) 540 if (rc == -1 && errno == EINTR)
@@ -622,6 +640,91 @@ handle_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs)
622 return 3; 640 return 3;
623} 641}
624 642
643/* Handle a `readlink' or `readlinkat' system call.
644
645 CALLNO is the system call number, and REGS are the current user
646 registers of the TRACEE.
647
648 If the first argument of a `readlinkat' system call is AT_FDCWD,
649 and the file name specified in either a `readlink' or `readlinkat'
650 system call is `/proc/self/exe', write the name of the executable
651 being run into the buffer specified in the system call.
652
653 Return the number of bytes written to the tracee's buffer in
654 *RESULT.
655
656 Value is 0 upon success. Value is 1 upon failure, and 2 if the
657 system call has been emulated. */
658
659static int
660handle_readlinkat (USER_WORD callno, USER_REGS_STRUCT *regs,
661 struct exec_tracee *tracee, USER_WORD *result)
662{
663#ifdef REENTRANT
664 /* readlinkat cannot be handled specially when the library is built
665 to be reentrant, as the file name information cannot be
666 recorded. */
667 return 0;
668#else /* !REENTRANT */
669
670 char buffer[PATH_MAX + 1];
671 USER_WORD address, return_buffer, size;
672 size_t length;
673
674 /* Read the file name. */
675
676#ifdef READLINK_SYSCALL
677 if (callno == READLINK_SYSCALL)
678 {
679 address = regs->SYSCALL_ARG_REG;
680 return_buffer = regs->SYSCALL_ARG1_REG;
681 size = regs->SYSCALL_ARG2_REG;
682 }
683 else
684#endif /* READLINK_SYSCALL */
685 {
686 address = regs->SYSCALL_ARG1_REG;
687 return_buffer = regs->SYSCALL_ARG2_REG;
688 size = regs->SYSCALL_ARG3_REG;
689 }
690
691 read_memory (tracee, buffer, PATH_MAX, address);
692
693 /* Make sure BUFFER is NULL terminated. */
694
695 if (!memchr (buffer, '\0', PATH_MAX))
696 {
697 errno = ENAMETOOLONG;
698 return 1;
699 }
700
701 /* Now check if the caller is looking for /proc/self/exe.
702
703 dirfd can be ignored, as for now only absolute file names are
704 handled. FIXME. */
705
706 if (strcmp (buffer, "/proc/self/exe") || !tracee->exec_file)
707 return 0;
708
709 /* Copy over tracee->exec_file. Truncate it to PATH_MAX, length, or
710 size, whichever is less. */
711
712 length = strlen (tracee->exec_file);
713 length = MIN (size, MIN (PATH_MAX, length));
714 strncpy (buffer, tracee->exec_file, length);
715
716 if (user_copy (tracee, (unsigned char *) buffer,
717 return_buffer, length))
718 {
719 errno = EIO;
720 return 1;
721 }
722
723 *result = length;
724 return 2;
725#endif /* REENTRANT */
726}
727
625/* Process the system call at which TRACEE is stopped. If the system 728/* Process the system call at which TRACEE is stopped. If the system
626 call is not known or not exec, send TRACEE on its way. Otherwise, 729 call is not known or not exec, send TRACEE on its way. Otherwise,
627 rewrite it to load the loader and perform an appropriate action. */ 730 rewrite it to load the loader and perform an appropriate action. */
@@ -635,6 +738,8 @@ process_system_call (struct exec_tracee *tracee)
635#ifdef __aarch64__ 738#ifdef __aarch64__
636 USER_WORD old_w1, old_w2; 739 USER_WORD old_w1, old_w2;
637#endif /* __aarch64__ */ 740#endif /* __aarch64__ */
741 USER_WORD result;
742 bool reporting_error;
638 743
639#ifdef __aarch64__ 744#ifdef __aarch64__
640 rc = aarch64_get_regs (tracee->pid, &regs); 745 rc = aarch64_get_regs (tracee->pid, &regs);
@@ -678,6 +783,24 @@ process_system_call (struct exec_tracee *tracee)
678 783
679 break; 784 break;
680 785
786#ifdef READLINK_SYSCALL
787 case READLINK_SYSCALL:
788#endif /* READLINK_SYSCALL */
789 case READLINKAT_SYSCALL:
790
791 /* Handle this readlinkat system call. */
792 rc = handle_readlinkat (callno, &regs, tracee,
793 &result);
794
795 /* rc means the same as in `handle_exec'. */
796
797 if (rc == 1)
798 goto report_syscall_error;
799 else if (rc == 2)
800 goto emulate_syscall;
801
802 /* Fallthrough. */
803
681 default: 804 default:
682 /* Don't wait for the system call to finish; instead, the system 805 /* Don't wait for the system call to finish; instead, the system
683 will DTRT upon the next call to PTRACE_SYSCALL after the 806 will DTRT upon the next call to PTRACE_SYSCALL after the
@@ -694,8 +817,16 @@ process_system_call (struct exec_tracee *tracee)
694 return; 817 return;
695 818
696 report_syscall_error: 819 report_syscall_error:
697 /* Reporting an error works by setting the system call number to -1, 820 reporting_error = true;
698 letting it continue, and then substituting errno for ENOSYS. 821 goto common;
822
823 emulate_syscall:
824 reporting_error = false;
825 common:
826
827 /* Reporting an error or emulating a system call works by setting
828 the system call number to -1, letting it continue, and then
829 substituting errno for ENOSYS in the case of an error.
699 830
700 Make sure that the stack pointer is restored to its original 831 Make sure that the stack pointer is restored to its original
701 position upon exit, or bad things can happen. */ 832 position upon exit, or bad things can happen. */
@@ -755,7 +886,7 @@ process_system_call (struct exec_tracee *tracee)
755 /* The process has been killed in response to a signal. In this 886 /* The process has been killed in response to a signal. In this
756 case, simply unlink the tracee and return. */ 887 case, simply unlink the tracee and return. */
757 remove_tracee (tracee); 888 remove_tracee (tracee);
758 else 889 else if (reporting_error)
759 { 890 {
760#ifdef __mips__ 891#ifdef __mips__
761 /* MIPS systems place errno in v0 and set a3 to 1. */ 892 /* MIPS systems place errno in v0 and set a3 to 1. */
@@ -778,6 +909,32 @@ process_system_call (struct exec_tracee *tracee)
778 /* Now wait for the next system call to happen. */ 909 /* Now wait for the next system call to happen. */
779 ptrace (PTRACE_SYSCALL, tracee->pid, NULL, NULL); 910 ptrace (PTRACE_SYSCALL, tracee->pid, NULL, NULL);
780 } 911 }
912 else
913 {
914 /* No error is being reported. Return the result in the
915 appropriate registers. */
916
917#ifdef __mips__
918 /* MIPS systems place errno in v0 and set a3 to 1. */
919 regs.gregs[2] = result;
920 regs.gregs[7] = 0;
921#else /* !__mips__ */
922 regs.SYSCALL_RET_REG = result;
923#endif /* __mips__ */
924
925 /* Report errno. */
926#ifdef __aarch64__
927 /* Restore x1 and x2. x0 is clobbered by errno. */
928 regs.regs[1] = old_w1;
929 regs.regs[2] = old_w2;
930 aarch64_set_regs (tracee->pid, &regs, false);
931#else /* !__aarch64__ */
932 ptrace (PTRACE_SETREGS, tracee->pid, NULL, &regs);
933#endif /* __aarch64__ */
934
935 /* Now wait for the next system call to happen. */
936 ptrace (PTRACE_SYSCALL, tracee->pid, NULL, NULL);
937 }
781} 938}
782 939
783 940
@@ -869,6 +1026,9 @@ after_fork (pid_t pid)
869 tracee->pid = pid; 1026 tracee->pid = pid;
870 tracee->next = tracing_processes; 1027 tracee->next = tracing_processes;
871 tracee->waiting_for_syscall = false; 1028 tracee->waiting_for_syscall = false;
1029#ifndef REENTRANT
1030 tracee->exec_file = NULL;
1031#endif /* REENTRANT */
872 tracing_processes = tracee; 1032 tracing_processes = tracee;
873 return 0; 1033 return 0;
874} 1034}