aboutsummaryrefslogtreecommitdiffstats
path: root/exec
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
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')
-rw-r--r--exec/config.h.in30
-rw-r--r--exec/configure.ac51
-rw-r--r--exec/exec.c52
-rw-r--r--exec/exec.h7
-rw-r--r--exec/trace.c168
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.
42You should have received a copy of the GNU General Public License 42You should have received a copy of the GNU General Public License
43along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */]) 43along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */])
44 44
45AC_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
45AC_PROG_CC 50AC_PROG_CC
46AC_PROG_CPP 51AC_PROG_CPP
47AC_PROG_INSTALL 52AC_PROG_INSTALL
@@ -56,6 +61,7 @@ AC_TYPE_PID_T
56AC_HEADER_STDBOOL 61AC_HEADER_STDBOOL
57AC_CHECK_FUNCS([getpagesize stpcpy stpncpy]) 62AC_CHECK_FUNCS([getpagesize stpcpy stpncpy])
58AC_CHECK_DECLS([stpcpy, stpncpy]) 63AC_CHECK_DECLS([stpcpy, stpncpy])
64AC_CHECK_HEADERS([sys/param.h]) dnl for MIN and MAX
59 65
60AH_BOTTOM([ 66AH_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
78AC_C_BIGENDIAN 96AC_C_BIGENDIAN
@@ -83,6 +101,8 @@ AH_TEMPLATE([USER_REGS_STRUCT], [Define to structure holding user registers.])
83AH_TEMPLATE([SYSCALL_NUM_REG], [Define to register holding the system call number.]) 101AH_TEMPLATE([SYSCALL_NUM_REG], [Define to register holding the system call number.])
84AH_TEMPLATE([SYSCALL_ARG_REG], [Define to register holding arg0 to system calls.]) 102AH_TEMPLATE([SYSCALL_ARG_REG], [Define to register holding arg0 to system calls.])
85AH_TEMPLATE([SYSCALL_ARG1_REG], [Define to register holding arg1 to system calls.]) 103AH_TEMPLATE([SYSCALL_ARG1_REG], [Define to register holding arg1 to system calls.])
104AH_TEMPLATE([SYSCALL_ARG2_REG], [Define to register holding arg2 to system calls.])
105AH_TEMPLATE([SYSCALL_ARG3_REG], [Define to register holding arg3 to system calls.])
86AH_TEMPLATE([SYSCALL_RET_REG], [Define to register holding value of system calls.]) 106AH_TEMPLATE([SYSCALL_RET_REG], [Define to register holding value of system calls.])
87AH_TEMPLATE([STACK_POINTER], [Define to register holding the stack pointer.]) 107AH_TEMPLATE([STACK_POINTER], [Define to register holding the stack pointer.])
88AH_TEMPLATE([EXEC_SYSCALL], [Define to number of the `exec' system call.]) 108AH_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])
94AH_TEMPLATE([INTERPRETER_BASE], [Virtual address for loading PIC interpreters]) 114AH_TEMPLATE([INTERPRETER_BASE], [Virtual address for loading PIC interpreters])
95AH_TEMPLATE([CLONE_SYSCALL], [Define to number of the `clone' system call.]) 115AH_TEMPLATE([CLONE_SYSCALL], [Define to number of the `clone' system call.])
96AH_TEMPLATE([CLONE3_SYSCALL], [Define to number of the `clone3' system call.]) 116AH_TEMPLATE([CLONE3_SYSCALL], [Define to number of the `clone3' system call.])
117AH_TEMPLATE([READLINK_SYSCALL], [Define to number of the `readlink' system call.])
118AH_TEMPLATE([READLINKAT_SYSCALL], [Define to number of the `readlinkat' system call.])
119AH_TEMPLATE([REENTRANT], [Define to 1 if the library is used within a signal handler.])
97 120
98AC_CANONICAL_HOST 121AC_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
950char * 946char *
951exec_0 (const char *name, struct exec_tracee *tracee, 947exec_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
187extern char *exec_0 (const char *, struct exec_tracee *, 192extern 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)
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}