aboutsummaryrefslogtreecommitdiffstats
path: root/exec/exec.c
diff options
context:
space:
mode:
authorPo Lu2023-05-31 11:27:19 +0800
committerPo Lu2023-05-31 11:27:19 +0800
commit456095ed3129f7ce2fe1ff019ea5d912a69ed2a1 (patch)
tree083ed74ffb0e862c8733262710dd589c349834d8 /exec/exec.c
parent8db957366448b6cc09462e295bed9a079426519f (diff)
downloademacs-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.c93
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
747static int 749static int
748insert_args (struct exec_tracee *tracee, USER_REGS_STRUCT *regs, 750insert_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