diff options
| author | Po Lu | 2024-03-14 13:45:48 +0800 |
|---|---|---|
| committer | Po Lu | 2024-03-14 13:45:48 +0800 |
| commit | 30bc867aecc59265b6e315acf459f8d79c423bca (patch) | |
| tree | 501c2c810e57464d20cf55d7e693d5f2f3ae2ef0 /exec | |
| parent | db5c8bda638468f8798c974f4ef4ab3905dbddd3 (diff) | |
| download | emacs-30bc867aecc59265b6e315acf459f8d79c423bca.tar.gz emacs-30bc867aecc59265b6e315acf459f8d79c423bca.zip | |
Improve /proc/self/exe substitution on Android
* exec/configure.ac (USER_SWORD): New macro.
* exec/exec.c (format_pid): Export this function.
* exec/exec.h:
* exec/trace.c (canon_path): New function.
(handle_readlinkat, handle_openat): Test complete file name
against /proc/self/exe, and further check for /proc/pid/exe.
Diffstat (limited to 'exec')
| -rw-r--r-- | exec/configure.ac | 8 | ||||
| -rw-r--r-- | exec/exec.c | 2 | ||||
| -rw-r--r-- | exec/exec.h | 1 | ||||
| -rw-r--r-- | exec/trace.c | 121 |
4 files changed, 121 insertions, 11 deletions
diff --git a/exec/configure.ac b/exec/configure.ac index 317250332cb..a473a1dc633 100644 --- a/exec/configure.ac +++ b/exec/configure.ac | |||
| @@ -122,6 +122,7 @@ AH_TEMPLATE([SYSCALL_RET_REG], [Define to register holding value of system calls | |||
| 122 | AH_TEMPLATE([STACK_POINTER], [Define to register holding the stack pointer.]) | 122 | AH_TEMPLATE([STACK_POINTER], [Define to register holding the stack pointer.]) |
| 123 | AH_TEMPLATE([EXEC_SYSCALL], [Define to number of the `exec' system call.]) | 123 | AH_TEMPLATE([EXEC_SYSCALL], [Define to number of the `exec' system call.]) |
| 124 | AH_TEMPLATE([USER_WORD], [Define to word type used by tracees.]) | 124 | AH_TEMPLATE([USER_WORD], [Define to word type used by tracees.]) |
| 125 | AH_TEMPLATE([USER_SWORD], [Define to signed word type used by tracees.]) | ||
| 125 | AH_TEMPLATE([EXEC_64], [Define to 1 if the system utilizes 64-bit ELF.]) | 126 | AH_TEMPLATE([EXEC_64], [Define to 1 if the system utilizes 64-bit ELF.]) |
| 126 | AH_TEMPLATE([STACK_GROWS_DOWNWARDS], [Define to 1 if the stack grows downwards.]) | 127 | AH_TEMPLATE([STACK_GROWS_DOWNWARDS], [Define to 1 if the stack grows downwards.]) |
| 127 | AH_TEMPLATE([ABI_RED_ZONE], [Define to number of reserved bytes past the stack frame.]) | 128 | AH_TEMPLATE([ABI_RED_ZONE], [Define to number of reserved bytes past the stack frame.]) |
| @@ -251,6 +252,7 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 251 | AC_DEFINE([STACK_POINTER], [rsp]) | 252 | AC_DEFINE([STACK_POINTER], [rsp]) |
| 252 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) | 253 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) |
| 253 | AC_DEFINE([USER_WORD], [uintptr_t]) | 254 | AC_DEFINE([USER_WORD], [uintptr_t]) |
| 255 | AC_DEFINE([USER_SWORD], [intptr_t]) | ||
| 254 | AC_DEFINE([EXEC_64], [1]) | 256 | AC_DEFINE([EXEC_64], [1]) |
| 255 | AC_DEFINE([ABI_RED_ZONE], [128]) | 257 | AC_DEFINE([ABI_RED_ZONE], [128]) |
| 256 | AC_DEFINE([EXECUTABLE_BASE], [0x555555554000]) | 258 | AC_DEFINE([EXECUTABLE_BASE], [0x555555554000]) |
| @@ -283,6 +285,7 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 283 | AC_DEFINE([STACK_POINTER], [esp]) | 285 | AC_DEFINE([STACK_POINTER], [esp]) |
| 284 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) | 286 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) |
| 285 | AC_DEFINE([USER_WORD], [uintptr_t]) | 287 | AC_DEFINE([USER_WORD], [uintptr_t]) |
| 288 | AC_DEFINE([USER_SWORD], [intptr_t]) | ||
| 286 | AC_DEFINE([EXECUTABLE_BASE], [0x0f000000]) | 289 | AC_DEFINE([EXECUTABLE_BASE], [0x0f000000]) |
| 287 | AC_DEFINE([INTERPRETER_BASE], [0xaf000000]) | 290 | AC_DEFINE([INTERPRETER_BASE], [0xaf000000]) |
| 288 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) | 291 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) |
| @@ -313,6 +316,7 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 313 | AC_DEFINE([STACK_POINTER], [sp]) | 316 | AC_DEFINE([STACK_POINTER], [sp]) |
| 314 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) | 317 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) |
| 315 | AC_DEFINE([USER_WORD], [uintptr_t]) | 318 | AC_DEFINE([USER_WORD], [uintptr_t]) |
| 319 | AC_DEFINE([USER_SWORD], [intptr_t]) | ||
| 316 | AC_DEFINE([EXEC_64], [1]) | 320 | AC_DEFINE([EXEC_64], [1]) |
| 317 | AC_DEFINE([EXECUTABLE_BASE], [0x3000000000]) | 321 | AC_DEFINE([EXECUTABLE_BASE], [0x3000000000]) |
| 318 | AC_DEFINE([INTERPRETER_BASE], [0x3f00000000]) | 322 | AC_DEFINE([INTERPRETER_BASE], [0x3f00000000]) |
| @@ -344,6 +348,7 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 344 | AC_DEFINE([STACK_POINTER], [[uregs[13]]]) | 348 | AC_DEFINE([STACK_POINTER], [[uregs[13]]]) |
| 345 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) | 349 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) |
| 346 | AC_DEFINE([USER_WORD], [uintptr_t]) | 350 | AC_DEFINE([USER_WORD], [uintptr_t]) |
| 351 | AC_DEFINE([USER_SWORD], [intptr_t]) | ||
| 347 | AC_DEFINE([EXECUTABLE_BASE], [0x0f000000]) | 352 | AC_DEFINE([EXECUTABLE_BASE], [0x0f000000]) |
| 348 | AC_DEFINE([INTERPRETER_BASE], [0x1f000000]) | 353 | AC_DEFINE([INTERPRETER_BASE], [0x1f000000]) |
| 349 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) | 354 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) |
| @@ -368,6 +373,7 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 368 | AC_DEFINE([STACK_POINTER], [[uregs[13]]]) | 373 | AC_DEFINE([STACK_POINTER], [[uregs[13]]]) |
| 369 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) | 374 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) |
| 370 | AC_DEFINE([USER_WORD], [uintptr_t]) | 375 | AC_DEFINE([USER_WORD], [uintptr_t]) |
| 376 | AC_DEFINE([USER_SWORD], [intptr_t]) | ||
| 371 | AC_DEFINE([EXECUTABLE_BASE], [0x0f000000]) | 377 | AC_DEFINE([EXECUTABLE_BASE], [0x0f000000]) |
| 372 | AC_DEFINE([INTERPRETER_BASE], [0x1f000000]) | 378 | AC_DEFINE([INTERPRETER_BASE], [0x1f000000]) |
| 373 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) | 379 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) |
| @@ -398,6 +404,7 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 398 | AC_DEFINE([STACK_POINTER], [[gregs[29]]]) # sp | 404 | AC_DEFINE([STACK_POINTER], [[gregs[29]]]) # sp |
| 399 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) | 405 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) |
| 400 | AC_DEFINE([USER_WORD], [uintptr_t]) | 406 | AC_DEFINE([USER_WORD], [uintptr_t]) |
| 407 | AC_DEFINE([USER_SWORD], [intptr_t]) | ||
| 401 | AC_DEFINE([EXECUTABLE_BASE], [0x0f000000]) | 408 | AC_DEFINE([EXECUTABLE_BASE], [0x0f000000]) |
| 402 | AC_DEFINE([INTERPRETER_BASE], [0x1f000000]) | 409 | AC_DEFINE([INTERPRETER_BASE], [0x1f000000]) |
| 403 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) | 410 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) |
| @@ -427,6 +434,7 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 427 | AC_DEFINE([STACK_POINTER], [[gregs[29]]]) # sp | 434 | AC_DEFINE([STACK_POINTER], [[gregs[29]]]) # sp |
| 428 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) | 435 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) |
| 429 | AC_DEFINE([USER_WORD], [uintptr_t]) | 436 | AC_DEFINE([USER_WORD], [uintptr_t]) |
| 437 | AC_DEFINE([USER_SWORD], [intptr_t]) | ||
| 430 | AC_DEFINE([EXEC_64], [1]) | 438 | AC_DEFINE([EXEC_64], [1]) |
| 431 | AC_DEFINE([EXECUTABLE_BASE], [0x400000]) | 439 | AC_DEFINE([EXECUTABLE_BASE], [0x400000]) |
| 432 | AC_DEFINE([INTERPRETER_BASE], [0x3f00000000]) | 440 | AC_DEFINE([INTERPRETER_BASE], [0x3f00000000]) |
diff --git a/exec/exec.c b/exec/exec.c index 254a983f25f..cbe22d4f18c 100644 --- a/exec/exec.c +++ b/exec/exec.c | |||
| @@ -865,7 +865,7 @@ insert_args (struct exec_tracee *tracee, USER_REGS_STRUCT *regs, | |||
| 865 | result in *IN, and return a pointer to the byte after the | 865 | result in *IN, and return a pointer to the byte after the |
| 866 | result. REM should be NULL. */ | 866 | result. REM should be NULL. */ |
| 867 | 867 | ||
| 868 | static char * | 868 | char * |
| 869 | format_pid (char *in, unsigned int pid) | 869 | format_pid (char *in, unsigned int pid) |
| 870 | { | 870 | { |
| 871 | unsigned int digits[32], *fill; | 871 | unsigned int digits[32], *fill; |
diff --git a/exec/exec.h b/exec/exec.h index ad1b50276c8..3ce06c35311 100644 --- a/exec/exec.h +++ b/exec/exec.h | |||
| @@ -180,6 +180,7 @@ extern int aarch64_set_regs (pid_t, USER_REGS_STRUCT *, bool); | |||
| 180 | 180 | ||
| 181 | 181 | ||
| 182 | 182 | ||
| 183 | extern char *format_pid (char *, unsigned int); | ||
| 183 | extern USER_WORD user_alloca (struct exec_tracee *, USER_REGS_STRUCT *, | 184 | extern USER_WORD user_alloca (struct exec_tracee *, USER_REGS_STRUCT *, |
| 184 | USER_REGS_STRUCT *, USER_WORD); | 185 | USER_REGS_STRUCT *, USER_WORD); |
| 185 | extern int user_copy (struct exec_tracee *, const unsigned char *, | 186 | extern int user_copy (struct exec_tracee *, const unsigned char *, |
diff --git a/exec/trace.c b/exec/trace.c index a7cbda54d68..64dadc092c2 100644 --- a/exec/trace.c +++ b/exec/trace.c | |||
| @@ -31,6 +31,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 31 | #include <unistd.h> | 31 | #include <unistd.h> |
| 32 | #include <stdlib.h> | 32 | #include <stdlib.h> |
| 33 | #include <errno.h> | 33 | #include <errno.h> |
| 34 | #include <fcntl.h> | ||
| 34 | 35 | ||
| 35 | #include "exec.h" | 36 | #include "exec.h" |
| 36 | 37 | ||
| @@ -894,6 +895,68 @@ handle_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs) | |||
| 894 | return 3; | 895 | return 3; |
| 895 | } | 896 | } |
| 896 | 897 | ||
| 898 | /* Modify BUFFER, of size SIZE, so that it holds the absolute name of | ||
| 899 | the file identified by BUFFER, relative to the current working | ||
| 900 | directory of TRACEE if FD be AT_FDCWD, or the file referenced by FD | ||
| 901 | otherwise. | ||
| 902 | |||
| 903 | Value is 1 if this information is unavailable (of which there are | ||
| 904 | variety of causes), and 0 on success. */ | ||
| 905 | |||
| 906 | static int | ||
| 907 | canon_path (struct exec_tracee *tracee, int fd, char *buffer, | ||
| 908 | ptrdiff_t size) | ||
| 909 | { | ||
| 910 | char link[sizeof "/proc//fd/" + 48], *p; /* Or /proc/pid/cwd. */ | ||
| 911 | char target[PATH_MAX]; | ||
| 912 | ssize_t rc, length; | ||
| 913 | |||
| 914 | if (buffer[0] == '/') | ||
| 915 | /* Absolute file name; return immediately. */ | ||
| 916 | return 0; | ||
| 917 | else if (fd == AT_FDCWD) | ||
| 918 | { | ||
| 919 | p = stpcpy (link, "/proc/"); | ||
| 920 | p = format_pid (p, tracee->pid); | ||
| 921 | stpcpy (p, "/cwd"); | ||
| 922 | } | ||
| 923 | else if (fd < 0) | ||
| 924 | /* Invalid file descriptor. */ | ||
| 925 | return 1; | ||
| 926 | else | ||
| 927 | { | ||
| 928 | p = stpcpy (link, "/proc/"); | ||
| 929 | p = format_pid (p, tracee->pid); | ||
| 930 | p = stpcpy (p, "/fd/"); | ||
| 931 | format_pid (p, fd); | ||
| 932 | } | ||
| 933 | |||
| 934 | /* Read LINK's target, and should it be oversized, punt. */ | ||
| 935 | rc = readlink (link, target, PATH_MAX); | ||
| 936 | if (rc < 0 || rc >= PATH_MAX) | ||
| 937 | return 1; | ||
| 938 | |||
| 939 | /* Consider the amount by which BUFFER's existing contents should be | ||
| 940 | displaced. */ | ||
| 941 | |||
| 942 | length = strlen (buffer) + 1; | ||
| 943 | if ((length + rc + (target[rc - 1] != '/')) > size) | ||
| 944 | /* Punt if this would overflow. */ | ||
| 945 | return 1; | ||
| 946 | |||
| 947 | memmove ((buffer + rc + (target[rc - 1] != '/')), | ||
| 948 | buffer, length); | ||
| 949 | |||
| 950 | /* Copy the new file name into BUFFER. */ | ||
| 951 | memcpy (buffer, target, rc); | ||
| 952 | |||
| 953 | /* Insert separator in between if need be. */ | ||
| 954 | if (target[rc - 1] != '/') | ||
| 955 | buffer[rc] = '/'; | ||
| 956 | |||
| 957 | return 0; | ||
| 958 | } | ||
| 959 | |||
| 897 | /* Handle a `readlink' or `readlinkat' system call. | 960 | /* Handle a `readlink' or `readlinkat' system call. |
| 898 | 961 | ||
| 899 | CALLNO is the system call number, and REGS are the current user | 962 | CALLNO is the system call number, and REGS are the current user |
| @@ -924,22 +987,26 @@ handle_readlinkat (USER_WORD callno, USER_REGS_STRUCT *regs, | |||
| 924 | char buffer[PATH_MAX + 1]; | 987 | char buffer[PATH_MAX + 1]; |
| 925 | USER_WORD address, return_buffer, size; | 988 | USER_WORD address, return_buffer, size; |
| 926 | size_t length; | 989 | size_t length; |
| 990 | char proc_pid_exe[sizeof "/proc//exe" + 24], *p; | ||
| 991 | int dirfd; | ||
| 927 | 992 | ||
| 928 | /* Read the file name. */ | 993 | /* Read the file name. */ |
| 929 | 994 | ||
| 930 | #ifdef READLINK_SYSCALL | 995 | #ifdef READLINK_SYSCALL |
| 931 | if (callno == READLINK_SYSCALL) | 996 | if (callno == READLINK_SYSCALL) |
| 932 | { | 997 | { |
| 933 | address = regs->SYSCALL_ARG_REG; | 998 | dirfd = AT_FDCWD; |
| 999 | address = regs->SYSCALL_ARG_REG; | ||
| 934 | return_buffer = regs->SYSCALL_ARG1_REG; | 1000 | return_buffer = regs->SYSCALL_ARG1_REG; |
| 935 | size = regs->SYSCALL_ARG2_REG; | 1001 | size = regs->SYSCALL_ARG2_REG; |
| 936 | } | 1002 | } |
| 937 | else | 1003 | else |
| 938 | #endif /* READLINK_SYSCALL */ | 1004 | #endif /* READLINK_SYSCALL */ |
| 939 | { | 1005 | { |
| 940 | address = regs->SYSCALL_ARG1_REG; | 1006 | dirfd = (USER_SWORD) regs->SYSCALL_ARG_REG; |
| 1007 | address = regs->SYSCALL_ARG1_REG; | ||
| 941 | return_buffer = regs->SYSCALL_ARG2_REG; | 1008 | return_buffer = regs->SYSCALL_ARG2_REG; |
| 942 | size = regs->SYSCALL_ARG3_REG; | 1009 | size = regs->SYSCALL_ARG3_REG; |
| 943 | } | 1010 | } |
| 944 | 1011 | ||
| 945 | read_memory (tracee, buffer, PATH_MAX, address); | 1012 | read_memory (tracee, buffer, PATH_MAX, address); |
| @@ -952,12 +1019,25 @@ handle_readlinkat (USER_WORD callno, USER_REGS_STRUCT *regs, | |||
| 952 | return 1; | 1019 | return 1; |
| 953 | } | 1020 | } |
| 954 | 1021 | ||
| 955 | /* Now check if the caller is looking for /proc/self/exe. | 1022 | /* Expand BUFFER into an absolute file name. TODO: |
| 1023 | AT_SYMLINK_FOLLOW? */ | ||
| 1024 | |||
| 1025 | if (canon_path (tracee, dirfd, buffer, sizeof buffer)) | ||
| 1026 | return 0; | ||
| 1027 | |||
| 1028 | /* Now check if the caller is looking for /proc/self/exe or its | ||
| 1029 | equivalent with the PID made explicit. | ||
| 956 | 1030 | ||
| 957 | dirfd can be ignored, as for now only absolute file names are | 1031 | dirfd can be ignored, as for now only absolute file names are |
| 958 | handled. FIXME. */ | 1032 | handled. FIXME. */ |
| 959 | 1033 | ||
| 960 | if (strcmp (buffer, "/proc/self/exe") || !tracee->exec_file) | 1034 | p = stpcpy (proc_pid_exe, "/proc/"); |
| 1035 | p = format_pid (p, tracee->pid); | ||
| 1036 | stpcpy (p, "/exe"); | ||
| 1037 | |||
| 1038 | if ((strcmp (buffer, "/proc/self/exe") | ||
| 1039 | && strcmp (buffer, proc_pid_exe)) | ||
| 1040 | || !tracee->exec_file) | ||
| 961 | return 0; | 1041 | return 0; |
| 962 | 1042 | ||
| 963 | /* Copy over tracee->exec_file. Truncate it to PATH_MAX, length, or | 1043 | /* Copy over tracee->exec_file. Truncate it to PATH_MAX, length, or |
| @@ -1004,15 +1084,23 @@ handle_openat (USER_WORD callno, USER_REGS_STRUCT *regs, | |||
| 1004 | USER_WORD address; | 1084 | USER_WORD address; |
| 1005 | size_t length; | 1085 | size_t length; |
| 1006 | USER_REGS_STRUCT original; | 1086 | USER_REGS_STRUCT original; |
| 1087 | char proc_pid_exe[sizeof "/proc//exe" + 24], *p; | ||
| 1088 | int dirfd; | ||
| 1007 | 1089 | ||
| 1008 | /* Read the file name. */ | 1090 | /* Read the file name. */ |
| 1009 | 1091 | ||
| 1010 | #ifdef OPEN_SYSCALL | 1092 | #ifdef OPEN_SYSCALL |
| 1011 | if (callno == OPEN_SYSCALL) | 1093 | if (callno == OPEN_SYSCALL) |
| 1012 | address = regs->SYSCALL_ARG_REG; | 1094 | { |
| 1095 | dirfd = AT_FDCWD; | ||
| 1096 | address = regs->SYSCALL_ARG_REG; | ||
| 1097 | } | ||
| 1013 | else | 1098 | else |
| 1014 | #endif /* OPEN_SYSCALL */ | 1099 | #endif /* OPEN_SYSCALL */ |
| 1015 | address = regs->SYSCALL_ARG1_REG; | 1100 | { |
| 1101 | dirfd = (USER_SWORD) regs->SYSCALL_ARG_REG; | ||
| 1102 | address = regs->SYSCALL_ARG1_REG; | ||
| 1103 | } | ||
| 1016 | 1104 | ||
| 1017 | /* Read the file name into the buffer and verify that it is NULL | 1105 | /* Read the file name into the buffer and verify that it is NULL |
| 1018 | terminated. */ | 1106 | terminated. */ |
| @@ -1024,12 +1112,25 @@ handle_openat (USER_WORD callno, USER_REGS_STRUCT *regs, | |||
| 1024 | return 1; | 1112 | return 1; |
| 1025 | } | 1113 | } |
| 1026 | 1114 | ||
| 1027 | /* Now check if the caller is looking for /proc/self/exe. | 1115 | /* Expand BUFFER into an absolute file name. TODO: |
| 1116 | AT_SYMLINK_FOLLOW? */ | ||
| 1117 | |||
| 1118 | if (canon_path (tracee, dirfd, buffer, sizeof buffer)) | ||
| 1119 | return 0; | ||
| 1120 | |||
| 1121 | /* Now check if the caller is looking for /proc/self/exe or its | ||
| 1122 | equivalent with the PID made explicit. | ||
| 1028 | 1123 | ||
| 1029 | dirfd can be ignored, as for now only absolute file names are | 1124 | dirfd can be ignored, as for now only absolute file names are |
| 1030 | handled. FIXME. */ | 1125 | handled. FIXME. */ |
| 1031 | 1126 | ||
| 1032 | if (strcmp (buffer, "/proc/self/exe") || !tracee->exec_file) | 1127 | p = stpcpy (proc_pid_exe, "/proc/"); |
| 1128 | p = format_pid (p, tracee->pid); | ||
| 1129 | stpcpy (p, "/exe"); | ||
| 1130 | |||
| 1131 | if ((strcmp (buffer, "/proc/self/exe") | ||
| 1132 | && strcmp (buffer, proc_pid_exe)) | ||
| 1133 | || !tracee->exec_file) | ||
| 1033 | return 0; | 1134 | return 0; |
| 1034 | 1135 | ||
| 1035 | /* Copy over tracee->exec_file. This doesn't correctly handle the | 1136 | /* Copy over tracee->exec_file. This doesn't correctly handle the |