diff options
| author | Po Lu | 2023-05-31 11:27:19 +0800 |
|---|---|---|
| committer | Po Lu | 2023-05-31 11:27:19 +0800 |
| commit | 456095ed3129f7ce2fe1ff019ea5d912a69ed2a1 (patch) | |
| tree | 083ed74ffb0e862c8733262710dd589c349834d8 /exec/exec.c | |
| parent | 8db957366448b6cc09462e295bed9a079426519f (diff) | |
| download | emacs-456095ed3129f7ce2fe1ff019ea5d912a69ed2a1.tar.gz emacs-456095ed3129f7ce2fe1ff019ea5d912a69ed2a1.zip | |
Update Android port
* exec/exec.c (insert_args): New argument `arg3'. Replace
argv[1] with that argument.
(exec_0): Pass file name of script to `insert_args'.
Diffstat (limited to 'exec/exec.c')
| -rw-r--r-- | exec/exec.c | 93 |
1 files changed, 63 insertions, 30 deletions
diff --git a/exec/exec.c b/exec/exec.c index 0e077284860..0d9187cabfa 100644 --- a/exec/exec.c +++ b/exec/exec.c | |||
| @@ -740,16 +740,18 @@ process_program_header (const char *name, int fd, | |||
| 740 | } | 740 | } |
| 741 | 741 | ||
| 742 | /* Prepend one or two extra arguments ARG1 and ARG2 to a pending | 742 | /* Prepend one or two extra arguments ARG1 and ARG2 to a pending |
| 743 | execve system call. TRACEE is the tracee performing the system | 743 | execve system call. Replace the argument immediately after |
| 744 | call, and REGS are its current user registers. Value is 1 upon | 744 | with ARG3. |
| 745 | failure, else 0. */ | 745 | |
| 746 | TRACEE is the tracee performing the system call, and REGS are its | ||
| 747 | current user registers. Value is 1 upon failure, else 0. */ | ||
| 746 | 748 | ||
| 747 | static int | 749 | static int |
| 748 | insert_args (struct exec_tracee *tracee, USER_REGS_STRUCT *regs, | 750 | insert_args (struct exec_tracee *tracee, USER_REGS_STRUCT *regs, |
| 749 | const char *arg1, const char *arg2) | 751 | const char *arg1, const char *arg2, const char *arg3) |
| 750 | { | 752 | { |
| 751 | USER_WORD argv, argc, word, new; | 753 | USER_WORD argv, argc, word, new; |
| 752 | USER_WORD new1, new2; | 754 | USER_WORD new1, new2, new3, i; |
| 753 | size_t text_size, effective_size; | 755 | size_t text_size, effective_size; |
| 754 | USER_REGS_STRUCT original; | 756 | USER_REGS_STRUCT original; |
| 755 | 757 | ||
| @@ -783,15 +785,17 @@ insert_args (struct exec_tracee *tracee, USER_REGS_STRUCT *regs, | |||
| 783 | text. */ | 785 | text. */ |
| 784 | 786 | ||
| 785 | text_size = (strlen (arg1) + 1 | 787 | text_size = (strlen (arg1) + 1 |
| 786 | + (arg2 ? strlen (arg2) + 1 : 0)); | 788 | + (arg2 ? strlen (arg2) + 1 : 0) |
| 789 | + strlen (arg3) + 1); | ||
| 787 | 790 | ||
| 788 | /* Round it up to the user word size. */ | 791 | /* Round it up to the user word size. */ |
| 789 | text_size += sizeof (USER_WORD) - 1; | 792 | text_size += sizeof (USER_WORD) - 1; |
| 790 | text_size &= ~(sizeof (USER_WORD) - 1); | 793 | text_size &= ~(sizeof (USER_WORD) - 1); |
| 791 | 794 | ||
| 792 | /* Now allocate the new argv. */ | 795 | /* Now allocate the new argv. Make sure argc is at least 1; it |
| 796 | needs to hold ARG3. */ | ||
| 793 | 797 | ||
| 794 | effective_size = sizeof word * (argc + 2) + text_size; | 798 | effective_size = sizeof word * (MAX (1, argc) + 2) + text_size; |
| 795 | 799 | ||
| 796 | if (arg2) | 800 | if (arg2) |
| 797 | effective_size += sizeof word; | 801 | effective_size += sizeof word; |
| @@ -808,11 +812,13 @@ insert_args (struct exec_tracee *tracee, USER_REGS_STRUCT *regs, | |||
| 808 | 812 | ||
| 809 | /* Figure out where argv starts. */ | 813 | /* Figure out where argv starts. */ |
| 810 | 814 | ||
| 811 | new2 = new + text_size; | 815 | new3 = new + text_size; |
| 812 | 816 | ||
| 813 | /* Now write the two strings. */ | 817 | /* Now write the first two strings. */ |
| 814 | 818 | ||
| 815 | new1 = new + strlen (arg1) + 1; | 819 | new1 = new + strlen (arg1) + 1; |
| 820 | new2 = new1 + (arg2 ? strlen (arg2) + 1 : 0); | ||
| 821 | |||
| 816 | if (user_copy (tracee, (const unsigned char *) arg1, | 822 | if (user_copy (tracee, (const unsigned char *) arg1, |
| 817 | new, new1 - new)) | 823 | new, new1 - new)) |
| 818 | goto fail; | 824 | goto fail; |
| @@ -821,50 +827,77 @@ insert_args (struct exec_tracee *tracee, USER_REGS_STRUCT *regs, | |||
| 821 | new1, new2 - new1)) | 827 | new1, new2 - new1)) |
| 822 | goto fail; | 828 | goto fail; |
| 823 | 829 | ||
| 830 | /* Write the replacement arg3, the file name of the executable. */ | ||
| 831 | |||
| 832 | if (user_copy (tracee, (const unsigned char *) arg3, | ||
| 833 | new2, new3 - new2)) | ||
| 834 | goto fail; | ||
| 835 | |||
| 824 | /* Start copying argv back to new2. First, write the one or two new | 836 | /* Start copying argv back to new2. First, write the one or two new |
| 825 | arguments. */ | 837 | arguments. */ |
| 826 | 838 | ||
| 827 | if (ptrace (PTRACE_POKETEXT, tracee->pid, | 839 | if (ptrace (PTRACE_POKETEXT, tracee->pid, |
| 828 | (void *) new2, (void *) new)) | 840 | (void *) new3, (void *) new)) |
| 829 | goto fail; | 841 | goto fail; |
| 830 | 842 | ||
| 831 | new2 += sizeof new2; | 843 | new3 += sizeof new3; |
| 832 | 844 | ||
| 833 | if (arg2 && ptrace (PTRACE_POKETEXT, tracee->pid, | 845 | if (arg2 && ptrace (PTRACE_POKETEXT, tracee->pid, |
| 834 | (void *) new2, (void *) new1)) | 846 | (void *) new3, (void *) new1)) |
| 835 | goto fail; | 847 | goto fail; |
| 836 | else if (arg2) | 848 | else if (arg2) |
| 837 | new2 += sizeof new2; | 849 | new3 += sizeof new3; |
| 850 | |||
| 851 | /* Next, write the third argument. */ | ||
| 852 | |||
| 853 | if (ptrace (PTRACE_POKETEXT, tracee->pid, (void *) new3, | ||
| 854 | (void *) new2)) | ||
| 855 | goto fail; | ||
| 856 | |||
| 857 | new3 += sizeof new3; | ||
| 838 | 858 | ||
| 839 | /* Copy the remaining arguments back. */ | 859 | /* Copy the remaining arguments back. */ |
| 840 | 860 | ||
| 841 | argv = regs->SYSCALL_ARG1_REG; | 861 | argv = regs->SYSCALL_ARG1_REG; |
| 842 | 862 | ||
| 843 | /* Make sure the trailing NULL is included. */ | 863 | if (argc) |
| 844 | argc += 1; | ||
| 845 | |||
| 846 | while (argc) | ||
| 847 | { | 864 | { |
| 848 | /* Read one argument. */ | 865 | /* Make sure the trailing NULL is included. */ |
| 849 | word = ptrace (PTRACE_PEEKDATA, tracee->pid, | 866 | argc += 1; |
| 850 | (void *) argv, NULL); | 867 | |
| 851 | argv += sizeof argv; | 868 | /* Now copy each argument in argv, starting from argv[1]. */ |
| 852 | argc--; | 869 | |
| 870 | for (i = 1; i < argc; ++i) | ||
| 871 | { | ||
| 872 | /* Read one argument. */ | ||
| 873 | word = ptrace (PTRACE_PEEKDATA, tracee->pid, | ||
| 874 | (void *) (argv + i * sizeof argv), NULL); | ||
| 875 | |||
| 876 | /* Write one argument, then increment new3. */ | ||
| 853 | 877 | ||
| 854 | /* Write one argument, then increment new2. */ | 878 | if (ptrace (PTRACE_POKETEXT, tracee->pid, |
| 879 | (void *) new3, (void *) word)) | ||
| 880 | goto fail; | ||
| 881 | |||
| 882 | new3 += sizeof new3; | ||
| 883 | } | ||
| 884 | } | ||
| 885 | else | ||
| 886 | { | ||
| 887 | /* Just write the trailing NULL. */ | ||
| 855 | 888 | ||
| 856 | if (ptrace (PTRACE_POKETEXT, tracee->pid, | 889 | if (ptrace (PTRACE_POKETEXT, tracee->pid, |
| 857 | (void *) new2, (void *) word)) | 890 | (void *) new3, (void *) 0)) |
| 858 | goto fail; | 891 | goto fail; |
| 859 | 892 | ||
| 860 | new2 += sizeof new2; | 893 | new3 += sizeof new3; |
| 861 | } | 894 | } |
| 862 | 895 | ||
| 863 | /* Assert that new2 is not out of bounds. */ | 896 | /* Assert that new3 is not out of bounds. */ |
| 864 | assert (new2 == new + effective_size); | 897 | assert (new3 == new + effective_size); |
| 865 | 898 | ||
| 866 | /* And that it is properly aligned. */ | 899 | /* And that it is properly aligned. */ |
| 867 | assert (!(new2 & (sizeof new2 - 2))); | 900 | assert (!(new3 & (sizeof new3 - 2))); |
| 868 | 901 | ||
| 869 | /* Now modify the system call argument to point to new + | 902 | /* Now modify the system call argument to point to new + |
| 870 | text_size. */ | 903 | text_size. */ |
| @@ -1046,7 +1079,7 @@ exec_0 (char *name, struct exec_tracee *tracee, | |||
| 1046 | and perhaps `extra'. */ | 1079 | and perhaps `extra'. */ |
| 1047 | 1080 | ||
| 1048 | if (insert_args (tracee, regs, interpreter_name, | 1081 | if (insert_args (tracee, regs, interpreter_name, |
| 1049 | extra)) | 1082 | extra, name)) |
| 1050 | goto fail1; | 1083 | goto fail1; |
| 1051 | } | 1084 | } |
| 1052 | 1085 | ||