diff options
| author | Po Lu | 2023-05-02 20:45:57 +0800 |
|---|---|---|
| committer | Po Lu | 2023-05-02 20:45:57 +0800 |
| commit | c47716f95b8fda9438047d2683a415a65c18ecbd (patch) | |
| tree | 947c45293556f41ce02426889890b3442f2b7b36 /exec | |
| parent | f4512cca0b996e5343ebe57511f45a29f64c4a8e (diff) | |
| download | emacs-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')
| -rw-r--r-- | exec/config.h.in | 30 | ||||
| -rw-r--r-- | exec/configure.ac | 51 | ||||
| -rw-r--r-- | exec/exec.c | 52 | ||||
| -rw-r--r-- | exec/exec.h | 7 | ||||
| -rw-r--r-- | exec/trace.c | 168 |
5 files changed, 288 insertions, 20 deletions
diff --git a/exec/config.h.in b/exec/config.h.in index d8c225b631d..c360e54a4ba 100644 --- a/exec/config.h.in +++ b/exec/config.h.in | |||
| @@ -76,6 +76,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 76 | /* Define to 1 if you have the <string.h> header file. */ | 76 | /* Define to 1 if you have the <string.h> header file. */ |
| 77 | #undef HAVE_STRING_H | 77 | #undef HAVE_STRING_H |
| 78 | 78 | ||
| 79 | /* Define to 1 if you have the <sys/param.h> header file. */ | ||
| 80 | #undef HAVE_SYS_PARAM_H | ||
| 81 | |||
| 79 | /* Define to 1 if you have the <sys/stat.h> header file. */ | 82 | /* Define to 1 if you have the <sys/stat.h> header file. */ |
| 80 | #undef HAVE_SYS_STAT_H | 83 | #undef HAVE_SYS_STAT_H |
| 81 | 84 | ||
| @@ -115,6 +118,15 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 115 | /* Define to the version of this package. */ | 118 | /* Define to the version of this package. */ |
| 116 | #undef PACKAGE_VERSION | 119 | #undef PACKAGE_VERSION |
| 117 | 120 | ||
| 121 | /* Define to number of the `readlinkat' system call. */ | ||
| 122 | #undef READLINKAT_SYSCALL | ||
| 123 | |||
| 124 | /* Define to number of the `readlink' system call. */ | ||
| 125 | #undef READLINK_SYSCALL | ||
| 126 | |||
| 127 | /* Define to 1 if the library is used within a signal handler. */ | ||
| 128 | #undef REENTRANT | ||
| 129 | |||
| 118 | /* Define to 1 if the stack grows downwards. */ | 130 | /* Define to 1 if the stack grows downwards. */ |
| 119 | #undef STACK_GROWS_DOWNWARDS | 131 | #undef STACK_GROWS_DOWNWARDS |
| 120 | 132 | ||
| @@ -129,6 +141,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 129 | /* Define to register holding arg1 to system calls. */ | 141 | /* Define to register holding arg1 to system calls. */ |
| 130 | #undef SYSCALL_ARG1_REG | 142 | #undef SYSCALL_ARG1_REG |
| 131 | 143 | ||
| 144 | /* Define to register holding arg2 to system calls. */ | ||
| 145 | #undef SYSCALL_ARG2_REG | ||
| 146 | |||
| 147 | /* Define to register holding arg3 to system calls. */ | ||
| 148 | #undef SYSCALL_ARG3_REG | ||
| 149 | |||
| 132 | /* Define to register holding arg0 to system calls. */ | 150 | /* Define to register holding arg0 to system calls. */ |
| 133 | #undef SYSCALL_ARG_REG | 151 | #undef SYSCALL_ARG_REG |
| 134 | 152 | ||
| @@ -217,3 +235,15 @@ typedef bool _Bool; | |||
| 217 | # define __bool_true_false_are_defined 1 | 235 | # define __bool_true_false_are_defined 1 |
| 218 | #endif | 236 | #endif |
| 219 | 237 | ||
| 238 | #ifdef HAVE_SYS_PARAM_H | ||
| 239 | #include <sys/param.h> | ||
| 240 | #endif /* HAVE_SYS_PARAM_H */ | ||
| 241 | |||
| 242 | #ifndef MAX | ||
| 243 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) | ||
| 244 | #endif /* MAX */ | ||
| 245 | |||
| 246 | #ifndef MIN | ||
| 247 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) | ||
| 248 | #endif /* MIN */ | ||
| 249 | |||
diff --git a/exec/configure.ac b/exec/configure.ac index f3eef60173c..b948e184896 100644 --- a/exec/configure.ac +++ b/exec/configure.ac | |||
| @@ -42,6 +42,11 @@ General Public License for more details. | |||
| 42 | You should have received a copy of the GNU General Public License | 42 | You should have received a copy of the GNU General Public License |
| 43 | along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */]) | 43 | along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */]) |
| 44 | 44 | ||
| 45 | AC_ARG_WITH([reentrancy], | ||
| 46 | [AS_HELP_STRING([--with-reentrancy], | ||
| 47 | [Generate library which can be used within a signal handler.])], | ||
| 48 | [AC_DEFINE([REENTRANT], [1])]) | ||
| 49 | |||
| 45 | AC_PROG_CC | 50 | AC_PROG_CC |
| 46 | AC_PROG_CPP | 51 | AC_PROG_CPP |
| 47 | AC_PROG_INSTALL | 52 | AC_PROG_INSTALL |
| @@ -56,6 +61,7 @@ AC_TYPE_PID_T | |||
| 56 | AC_HEADER_STDBOOL | 61 | AC_HEADER_STDBOOL |
| 57 | AC_CHECK_FUNCS([getpagesize stpcpy stpncpy]) | 62 | AC_CHECK_FUNCS([getpagesize stpcpy stpncpy]) |
| 58 | AC_CHECK_DECLS([stpcpy, stpncpy]) | 63 | AC_CHECK_DECLS([stpcpy, stpncpy]) |
| 64 | AC_CHECK_HEADERS([sys/param.h]) dnl for MIN and MAX | ||
| 59 | 65 | ||
| 60 | AH_BOTTOM([ | 66 | AH_BOTTOM([ |
| 61 | #ifdef HAVE_STDBOOL_H | 67 | #ifdef HAVE_STDBOOL_H |
| @@ -73,6 +79,18 @@ typedef bool _Bool; | |||
| 73 | # define true 1 | 79 | # define true 1 |
| 74 | # define __bool_true_false_are_defined 1 | 80 | # define __bool_true_false_are_defined 1 |
| 75 | #endif | 81 | #endif |
| 82 | |||
| 83 | #ifdef HAVE_SYS_PARAM_H | ||
| 84 | #include <sys/param.h> | ||
| 85 | #endif /* HAVE_SYS_PARAM_H */ | ||
| 86 | |||
| 87 | #ifndef MAX | ||
| 88 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) | ||
| 89 | #endif /* MAX */ | ||
| 90 | |||
| 91 | #ifndef MIN | ||
| 92 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) | ||
| 93 | #endif /* MIN */ | ||
| 76 | ]) | 94 | ]) |
| 77 | 95 | ||
| 78 | AC_C_BIGENDIAN | 96 | AC_C_BIGENDIAN |
| @@ -83,6 +101,8 @@ AH_TEMPLATE([USER_REGS_STRUCT], [Define to structure holding user registers.]) | |||
| 83 | AH_TEMPLATE([SYSCALL_NUM_REG], [Define to register holding the system call number.]) | 101 | AH_TEMPLATE([SYSCALL_NUM_REG], [Define to register holding the system call number.]) |
| 84 | AH_TEMPLATE([SYSCALL_ARG_REG], [Define to register holding arg0 to system calls.]) | 102 | AH_TEMPLATE([SYSCALL_ARG_REG], [Define to register holding arg0 to system calls.]) |
| 85 | AH_TEMPLATE([SYSCALL_ARG1_REG], [Define to register holding arg1 to system calls.]) | 103 | AH_TEMPLATE([SYSCALL_ARG1_REG], [Define to register holding arg1 to system calls.]) |
| 104 | AH_TEMPLATE([SYSCALL_ARG2_REG], [Define to register holding arg2 to system calls.]) | ||
| 105 | AH_TEMPLATE([SYSCALL_ARG3_REG], [Define to register holding arg3 to system calls.]) | ||
| 86 | AH_TEMPLATE([SYSCALL_RET_REG], [Define to register holding value of system calls.]) | 106 | AH_TEMPLATE([SYSCALL_RET_REG], [Define to register holding value of system calls.]) |
| 87 | AH_TEMPLATE([STACK_POINTER], [Define to register holding the stack pointer.]) | 107 | AH_TEMPLATE([STACK_POINTER], [Define to register holding the stack pointer.]) |
| 88 | AH_TEMPLATE([EXEC_SYSCALL], [Define to number of the `exec' system call.]) | 108 | AH_TEMPLATE([EXEC_SYSCALL], [Define to number of the `exec' system call.]) |
| @@ -94,6 +114,9 @@ AH_TEMPLATE([EXECUTABLE_BASE], [Virtual address for loading PIC executables]) | |||
| 94 | AH_TEMPLATE([INTERPRETER_BASE], [Virtual address for loading PIC interpreters]) | 114 | AH_TEMPLATE([INTERPRETER_BASE], [Virtual address for loading PIC interpreters]) |
| 95 | AH_TEMPLATE([CLONE_SYSCALL], [Define to number of the `clone' system call.]) | 115 | AH_TEMPLATE([CLONE_SYSCALL], [Define to number of the `clone' system call.]) |
| 96 | AH_TEMPLATE([CLONE3_SYSCALL], [Define to number of the `clone3' system call.]) | 116 | AH_TEMPLATE([CLONE3_SYSCALL], [Define to number of the `clone3' system call.]) |
| 117 | AH_TEMPLATE([READLINK_SYSCALL], [Define to number of the `readlink' system call.]) | ||
| 118 | AH_TEMPLATE([READLINKAT_SYSCALL], [Define to number of the `readlinkat' system call.]) | ||
| 119 | AH_TEMPLATE([REENTRANT], [Define to 1 if the library is used within a signal handler.]) | ||
| 97 | 120 | ||
| 98 | AC_CANONICAL_HOST | 121 | AC_CANONICAL_HOST |
| 99 | 122 | ||
| @@ -206,6 +229,8 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 206 | AC_DEFINE([SYSCALL_RET_REG], [rax]) | 229 | AC_DEFINE([SYSCALL_RET_REG], [rax]) |
| 207 | AC_DEFINE([SYSCALL_ARG_REG], [rdi]) | 230 | AC_DEFINE([SYSCALL_ARG_REG], [rdi]) |
| 208 | AC_DEFINE([SYSCALL_ARG1_REG], [rsi]) | 231 | AC_DEFINE([SYSCALL_ARG1_REG], [rsi]) |
| 232 | AC_DEFINE([SYSCALL_ARG2_REG], [rdx]) | ||
| 233 | AC_DEFINE([SYSCALL_ARG3_REG], [r10]) | ||
| 209 | AC_DEFINE([STACK_POINTER], [rsp]) | 234 | AC_DEFINE([STACK_POINTER], [rsp]) |
| 210 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) | 235 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) |
| 211 | AC_DEFINE([USER_WORD], [uintptr_t]) | 236 | AC_DEFINE([USER_WORD], [uintptr_t]) |
| @@ -215,6 +240,8 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 215 | AC_DEFINE([INTERPRETER_BASE], [0x600000000000]) | 240 | AC_DEFINE([INTERPRETER_BASE], [0x600000000000]) |
| 216 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) | 241 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) |
| 217 | AC_DEFINE([CLONE_SYSCALL], [__NR_clone]) | 242 | AC_DEFINE([CLONE_SYSCALL], [__NR_clone]) |
| 243 | AC_DEFINE([READLINK_SYSCALL], [__NR_readlink]) | ||
| 244 | AC_DEFINE([READLINKAT_SYSCALL], [__NR_readlinkat]) | ||
| 218 | exec_CHECK_LINUX_CLONE3 | 245 | exec_CHECK_LINUX_CLONE3 |
| 219 | # Make sure the loader doesn't conflict with other position | 246 | # Make sure the loader doesn't conflict with other position |
| 220 | # dependent code. | 247 | # dependent code. |
| @@ -232,6 +259,8 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 232 | AC_DEFINE([SYSCALL_RET_REG], [eax]) | 259 | AC_DEFINE([SYSCALL_RET_REG], [eax]) |
| 233 | AC_DEFINE([SYSCALL_ARG_REG], [ebx]) | 260 | AC_DEFINE([SYSCALL_ARG_REG], [ebx]) |
| 234 | AC_DEFINE([SYSCALL_ARG1_REG], [ecx]) | 261 | AC_DEFINE([SYSCALL_ARG1_REG], [ecx]) |
| 262 | AC_DEFINE([SYSCALL_ARG2_REG], [edx]) | ||
| 263 | AC_DEFINE([SYSCALL_ARG3_REG], [esi]) | ||
| 235 | AC_DEFINE([STACK_POINTER], [esp]) | 264 | AC_DEFINE([STACK_POINTER], [esp]) |
| 236 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) | 265 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) |
| 237 | AC_DEFINE([USER_WORD], [uintptr_t]) | 266 | AC_DEFINE([USER_WORD], [uintptr_t]) |
| @@ -239,6 +268,8 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 239 | AC_DEFINE([INTERPRETER_BASE], [0xaf000000]) | 268 | AC_DEFINE([INTERPRETER_BASE], [0xaf000000]) |
| 240 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) | 269 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) |
| 241 | AC_DEFINE([CLONE_SYSCALL], [__NR_clone]) | 270 | AC_DEFINE([CLONE_SYSCALL], [__NR_clone]) |
| 271 | AC_DEFINE([READLINK_SYSCALL], [__NR_readlink]) | ||
| 272 | AC_DEFINE([READLINKAT_SYSCALL], [__NR_readlinkat]) | ||
| 242 | exec_CHECK_LINUX_CLONE3 | 273 | exec_CHECK_LINUX_CLONE3 |
| 243 | # Make sure the loader doesn't conflict with other position | 274 | # Make sure the loader doesn't conflict with other position |
| 244 | # dependent code. | 275 | # dependent code. |
| @@ -256,6 +287,8 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 256 | AC_DEFINE([SYSCALL_RET_REG], [[regs[0]]]) | 287 | AC_DEFINE([SYSCALL_RET_REG], [[regs[0]]]) |
| 257 | AC_DEFINE([SYSCALL_ARG_REG], [[regs[0]]]) | 288 | AC_DEFINE([SYSCALL_ARG_REG], [[regs[0]]]) |
| 258 | AC_DEFINE([SYSCALL_ARG1_REG], [[regs[1]]]) | 289 | AC_DEFINE([SYSCALL_ARG1_REG], [[regs[1]]]) |
| 290 | AC_DEFINE([SYSCALL_ARG2_REG], [[regs[2]]]) | ||
| 291 | AC_DEFINE([SYSCALL_ARG3_REG], [[regs[3]]]) | ||
| 259 | AC_DEFINE([STACK_POINTER], [sp]) | 292 | AC_DEFINE([STACK_POINTER], [sp]) |
| 260 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) | 293 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) |
| 261 | AC_DEFINE([USER_WORD], [uintptr_t]) | 294 | AC_DEFINE([USER_WORD], [uintptr_t]) |
| @@ -264,6 +297,8 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 264 | AC_DEFINE([INTERPRETER_BASE], [0x3f00000000]) | 297 | AC_DEFINE([INTERPRETER_BASE], [0x3f00000000]) |
| 265 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) | 298 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) |
| 266 | AC_DEFINE([CLONE_SYSCALL], [__NR_clone]) | 299 | AC_DEFINE([CLONE_SYSCALL], [__NR_clone]) |
| 300 | # Note that aarch64 has no `readlink'. | ||
| 301 | AC_DEFINE([READLINKAT_SYSCALL], [__NR_readlinkat]) | ||
| 267 | exec_CHECK_LINUX_CLONE3 | 302 | exec_CHECK_LINUX_CLONE3 |
| 268 | # Make sure the loader doesn't conflict with other position | 303 | # Make sure the loader doesn't conflict with other position |
| 269 | # dependent code. ARM places rather significant restrictions on | 304 | # dependent code. ARM places rather significant restrictions on |
| @@ -282,6 +317,8 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 282 | AC_DEFINE([SYSCALL_RET_REG], [[uregs[0]]]) | 317 | AC_DEFINE([SYSCALL_RET_REG], [[uregs[0]]]) |
| 283 | AC_DEFINE([SYSCALL_ARG_REG], [[uregs[0]]]) | 318 | AC_DEFINE([SYSCALL_ARG_REG], [[uregs[0]]]) |
| 284 | AC_DEFINE([SYSCALL_ARG1_REG], [[uregs[1]]]) | 319 | AC_DEFINE([SYSCALL_ARG1_REG], [[uregs[1]]]) |
| 320 | AC_DEFINE([SYSCALL_ARG2_REG], [[uregs[2]]]) | ||
| 321 | AC_DEFINE([SYSCALL_ARG3_REG], [[uregs[3]]]) | ||
| 285 | AC_DEFINE([STACK_POINTER], [[uregs[13]]]) | 322 | AC_DEFINE([STACK_POINTER], [[uregs[13]]]) |
| 286 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) | 323 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) |
| 287 | AC_DEFINE([USER_WORD], [uintptr_t]) | 324 | AC_DEFINE([USER_WORD], [uintptr_t]) |
| @@ -289,6 +326,8 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 289 | AC_DEFINE([INTERPRETER_BASE], [0x1f000000]) | 326 | AC_DEFINE([INTERPRETER_BASE], [0x1f000000]) |
| 290 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) | 327 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) |
| 291 | AC_DEFINE([CLONE_SYSCALL], [__NR_clone]) | 328 | AC_DEFINE([CLONE_SYSCALL], [__NR_clone]) |
| 329 | AC_DEFINE([READLINK_SYSCALL], [__NR_readlink]) | ||
| 330 | AC_DEFINE([READLINKAT_SYSCALL], [__NR_readlinkat]) | ||
| 292 | exec_CHECK_LINUX_CLONE3 | 331 | exec_CHECK_LINUX_CLONE3 |
| 293 | LOADERFLAGS="$LOADERFLAGS $LDPREFIX-Ttext=0x20000000" | 332 | LOADERFLAGS="$LOADERFLAGS $LDPREFIX-Ttext=0x20000000" |
| 294 | exec_loader=loader-armeabi.s], | 333 | exec_loader=loader-armeabi.s], |
| @@ -300,6 +339,8 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 300 | AC_DEFINE([SYSCALL_RET_REG], [[uregs[0]]]) | 339 | AC_DEFINE([SYSCALL_RET_REG], [[uregs[0]]]) |
| 301 | AC_DEFINE([SYSCALL_ARG_REG], [[uregs[0]]]) | 340 | AC_DEFINE([SYSCALL_ARG_REG], [[uregs[0]]]) |
| 302 | AC_DEFINE([SYSCALL_ARG1_REG], [[uregs[1]]]) | 341 | AC_DEFINE([SYSCALL_ARG1_REG], [[uregs[1]]]) |
| 342 | AC_DEFINE([SYSCALL_ARG2_REG], [[uregs[2]]]) | ||
| 343 | AC_DEFINE([SYSCALL_ARG3_REG], [[uregs[3]]]) | ||
| 303 | AC_DEFINE([STACK_POINTER], [[uregs[13]]]) | 344 | AC_DEFINE([STACK_POINTER], [[uregs[13]]]) |
| 304 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) | 345 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) |
| 305 | AC_DEFINE([USER_WORD], [uintptr_t]) | 346 | AC_DEFINE([USER_WORD], [uintptr_t]) |
| @@ -307,6 +348,8 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 307 | AC_DEFINE([INTERPRETER_BASE], [0x1f000000]) | 348 | AC_DEFINE([INTERPRETER_BASE], [0x1f000000]) |
| 308 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) | 349 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) |
| 309 | AC_DEFINE([CLONE_SYSCALL], [__NR_clone]) | 350 | AC_DEFINE([CLONE_SYSCALL], [__NR_clone]) |
| 351 | AC_DEFINE([READLINK_SYSCALL], [__NR_readlink]) | ||
| 352 | AC_DEFINE([READLINKAT_SYSCALL], [__NR_readlinkat]) | ||
| 310 | exec_CHECK_LINUX_CLONE3 | 353 | exec_CHECK_LINUX_CLONE3 |
| 311 | LOADERFLAGS="$LOADERFLAGS $LDPREFIX-Ttext=0x20000000" | 354 | LOADERFLAGS="$LOADERFLAGS $LDPREFIX-Ttext=0x20000000" |
| 312 | exec_loader=loader-armeabi.s], | 355 | exec_loader=loader-armeabi.s], |
| @@ -324,6 +367,8 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 324 | AC_DEFINE([SYSCALL_RET_REG], [[gregs[4]]]) # a0 | 367 | AC_DEFINE([SYSCALL_RET_REG], [[gregs[4]]]) # a0 |
| 325 | AC_DEFINE([SYSCALL_ARG_REG], [[gregs[4]]]) # a0 | 368 | AC_DEFINE([SYSCALL_ARG_REG], [[gregs[4]]]) # a0 |
| 326 | AC_DEFINE([SYSCALL_ARG1_REG], [[gregs[5]]]) # a1 | 369 | AC_DEFINE([SYSCALL_ARG1_REG], [[gregs[5]]]) # a1 |
| 370 | AC_DEFINE([SYSCALL_ARG2_REG], [[gregs[4]]]) # a2 | ||
| 371 | AC_DEFINE([SYSCALL_ARG3_REG], [[gregs[5]]]) # a3 | ||
| 327 | AC_DEFINE([STACK_POINTER], [[gregs[29]]]) # sp | 372 | AC_DEFINE([STACK_POINTER], [[gregs[29]]]) # sp |
| 328 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) | 373 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) |
| 329 | AC_DEFINE([USER_WORD], [uintptr_t]) | 374 | AC_DEFINE([USER_WORD], [uintptr_t]) |
| @@ -331,6 +376,8 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 331 | AC_DEFINE([INTERPRETER_BASE], [0x1f000000]) | 376 | AC_DEFINE([INTERPRETER_BASE], [0x1f000000]) |
| 332 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) | 377 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) |
| 333 | AC_DEFINE([CLONE_SYSCALL], [__NR_clone]) | 378 | AC_DEFINE([CLONE_SYSCALL], [__NR_clone]) |
| 379 | AC_DEFINE([READLINK_SYSCALL], [__NR_readlink]) | ||
| 380 | AC_DEFINE([READLINKAT_SYSCALL], [__NR_readlinkat]) | ||
| 334 | AC_CHECK_DECL([_MIPS_SIM], [exec_CHECK_MIPS_NABI], | 381 | AC_CHECK_DECL([_MIPS_SIM], [exec_CHECK_MIPS_NABI], |
| 335 | [AC_MSG_ERROR([_MIPS_SIM could not be determined]), | 382 | [AC_MSG_ERROR([_MIPS_SIM could not be determined]), |
| 336 | [[ | 383 | [[ |
| @@ -347,6 +394,8 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 347 | AC_DEFINE([SYSCALL_RET_REG], [[gregs[4]]]) # a0 | 394 | AC_DEFINE([SYSCALL_RET_REG], [[gregs[4]]]) # a0 |
| 348 | AC_DEFINE([SYSCALL_ARG_REG], [[gregs[4]]]) # a0 | 395 | AC_DEFINE([SYSCALL_ARG_REG], [[gregs[4]]]) # a0 |
| 349 | AC_DEFINE([SYSCALL_ARG1_REG], [[gregs[5]]]) # a1 | 396 | AC_DEFINE([SYSCALL_ARG1_REG], [[gregs[5]]]) # a1 |
| 397 | AC_DEFINE([SYSCALL_ARG2_REG], [[gregs[4]]]) # a2 | ||
| 398 | AC_DEFINE([SYSCALL_ARG3_REG], [[gregs[5]]]) # a3 | ||
| 350 | AC_DEFINE([STACK_POINTER], [[gregs[29]]]) # sp | 399 | AC_DEFINE([STACK_POINTER], [[gregs[29]]]) # sp |
| 351 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) | 400 | AC_DEFINE([EXEC_SYSCALL], [__NR_execve]) |
| 352 | AC_DEFINE([USER_WORD], [uintptr_t]) | 401 | AC_DEFINE([USER_WORD], [uintptr_t]) |
| @@ -355,6 +404,8 @@ AS_CASE([$host], [x86_64-*linux*], | |||
| 355 | AC_DEFINE([INTERPRETER_BASE], [0x3f00000000]) | 404 | AC_DEFINE([INTERPRETER_BASE], [0x3f00000000]) |
| 356 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) | 405 | AC_DEFINE([STACK_GROWS_DOWNWARDS], [1]) |
| 357 | AC_DEFINE([CLONE_SYSCALL], [__NR_clone]) | 406 | AC_DEFINE([CLONE_SYSCALL], [__NR_clone]) |
| 407 | AC_DEFINE([READLINK_SYSCALL], [__NR_readlink]) | ||
| 408 | AC_DEFINE([READLINKAT_SYSCALL], [__NR_readlinkat]) | ||
| 358 | AC_CACHE_CHECK([whether as understands `daddi'], | 409 | AC_CACHE_CHECK([whether as understands `daddi'], |
| 359 | [exec_cv_as_daddi], | 410 | [exec_cv_as_daddi], |
| 360 | [exec_cv_as_daddi=no | 411 | [exec_cv_as_daddi=no |
diff --git a/exec/exec.c b/exec/exec.c index 7f2cc75338b..17051428658 100644 --- a/exec/exec.c +++ b/exec/exec.c | |||
| @@ -31,14 +31,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 31 | #include <sys/param.h> | 31 | #include <sys/param.h> |
| 32 | #include <sys/mman.h> | 32 | #include <sys/mman.h> |
| 33 | 33 | ||
| 34 | #ifndef MIN | ||
| 35 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) | ||
| 36 | #endif /* MIN */ | ||
| 37 | |||
| 38 | #ifndef MAX | ||
| 39 | #define MAX(a, b) ((a) < (b) ? (b) : (a)) | ||
| 40 | #endif /* MAX */ | ||
| 41 | |||
| 42 | #include "exec.h" | 34 | #include "exec.h" |
| 43 | 35 | ||
| 44 | #if defined __mips__ && !defined MIPS_NABI | 36 | #if defined __mips__ && !defined MIPS_NABI |
| @@ -938,6 +930,10 @@ format_pid (char *in, unsigned int pid) | |||
| 938 | with #!; in that case, find the program to open and use that | 930 | with #!; in that case, find the program to open and use that |
| 939 | instead. | 931 | instead. |
| 940 | 932 | ||
| 933 | If REENTRANT is not defined, NAME is actually a buffer of size | ||
| 934 | PATH_MAX + 80. In that case, copy over the file name actually | ||
| 935 | opened. | ||
| 936 | |||
| 941 | Next, read the executable header, and add the necessary memory | 937 | Next, read the executable header, and add the necessary memory |
| 942 | mappings for each file. Finally, return the action data and its | 938 | mappings for each file. Finally, return the action data and its |
| 943 | size in *SIZE. | 939 | size in *SIZE. |
| @@ -948,7 +944,7 @@ format_pid (char *in, unsigned int pid) | |||
| 948 | Value is NULL upon failure, with errno set accordingly. */ | 944 | Value is NULL upon failure, with errno set accordingly. */ |
| 949 | 945 | ||
| 950 | char * | 946 | char * |
| 951 | exec_0 (const char *name, struct exec_tracee *tracee, | 947 | exec_0 (char *name, struct exec_tracee *tracee, |
| 952 | size_t *size, USER_REGS_STRUCT *regs) | 948 | size_t *size, USER_REGS_STRUCT *regs) |
| 953 | { | 949 | { |
| 954 | int fd, rc, i; | 950 | int fd, rc, i; |
| @@ -961,7 +957,8 @@ exec_0 (const char *name, struct exec_tracee *tracee, | |||
| 961 | #if defined __mips__ && !defined MIPS_NABI | 957 | #if defined __mips__ && !defined MIPS_NABI |
| 962 | int fpu_mode; | 958 | int fpu_mode; |
| 963 | #endif /* defined __mips__ && !defined MIPS_NABI */ | 959 | #endif /* defined __mips__ && !defined MIPS_NABI */ |
| 964 | char buffer[PATH_MAX + 80], *rewrite; | 960 | char buffer[80], buffer1[PATH_MAX + 80], *rewrite; |
| 961 | ssize_t link_size; | ||
| 965 | size_t remaining; | 962 | size_t remaining; |
| 966 | 963 | ||
| 967 | /* If name is not absolute, then make it relative to TRACEE's | 964 | /* If name is not absolute, then make it relative to TRACEE's |
| @@ -971,18 +968,43 @@ exec_0 (const char *name, struct exec_tracee *tracee, | |||
| 971 | { | 968 | { |
| 972 | /* Clear `buffer'. */ | 969 | /* Clear `buffer'. */ |
| 973 | memset (buffer, 0, sizeof buffer); | 970 | memset (buffer, 0, sizeof buffer); |
| 971 | memset (buffer1, 0, sizeof buffer); | ||
| 974 | 972 | ||
| 975 | /* Copy over /proc, the PID, and /cwd/. */ | 973 | /* Copy over /proc, the PID, and /cwd/. */ |
| 976 | rewrite = stpcpy (buffer, "/proc/"); | 974 | rewrite = stpcpy (buffer, "/proc/"); |
| 977 | rewrite = format_pid (rewrite, tracee->pid); | 975 | rewrite = format_pid (rewrite, tracee->pid); |
| 978 | rewrite = stpcpy (rewrite, "/cwd/"); | 976 | stpcpy (rewrite, "/cwd"); |
| 977 | |||
| 978 | /* Resolve this symbolic link. */ | ||
| 979 | |||
| 980 | link_size = readlink (buffer, buffer1, | ||
| 981 | PATH_MAX + 1); | ||
| 982 | |||
| 983 | if (link_size < 0) | ||
| 984 | return NULL; | ||
| 985 | |||
| 986 | /* Check that the name is a reasonable size. */ | ||
| 987 | |||
| 988 | if (link_size > PATH_MAX) | ||
| 989 | { | ||
| 990 | /* The name is too long. */ | ||
| 991 | errno = ENAMETOOLONG; | ||
| 992 | return NULL; | ||
| 993 | } | ||
| 994 | |||
| 995 | /* Add a directory separator if necessary. */ | ||
| 996 | |||
| 997 | if (!link_size || buffer1[link_size - 1] != '/') | ||
| 998 | buffer1[link_size] = '/', link_size++; | ||
| 979 | 999 | ||
| 980 | /* Make sure there is enough free space. */ | 1000 | rewrite = buffer1 + link_size; |
| 981 | remaining = buffer + sizeof buffer - rewrite - 1; | 1001 | remaining = buffer1 + sizeof buffer1 - rewrite - 1; |
| 982 | rewrite = stpncpy (rewrite, name, remaining); | 1002 | rewrite = stpncpy (rewrite, name, remaining); |
| 983 | 1003 | ||
| 984 | /* Replace name with buffer. */ | 1004 | /* Replace name with buffer1. */ |
| 985 | name = buffer; | 1005 | #ifndef REENTRANT |
| 1006 | strcpy (name, buffer1); | ||
| 1007 | #endif /* REENTRANT */ | ||
| 986 | } | 1008 | } |
| 987 | 1009 | ||
| 988 | fd = open (name, O_RDONLY); | 1010 | fd = open (name, O_RDONLY); |
diff --git a/exec/exec.h b/exec/exec.h index 0f6a8a893b6..625ad0bb219 100644 --- a/exec/exec.h +++ b/exec/exec.h | |||
| @@ -154,6 +154,11 @@ struct exec_tracee | |||
| 154 | /* Whether or not the tracee is currently waiting for a system call | 154 | /* Whether or not the tracee is currently waiting for a system call |
| 155 | to complete. */ | 155 | to complete. */ |
| 156 | bool waiting_for_syscall; | 156 | bool waiting_for_syscall; |
| 157 | |||
| 158 | #ifndef REENTRANT | ||
| 159 | /* Name of the executable being run. */ | ||
| 160 | char *exec_file; | ||
| 161 | #endif /* !REENTRANT */ | ||
| 157 | }; | 162 | }; |
| 158 | 163 | ||
| 159 | 164 | ||
| @@ -184,7 +189,7 @@ extern pid_t exec_waitpid (pid_t, int *, int); | |||
| 184 | 189 | ||
| 185 | /* Defined in exec.c. */ | 190 | /* Defined in exec.c. */ |
| 186 | 191 | ||
| 187 | extern char *exec_0 (const char *, struct exec_tracee *, | 192 | extern char *exec_0 (char *, struct exec_tracee *, |
| 188 | size_t *, USER_REGS_STRUCT *); | 193 | size_t *, USER_REGS_STRUCT *); |
| 189 | 194 | ||
| 190 | 195 | ||
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) | |||
| 431 | static int | 438 | static int |
| 432 | handle_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs) | 439 | handle_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 | |||
| 659 | static int | ||
| 660 | handle_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, ®s); | 745 | rc = aarch64_get_regs (tracee->pid, ®s); |
| @@ -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, ®s, 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, ®s, false); | ||
| 931 | #else /* !__aarch64__ */ | ||
| 932 | ptrace (PTRACE_SETREGS, tracee->pid, NULL, ®s); | ||
| 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 | } |