Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
/* Program execution for Emacs.
|
|
|
|
|
|
2025-01-01 07:39:17 +00:00
|
|
|
|
Copyright (C) 2023-2025 Free Software Foundation, Inc.
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
|
|
|
|
This file is part of GNU Emacs.
|
|
|
|
|
|
|
|
|
|
GNU Emacs is free software: you can redistribute it and/or modify
|
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
|
the Free Software Foundation, either version 3 of the License, or (at
|
|
|
|
|
your option) any later version.
|
|
|
|
|
|
|
|
|
|
GNU Emacs is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include <string.h>
|
2023-05-01 21:23:12 +08:00
|
|
|
|
#include <stdlib.h>
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
|
|
|
|
#include <sys/ptrace.h>
|
|
|
|
|
#include <sys/param.h>
|
|
|
|
|
#include <sys/mman.h>
|
|
|
|
|
|
|
|
|
|
#include "exec.h"
|
|
|
|
|
|
|
|
|
|
#if defined __mips__ && !defined MIPS_NABI
|
|
|
|
|
#include "mipsfpu.h"
|
|
|
|
|
#endif /* defined __mips__ && !defined MIPS_NABI */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-05-01 21:42:42 +08:00
|
|
|
|
|
|
|
|
|
/* Define replacements for required string functions. */
|
|
|
|
|
|
2023-05-02 08:16:00 +08:00
|
|
|
|
#if !defined HAVE_STPCPY || !defined HAVE_DECL_STPCPY
|
2023-05-01 21:42:42 +08:00
|
|
|
|
|
|
|
|
|
/* Copy SRC to DEST, returning the address of the terminating '\0' in
|
|
|
|
|
DEST. */
|
|
|
|
|
|
|
|
|
|
static char *
|
|
|
|
|
rpl_stpcpy (char *dest, const char *src)
|
|
|
|
|
{
|
|
|
|
|
register char *d;
|
|
|
|
|
register const char *s;
|
|
|
|
|
|
|
|
|
|
d = dest;
|
|
|
|
|
s = src;
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
*d++ = *s;
|
|
|
|
|
while (*s++ != '\0');
|
|
|
|
|
|
|
|
|
|
return d - 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define stpcpy rpl_stpcpy
|
2023-05-02 08:16:00 +08:00
|
|
|
|
#endif /* !defined HAVE_STPCPY || !defined HAVE_DECL_STPCPY */
|
2023-05-01 21:42:42 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
/* Executable reading functions.
|
|
|
|
|
These functions extract information from an executable that is
|
|
|
|
|
about to be loaded.
|
|
|
|
|
|
|
|
|
|
`exec_0' takes the name of the program, determines whether or not
|
|
|
|
|
its format is correct, and if so, returns the list of actions that
|
|
|
|
|
the loader should perform.
|
|
|
|
|
|
|
|
|
|
The actions include:
|
|
|
|
|
|
|
|
|
|
- Making the stack executable, if PT_GNU_STACK.
|
|
|
|
|
- Mapping PT_LOAD sections into the executable with the correct
|
|
|
|
|
memory protection.
|
|
|
|
|
- On MIPS, setting the floating point register size.
|
|
|
|
|
- Transferring control to the interpreter or executable. */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Check whether or not FD starts with a #!, and return the executable
|
|
|
|
|
to load if it does. Value is NAME if no interpreter character was
|
|
|
|
|
found, or the interpreter otherwise. Value is NULL upon an IO
|
|
|
|
|
error.
|
|
|
|
|
|
|
|
|
|
If an additional command line argument is specified, place it in
|
|
|
|
|
*EXTRA. */
|
|
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
|
check_interpreter (const char *name, int fd, const char **extra)
|
|
|
|
|
{
|
|
|
|
|
static char buffer[PATH_MAX], *start;
|
|
|
|
|
char first[2], *end, *ws;
|
|
|
|
|
ssize_t rc;
|
|
|
|
|
|
|
|
|
|
/* Read the first character. */
|
|
|
|
|
rc = read (fd, &first, 2);
|
|
|
|
|
|
|
|
|
|
if (rc != 2)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
if (first[0] != '#' || first[1] != '!')
|
|
|
|
|
goto nomatch;
|
|
|
|
|
|
|
|
|
|
rc = read (fd, buffer, PATH_MAX);
|
|
|
|
|
|
|
|
|
|
if (rc < 0)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
/* Strip leading whitespace. */
|
|
|
|
|
start = buffer;
|
2024-09-17 16:38:53 -07:00
|
|
|
|
while (start < buffer + rc && (*start == ' ' || *start == '\t'))
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
++start;
|
|
|
|
|
|
|
|
|
|
/* Look for a newline character. */
|
2024-09-17 16:38:53 -07:00
|
|
|
|
end = memchr (start, '\n', buffer + rc - start);
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
|
|
|
|
if (!end)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
/* The string containing the interpreter is now in start. NULL
|
|
|
|
|
terminate it. */
|
|
|
|
|
*end = '\0';
|
|
|
|
|
|
|
|
|
|
/* Now look for any whitespace characters. */
|
2024-09-17 16:38:53 -07:00
|
|
|
|
for (ws = start; *ws && *ws != ' ' && *ws != '\t'; ws++)
|
|
|
|
|
continue;
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
|
|
|
|
/* If there's no whitespace, return the entire start. */
|
|
|
|
|
|
2024-09-17 16:38:53 -07:00
|
|
|
|
if (!*ws)
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
{
|
|
|
|
|
if (lseek (fd, 0, SEEK_SET))
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
return start;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Otherwise, split the string at the whitespace and return the
|
|
|
|
|
additional argument. */
|
|
|
|
|
*ws = '\0';
|
|
|
|
|
|
|
|
|
|
if (lseek (fd, 0, SEEK_SET))
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
*extra = ws + 1;
|
|
|
|
|
return start;
|
|
|
|
|
|
|
|
|
|
nomatch:
|
|
|
|
|
/* There's no interpreter. */
|
|
|
|
|
if (lseek (fd, 0, SEEK_SET))
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
return name;
|
|
|
|
|
|
|
|
|
|
fail:
|
|
|
|
|
errno = ENOEXEC;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Static area used to store data placed on the loader's stack. */
|
|
|
|
|
static char loader_area[65536];
|
|
|
|
|
|
|
|
|
|
/* Number of bytes used in that area. */
|
|
|
|
|
static int loader_area_used;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Structure definitions for commands placed in the loader area.
|
|
|
|
|
Arrange these so that each member is naturally aligned. */
|
|
|
|
|
|
|
|
|
|
struct exec_open_command
|
|
|
|
|
{
|
|
|
|
|
/* Word identifying the type of this command. */
|
|
|
|
|
USER_WORD command;
|
|
|
|
|
|
|
|
|
|
/* NULL-terminated file name follows, padded to the size of a user
|
|
|
|
|
word. */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct exec_map_command
|
|
|
|
|
{
|
|
|
|
|
/* Word identifying the type of this command. */
|
|
|
|
|
USER_WORD command;
|
|
|
|
|
|
|
|
|
|
/* Where the file will be mapped. */
|
|
|
|
|
USER_WORD vm_address;
|
|
|
|
|
|
|
|
|
|
/* Offset into the file to map from. */
|
|
|
|
|
USER_WORD file_offset;
|
|
|
|
|
|
|
|
|
|
/* Memory protection for mprotect. */
|
|
|
|
|
USER_WORD protection;
|
|
|
|
|
|
|
|
|
|
/* Number of bytes to be mapped. */
|
|
|
|
|
USER_WORD length;
|
|
|
|
|
|
|
|
|
|
/* Flags for mmap. */
|
|
|
|
|
USER_WORD flags;
|
|
|
|
|
|
|
|
|
|
/* Number of bytes to clear at the end of this mapping. */
|
|
|
|
|
USER_WORD clear;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct exec_jump_command
|
|
|
|
|
{
|
|
|
|
|
/* Word identifying the type of this command. */
|
|
|
|
|
USER_WORD command;
|
|
|
|
|
|
|
|
|
|
/* Address to jump to. */
|
|
|
|
|
USER_WORD entry;
|
|
|
|
|
|
|
|
|
|
/* The value of AT_ENTRY inside the aux vector. */
|
|
|
|
|
USER_WORD at_entry;
|
|
|
|
|
|
|
|
|
|
/* The value of AT_PHENT inside the aux vector. */
|
|
|
|
|
USER_WORD at_phent;
|
|
|
|
|
|
|
|
|
|
/* The value of AT_PHNUM inside the aux vector. */
|
|
|
|
|
USER_WORD at_phnum;
|
|
|
|
|
|
|
|
|
|
/* The value of AT_PHDR inside the aux vector. */
|
|
|
|
|
USER_WORD at_phdr;
|
|
|
|
|
|
|
|
|
|
/* The value of AT_BASE inside the aux vector. */
|
|
|
|
|
USER_WORD at_base;
|
|
|
|
|
|
|
|
|
|
#if defined __mips__ && !defined MIPS_NABI
|
|
|
|
|
/* The FPU mode to apply. */
|
|
|
|
|
USER_WORD fpu_mode;
|
|
|
|
|
#endif /* defined __mips__ && !defined MIPS_NABI */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Write a command to open the file NAME to the loader area.
|
|
|
|
|
If ALTERNATE is true, then use the command code 16 instead
|
|
|
|
|
of 0. Value is 1 upon failure, else 0. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
write_open_command (const char *name, bool alternate)
|
|
|
|
|
{
|
|
|
|
|
struct exec_open_command command;
|
|
|
|
|
size_t size;
|
|
|
|
|
|
|
|
|
|
/* First, write the command to open NAME. This is followed by NAME
|
|
|
|
|
itself, padded to sizeof (USER_WORD) bytes. */
|
|
|
|
|
|
|
|
|
|
command.command = alternate ? 16 : 0;
|
|
|
|
|
if (sizeof loader_area - loader_area_used < sizeof command)
|
|
|
|
|
return 1;
|
|
|
|
|
memcpy (loader_area + loader_area_used, &command, sizeof command);
|
|
|
|
|
loader_area_used += sizeof command;
|
|
|
|
|
|
|
|
|
|
/* Calculate the length of NAME. */
|
|
|
|
|
size = strlen (name) + 1;
|
|
|
|
|
|
|
|
|
|
/* Round it up. */
|
|
|
|
|
size = ((size + (sizeof (USER_WORD) - 1))
|
|
|
|
|
& ~(sizeof (USER_WORD) - 1));
|
|
|
|
|
|
|
|
|
|
if (sizeof loader_area - loader_area_used < size)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
/* Now copy name to the loader area, filling the padding with NULL
|
|
|
|
|
bytes. */
|
|
|
|
|
strncpy (loader_area + loader_area_used, name, size);
|
|
|
|
|
|
|
|
|
|
/* Increase loader_area_used. */
|
|
|
|
|
loader_area_used += size;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Write the commands necessary to map the executable file into memory
|
|
|
|
|
for the given PT_LOAD program HEADER. Value is 1 upon failure,
|
|
|
|
|
else 0. If USE_ALTERNATE, use the command code 17 instead of
|
|
|
|
|
1.
|
|
|
|
|
|
|
|
|
|
Apply the given OFFSET to virtual addresses that will be mapped. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
write_load_command (program_header *header, bool use_alternate,
|
|
|
|
|
USER_WORD offset)
|
|
|
|
|
{
|
|
|
|
|
struct exec_map_command command;
|
|
|
|
|
struct exec_map_command command1;
|
|
|
|
|
USER_WORD start, end;
|
|
|
|
|
bool need_command1;
|
Optimize process execution on Android
* exec/configure.ac (REENTRANT): Remove option for reentrancy.
(PROGRAM_COUNTER, HAVE_SECCOMP): Define register providing the
program counter and enable seccomp if its headers are available.
* exec/exec.c (write_load_command): Avoid defining unused
variable.
(exec_0): Remove code specific to REENTRANT configurations.
* exec/exec.h (struct exec_tracee) <exec_data, data_size>: New
fields for loader instructions and their size.
* exec/exec1.c (main): Call exec_init before forking.
* exec/mipsel-user.h (ELF_NGREG): Delete definition.
(struct mipsel_regs): Reduce number of gregs to 32, but
introduce separate fields for special registers.
* exec/trace.c (use_seccomp_p): New variable; defile to false if
!HAVE_SECCOMP.
(remove_tracee): Cease providing for non-reentrant
configurations. Release executable data if present.
(handle_clone_prepare): Likewise. Resume process with
PTRACE_CONT if seccomp-based interception is enabled.
(handle_clone, check_signal): Resume processes as above.
(handle_exec): Divide into two functions, with only rewriting
the system call and generating instructions for the loader
remaining in the first, and copying such instructions into the
loader's stack removed into a new function, `finish_exec'.
(finish_exec): New function.
(handle_readlinkat, handle_openat): Abolish non-REENTRANT
configurations.
(process_system_call): Divide exec system calls into two phases,
disambiguated by the value of tracee->waiting_for_syscall. Typo
fixes. Accommodate syscall-exit-stops where the signal was
initially intercepted by `seccomp_system_call'.
(interesting_syscalls): New array.
(ARRAYELTS): New macro.
(seccomp_system_call, establish_seccomp_filter): New function.
(tracing_execve) [HAVE_SECCOMP]: Establish a seccomp filter if
this is to be enabled.
(after_fork): Provide PTRACE_O_TRACESECCOMP. Resume process
with PTRACE_CONT if seccomp-based interception is enabled.
(exec_waitpid): Resume process with PTRACE_CONT if seccomp-based
interception is enabled. Dispatch stops identifying as
PTRACE_EVENT_SECCOMP to `seccomp_system_call'.
(exec_init): Establish whether it is possible to enable seccomp.
2024-07-01 18:11:58 +08:00
|
|
|
|
#ifndef PAGE_MASK
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
static long pagesize;
|
Optimize process execution on Android
* exec/configure.ac (REENTRANT): Remove option for reentrancy.
(PROGRAM_COUNTER, HAVE_SECCOMP): Define register providing the
program counter and enable seccomp if its headers are available.
* exec/exec.c (write_load_command): Avoid defining unused
variable.
(exec_0): Remove code specific to REENTRANT configurations.
* exec/exec.h (struct exec_tracee) <exec_data, data_size>: New
fields for loader instructions and their size.
* exec/exec1.c (main): Call exec_init before forking.
* exec/mipsel-user.h (ELF_NGREG): Delete definition.
(struct mipsel_regs): Reduce number of gregs to 32, but
introduce separate fields for special registers.
* exec/trace.c (use_seccomp_p): New variable; defile to false if
!HAVE_SECCOMP.
(remove_tracee): Cease providing for non-reentrant
configurations. Release executable data if present.
(handle_clone_prepare): Likewise. Resume process with
PTRACE_CONT if seccomp-based interception is enabled.
(handle_clone, check_signal): Resume processes as above.
(handle_exec): Divide into two functions, with only rewriting
the system call and generating instructions for the loader
remaining in the first, and copying such instructions into the
loader's stack removed into a new function, `finish_exec'.
(finish_exec): New function.
(handle_readlinkat, handle_openat): Abolish non-REENTRANT
configurations.
(process_system_call): Divide exec system calls into two phases,
disambiguated by the value of tracee->waiting_for_syscall. Typo
fixes. Accommodate syscall-exit-stops where the signal was
initially intercepted by `seccomp_system_call'.
(interesting_syscalls): New array.
(ARRAYELTS): New macro.
(seccomp_system_call, establish_seccomp_filter): New function.
(tracing_execve) [HAVE_SECCOMP]: Establish a seccomp filter if
this is to be enabled.
(after_fork): Provide PTRACE_O_TRACESECCOMP. Resume process
with PTRACE_CONT if seccomp-based interception is enabled.
(exec_waitpid): Resume process with PTRACE_CONT if seccomp-based
interception is enabled. Dispatch stops identifying as
PTRACE_EVENT_SECCOMP to `seccomp_system_call'.
(exec_init): Establish whether it is possible to enable seccomp.
2024-07-01 18:11:58 +08:00
|
|
|
|
#endif /* !PAGE_MASK */
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
|
|
|
|
/* First, write the commands necessary to map the specified segment
|
|
|
|
|
itself.
|
|
|
|
|
|
|
|
|
|
This is the area between header->p_vaddr and header->p_filesz,
|
|
|
|
|
rounded up to the page size. */
|
|
|
|
|
|
|
|
|
|
#ifndef PAGE_MASK
|
|
|
|
|
/* This system doesn't define a fixed page size. */
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_GETPAGESIZE
|
|
|
|
|
if (!pagesize)
|
|
|
|
|
pagesize = getpagesize ();
|
Optimize process execution on Android
* exec/configure.ac (REENTRANT): Remove option for reentrancy.
(PROGRAM_COUNTER, HAVE_SECCOMP): Define register providing the
program counter and enable seccomp if its headers are available.
* exec/exec.c (write_load_command): Avoid defining unused
variable.
(exec_0): Remove code specific to REENTRANT configurations.
* exec/exec.h (struct exec_tracee) <exec_data, data_size>: New
fields for loader instructions and their size.
* exec/exec1.c (main): Call exec_init before forking.
* exec/mipsel-user.h (ELF_NGREG): Delete definition.
(struct mipsel_regs): Reduce number of gregs to 32, but
introduce separate fields for special registers.
* exec/trace.c (use_seccomp_p): New variable; defile to false if
!HAVE_SECCOMP.
(remove_tracee): Cease providing for non-reentrant
configurations. Release executable data if present.
(handle_clone_prepare): Likewise. Resume process with
PTRACE_CONT if seccomp-based interception is enabled.
(handle_clone, check_signal): Resume processes as above.
(handle_exec): Divide into two functions, with only rewriting
the system call and generating instructions for the loader
remaining in the first, and copying such instructions into the
loader's stack removed into a new function, `finish_exec'.
(finish_exec): New function.
(handle_readlinkat, handle_openat): Abolish non-REENTRANT
configurations.
(process_system_call): Divide exec system calls into two phases,
disambiguated by the value of tracee->waiting_for_syscall. Typo
fixes. Accommodate syscall-exit-stops where the signal was
initially intercepted by `seccomp_system_call'.
(interesting_syscalls): New array.
(ARRAYELTS): New macro.
(seccomp_system_call, establish_seccomp_filter): New function.
(tracing_execve) [HAVE_SECCOMP]: Establish a seccomp filter if
this is to be enabled.
(after_fork): Provide PTRACE_O_TRACESECCOMP. Resume process
with PTRACE_CONT if seccomp-based interception is enabled.
(exec_waitpid): Resume process with PTRACE_CONT if seccomp-based
interception is enabled. Dispatch stops identifying as
PTRACE_EVENT_SECCOMP to `seccomp_system_call'.
(exec_init): Establish whether it is possible to enable seccomp.
2024-07-01 18:11:58 +08:00
|
|
|
|
#else /* !HAVE_GETPAGESIZE */
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
if (!pagesize)
|
|
|
|
|
pagesize = sysconf (_SC_PAGESIZE);
|
Optimize process execution on Android
* exec/configure.ac (REENTRANT): Remove option for reentrancy.
(PROGRAM_COUNTER, HAVE_SECCOMP): Define register providing the
program counter and enable seccomp if its headers are available.
* exec/exec.c (write_load_command): Avoid defining unused
variable.
(exec_0): Remove code specific to REENTRANT configurations.
* exec/exec.h (struct exec_tracee) <exec_data, data_size>: New
fields for loader instructions and their size.
* exec/exec1.c (main): Call exec_init before forking.
* exec/mipsel-user.h (ELF_NGREG): Delete definition.
(struct mipsel_regs): Reduce number of gregs to 32, but
introduce separate fields for special registers.
* exec/trace.c (use_seccomp_p): New variable; defile to false if
!HAVE_SECCOMP.
(remove_tracee): Cease providing for non-reentrant
configurations. Release executable data if present.
(handle_clone_prepare): Likewise. Resume process with
PTRACE_CONT if seccomp-based interception is enabled.
(handle_clone, check_signal): Resume processes as above.
(handle_exec): Divide into two functions, with only rewriting
the system call and generating instructions for the loader
remaining in the first, and copying such instructions into the
loader's stack removed into a new function, `finish_exec'.
(finish_exec): New function.
(handle_readlinkat, handle_openat): Abolish non-REENTRANT
configurations.
(process_system_call): Divide exec system calls into two phases,
disambiguated by the value of tracee->waiting_for_syscall. Typo
fixes. Accommodate syscall-exit-stops where the signal was
initially intercepted by `seccomp_system_call'.
(interesting_syscalls): New array.
(ARRAYELTS): New macro.
(seccomp_system_call, establish_seccomp_filter): New function.
(tracing_execve) [HAVE_SECCOMP]: Establish a seccomp filter if
this is to be enabled.
(after_fork): Provide PTRACE_O_TRACESECCOMP. Resume process
with PTRACE_CONT if seccomp-based interception is enabled.
(exec_waitpid): Resume process with PTRACE_CONT if seccomp-based
interception is enabled. Dispatch stops identifying as
PTRACE_EVENT_SECCOMP to `seccomp_system_call'.
(exec_init): Establish whether it is possible to enable seccomp.
2024-07-01 18:11:58 +08:00
|
|
|
|
#endif /* !HAVE_GETPAGESIZE */
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
|
|
|
|
#define PAGE_MASK (~(pagesize - 1))
|
|
|
|
|
#define PAGE_SIZE (pagesize)
|
Optimize process execution on Android
* exec/configure.ac (REENTRANT): Remove option for reentrancy.
(PROGRAM_COUNTER, HAVE_SECCOMP): Define register providing the
program counter and enable seccomp if its headers are available.
* exec/exec.c (write_load_command): Avoid defining unused
variable.
(exec_0): Remove code specific to REENTRANT configurations.
* exec/exec.h (struct exec_tracee) <exec_data, data_size>: New
fields for loader instructions and their size.
* exec/exec1.c (main): Call exec_init before forking.
* exec/mipsel-user.h (ELF_NGREG): Delete definition.
(struct mipsel_regs): Reduce number of gregs to 32, but
introduce separate fields for special registers.
* exec/trace.c (use_seccomp_p): New variable; defile to false if
!HAVE_SECCOMP.
(remove_tracee): Cease providing for non-reentrant
configurations. Release executable data if present.
(handle_clone_prepare): Likewise. Resume process with
PTRACE_CONT if seccomp-based interception is enabled.
(handle_clone, check_signal): Resume processes as above.
(handle_exec): Divide into two functions, with only rewriting
the system call and generating instructions for the loader
remaining in the first, and copying such instructions into the
loader's stack removed into a new function, `finish_exec'.
(finish_exec): New function.
(handle_readlinkat, handle_openat): Abolish non-REENTRANT
configurations.
(process_system_call): Divide exec system calls into two phases,
disambiguated by the value of tracee->waiting_for_syscall. Typo
fixes. Accommodate syscall-exit-stops where the signal was
initially intercepted by `seccomp_system_call'.
(interesting_syscalls): New array.
(ARRAYELTS): New macro.
(seccomp_system_call, establish_seccomp_filter): New function.
(tracing_execve) [HAVE_SECCOMP]: Establish a seccomp filter if
this is to be enabled.
(after_fork): Provide PTRACE_O_TRACESECCOMP. Resume process
with PTRACE_CONT if seccomp-based interception is enabled.
(exec_waitpid): Resume process with PTRACE_CONT if seccomp-based
interception is enabled. Dispatch stops identifying as
PTRACE_EVENT_SECCOMP to `seccomp_system_call'.
(exec_init): Establish whether it is possible to enable seccomp.
2024-07-01 18:11:58 +08:00
|
|
|
|
#endif /* !PAGE_MASK */
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
|
|
|
|
start = header->p_vaddr & PAGE_MASK;
|
|
|
|
|
end = ((header->p_vaddr + header->p_filesz
|
|
|
|
|
+ PAGE_SIZE)
|
|
|
|
|
& PAGE_MASK);
|
|
|
|
|
|
|
|
|
|
command.command = use_alternate ? 17 : 1;
|
|
|
|
|
command.vm_address = start;
|
|
|
|
|
command.file_offset = header->p_offset & PAGE_MASK;
|
|
|
|
|
command.protection = 0;
|
|
|
|
|
command.length = end - start;
|
|
|
|
|
command.clear = 0;
|
|
|
|
|
command.flags = MAP_PRIVATE | MAP_FIXED;
|
|
|
|
|
|
|
|
|
|
/* Apply the memory protection specified in the header. */
|
|
|
|
|
|
|
|
|
|
if (header->p_flags & 4) /* PF_R */
|
|
|
|
|
command.protection |= PROT_READ;
|
|
|
|
|
|
|
|
|
|
if (header->p_flags & 2) /* PF_W */
|
|
|
|
|
command.protection |= PROT_WRITE;
|
|
|
|
|
|
|
|
|
|
if (header->p_flags & 1) /* PF_X */
|
|
|
|
|
command.protection |= PROT_EXEC;
|
|
|
|
|
|
|
|
|
|
/* Next, write any command necessary to map pages in the area
|
|
|
|
|
between p_filesz and p_memsz. */
|
|
|
|
|
need_command1 = false;
|
|
|
|
|
|
|
|
|
|
if (header->p_memsz > header->p_filesz)
|
|
|
|
|
{
|
|
|
|
|
/* If there are bytes after end which need to be initialized, do
|
|
|
|
|
that now. */
|
|
|
|
|
command.clear = end - header->p_vaddr - header->p_filesz;
|
|
|
|
|
start = end;
|
|
|
|
|
end = header->p_vaddr + header->p_memsz + PAGE_SIZE;
|
|
|
|
|
end &= PAGE_MASK;
|
|
|
|
|
|
|
|
|
|
if (end > start)
|
|
|
|
|
{
|
|
|
|
|
command1.command = 4;
|
|
|
|
|
command1.vm_address = start;
|
|
|
|
|
command1.file_offset = 0;
|
|
|
|
|
command1.length = end - start;
|
|
|
|
|
command1.clear = 0;
|
|
|
|
|
command1.protection = command.protection;
|
|
|
|
|
command1.flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED;
|
|
|
|
|
need_command1 = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Apply the offset to both commands if necessary. */
|
|
|
|
|
|
|
|
|
|
if (offset)
|
|
|
|
|
{
|
|
|
|
|
if (need_command1)
|
|
|
|
|
command1.vm_address += offset;
|
|
|
|
|
|
|
|
|
|
command.vm_address += offset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Write both commands. */
|
|
|
|
|
|
|
|
|
|
if (sizeof loader_area - loader_area_used < sizeof command)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
memcpy (loader_area + loader_area_used, &command,
|
|
|
|
|
sizeof command);
|
|
|
|
|
loader_area_used += sizeof command;
|
|
|
|
|
|
|
|
|
|
if (!need_command1)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (sizeof loader_area - loader_area_used < sizeof command1)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
memcpy (loader_area + loader_area_used, &command1,
|
|
|
|
|
sizeof command1);
|
|
|
|
|
loader_area_used += sizeof command1;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if defined __mips__ && !defined MIPS_NABI
|
|
|
|
|
|
|
|
|
|
/* Static storage used for MIPS ABI flags. */
|
|
|
|
|
static struct mips_elf_abi_flags exec_abi, interpreter_abi;
|
|
|
|
|
|
|
|
|
|
/* Static storage for interpreter headers. */
|
|
|
|
|
static elf_header exec_interpreter_header;
|
|
|
|
|
|
|
|
|
|
/* Pointer to the ELF header of this executable's interpreter. */
|
|
|
|
|
static elf_header *interpreter_header;
|
|
|
|
|
|
|
|
|
|
/* Pointer to any PT_MIPS_ABIFLAGS program header found in the
|
|
|
|
|
executable itself. */
|
|
|
|
|
static struct mips_elf_abi_flags *exec_abiflags;
|
|
|
|
|
|
|
|
|
|
/* Pointer to any PT_MIPS_ABIFLAGS program header found in the
|
|
|
|
|
executable's ELF interpreter. */
|
|
|
|
|
static struct mips_elf_abi_flags *interpreter_abiflags;
|
|
|
|
|
|
|
|
|
|
#endif /* defined __mips__ && !defined MIPS_NABI */
|
|
|
|
|
|
|
|
|
|
/* Process the specified program HEADER; HEADER is from the ELF
|
|
|
|
|
interpreter of another executable. FD is the executable file from
|
|
|
|
|
which it is being read, NAME is its file name, and ELF_HEADER is
|
|
|
|
|
its header.
|
|
|
|
|
|
|
|
|
|
If ELF_HEADER->e_type is ET_DYN, add the base address for position
|
|
|
|
|
independent interpreter code to virtual addresses.
|
|
|
|
|
|
|
|
|
|
Value is 1 upon failure, else 0. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
process_interpreter_1 (const char *name, int fd,
|
|
|
|
|
program_header *header,
|
|
|
|
|
elf_header *elf_header)
|
|
|
|
|
{
|
|
|
|
|
int rc;
|
|
|
|
|
#if defined __mips__ && !defined MIPS_NABI
|
|
|
|
|
ssize_t rc1;
|
|
|
|
|
#endif /* defined __mips__ && !defined MIPS_NABI */
|
|
|
|
|
|
|
|
|
|
switch (header->p_type)
|
|
|
|
|
{
|
|
|
|
|
default: /* PT_NULL, PT_NOTE, PT_DYNAMIC, PT_INTERP, et cetera */
|
|
|
|
|
rc = 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 1: /* PT_LOAD */
|
|
|
|
|
/* This describes a segment in the file that must be loaded.
|
|
|
|
|
Write the appropriate load command. */
|
|
|
|
|
|
|
|
|
|
if (elf_header->e_type == 3) /* ET_DYN */
|
|
|
|
|
rc = write_load_command (header, true,
|
|
|
|
|
INTERPRETER_BASE);
|
|
|
|
|
else
|
|
|
|
|
rc = write_load_command (header, true, 0);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
#if defined __mips__ && !defined MIPS_NABI
|
|
|
|
|
case 0x70000003: /* PT_MIPS_ABIFLAGS */
|
|
|
|
|
/* Record this header for later use. */
|
|
|
|
|
rc1 = pread (fd, &interpreter_abi, sizeof interpreter_abi,
|
|
|
|
|
header->p_offset);
|
|
|
|
|
|
|
|
|
|
if (rc1 != sizeof interpreter_abi)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
interpreter_abiflags = &interpreter_abi;
|
|
|
|
|
rc = 0;
|
|
|
|
|
#endif /* defined __mips__ && !defined MIPS_NABI */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Read the ELF interpreter specified in the given program header from
|
|
|
|
|
FD, and append the commands necessary to load it to the load area.
|
|
|
|
|
Then, return the interpreter entry point in *ENTRY.
|
|
|
|
|
|
|
|
|
|
Value is 1 upon failure, else 0. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
process_interpreter (int fd, program_header *prog_header,
|
|
|
|
|
USER_WORD *entry)
|
|
|
|
|
{
|
|
|
|
|
char buffer[PATH_MAX + 1];
|
|
|
|
|
int rc, size, i;
|
|
|
|
|
elf_header header;
|
|
|
|
|
program_header program;
|
|
|
|
|
|
|
|
|
|
/* Read the interpreter name. */
|
|
|
|
|
size = MIN (prog_header->p_filesz, PATH_MAX);
|
|
|
|
|
rc = pread (fd, buffer, size, prog_header->p_offset);
|
|
|
|
|
if (rc < size)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
/* Make sure the name is NULL terminated. */
|
|
|
|
|
buffer[size] = '\0';
|
|
|
|
|
|
|
|
|
|
/* Check if the file is executable. This is unfortunately not
|
|
|
|
|
atomic. */
|
|
|
|
|
|
|
|
|
|
if (access (buffer, X_OK))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
/* Read the interpreter's header much like exec_0.
|
|
|
|
|
|
|
|
|
|
However, use special command codes in `process_program_header' if
|
|
|
|
|
it is position independent. That way, the loader knows it should
|
|
|
|
|
use the open interpreter instead. */
|
|
|
|
|
|
|
|
|
|
fd = open (buffer, O_RDONLY);
|
|
|
|
|
|
|
|
|
|
if (fd < 0)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
rc = read (fd, &header, sizeof header);
|
|
|
|
|
|
|
|
|
|
if (rc < sizeof header)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
#if defined __mips__ && !defined MIPS_NABI
|
|
|
|
|
/* Record this interpreter's header for later use determining the
|
|
|
|
|
floating point ABI. */
|
|
|
|
|
exec_interpreter_header = header;
|
|
|
|
|
interpreter_header = &exec_interpreter_header;
|
|
|
|
|
#endif /* defined __mips__ && !defined MIPS_NABI */
|
|
|
|
|
|
|
|
|
|
/* Verify that this is indeed an ELF file. */
|
|
|
|
|
|
|
|
|
|
if (header.e_ident[0] != 0x7f
|
|
|
|
|
|| header.e_ident[1] != 'E'
|
|
|
|
|
|| header.e_ident[2] != 'L'
|
|
|
|
|
|| header.e_ident[3] != 'F')
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
/* Now check that the class is correct. */
|
|
|
|
|
#ifdef EXEC_64
|
|
|
|
|
if (header.e_ident[4] != 2)
|
|
|
|
|
goto fail;
|
|
|
|
|
#else /* !EXEC_64 */
|
|
|
|
|
if (header.e_ident[4] != 1)
|
|
|
|
|
goto fail;
|
|
|
|
|
#endif /* EXEC_64 */
|
|
|
|
|
|
|
|
|
|
/* And the endianness. */
|
|
|
|
|
#ifndef WORDS_BIGENDIAN
|
|
|
|
|
if (header.e_ident[5] != 1)
|
|
|
|
|
goto fail;
|
|
|
|
|
#else /* WORDS_BIGENDIAN */
|
|
|
|
|
if (header.e_ident[5] != 2)
|
|
|
|
|
goto fail;
|
|
|
|
|
#endif /* EXEC_64 */
|
|
|
|
|
|
|
|
|
|
/* Check that this is an executable. */
|
|
|
|
|
if (header.e_type != 2 && header.e_type != 3)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
/* Now check that the ELF program header makes sense. */
|
|
|
|
|
if (header.e_phnum > 0xffff
|
|
|
|
|
|| (header.e_phentsize
|
|
|
|
|
!= sizeof (program_header)))
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
if (write_open_command (buffer, true))
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < header.e_phnum; ++i)
|
|
|
|
|
{
|
|
|
|
|
rc = read (fd, &program, sizeof program);
|
|
|
|
|
if (rc < sizeof program)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
if (process_interpreter_1 (buffer, fd, &program,
|
|
|
|
|
&header))
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (header.e_type == 3) /* ET_DYN */
|
|
|
|
|
*entry = header.e_entry + INTERPRETER_BASE;
|
|
|
|
|
else
|
|
|
|
|
*entry = header.e_entry;
|
|
|
|
|
|
|
|
|
|
close (fd);
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
fail:
|
|
|
|
|
close (fd);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Process the specified program HEADER. FD is the executable file
|
|
|
|
|
from which it is being read, NAME is its file name, and ELF_HEADER
|
|
|
|
|
is its header.
|
|
|
|
|
|
|
|
|
|
If ELF_HEADER->e_type is ET_DYN, add the base address for position
|
|
|
|
|
independent code to virtual addresses.
|
|
|
|
|
|
|
|
|
|
If OFFSET is non-NULL, and *OFFSET is -1, write the virtual address
|
|
|
|
|
of HEADER if it describes a PT_LOAD segment.
|
|
|
|
|
|
|
|
|
|
If an interpreter is found, set *ENTRY to its entry point.
|
|
|
|
|
|
|
|
|
|
Value is 1 upon failure, else 0. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
process_program_header (const char *name, int fd,
|
|
|
|
|
program_header *header,
|
|
|
|
|
elf_header *elf_header,
|
|
|
|
|
USER_WORD *entry,
|
|
|
|
|
USER_WORD *offset)
|
|
|
|
|
{
|
|
|
|
|
int rc;
|
|
|
|
|
#if defined __mips__ && !defined MIPS_NABI
|
|
|
|
|
ssize_t rc1;
|
|
|
|
|
#endif /* defined __mips__ && !defined MIPS_NABI */
|
|
|
|
|
|
|
|
|
|
switch (header->p_type)
|
|
|
|
|
{
|
|
|
|
|
default: /* PT_NULL, PT_NOTE, PT_DYNAMIC, et cetera */
|
|
|
|
|
rc = 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 1: /* PT_LOAD */
|
|
|
|
|
/* This describes a segment in the file that must be loaded.
|
|
|
|
|
Write the appropriate load command. */
|
|
|
|
|
|
|
|
|
|
if (elf_header->e_type == 3) /* ET_DYN */
|
|
|
|
|
{
|
|
|
|
|
rc = write_load_command (header, false,
|
|
|
|
|
EXECUTABLE_BASE);
|
|
|
|
|
|
|
|
|
|
if (!rc && offset && *offset == (USER_WORD) -1)
|
|
|
|
|
*offset = EXECUTABLE_BASE + header->p_vaddr;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
rc = write_load_command (header, false, 0);
|
|
|
|
|
|
|
|
|
|
if (!rc && offset && *offset == (USER_WORD) -1)
|
|
|
|
|
*offset = header->p_vaddr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 3: /* PT_INTERP */
|
2023-05-01 21:42:42 +08:00
|
|
|
|
/* This describes another executable that must be loaded. Open
|
|
|
|
|
the interpreter and process each of its headers as well. */
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
rc = process_interpreter (fd, header, entry);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 1685382481: /* PT_GNU_STACK */
|
|
|
|
|
/* TODO */
|
|
|
|
|
rc = 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
#if defined __mips__ && !defined MIPS_NABI
|
|
|
|
|
case 0x70000003: /* PT_MIPS_ABIFLAGS */
|
|
|
|
|
/* Record this header for later use. */
|
|
|
|
|
rc1 = pread (fd, &exec_abi, sizeof exec_abi,
|
|
|
|
|
header->p_offset);
|
|
|
|
|
|
|
|
|
|
if (rc1 != sizeof exec_abi)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
exec_abiflags = &exec_abi;
|
|
|
|
|
rc = 0;
|
|
|
|
|
#endif /* defined __mips__ && !defined MIPS_NABI */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Prepend one or two extra arguments ARG1 and ARG2 to a pending
|
2023-05-31 11:27:19 +08:00
|
|
|
|
execve system call. Replace the argument immediately after
|
|
|
|
|
with ARG3.
|
|
|
|
|
|
|
|
|
|
TRACEE is the tracee performing the system call, and REGS are its
|
|
|
|
|
current user registers. Value is 1 upon failure, else 0. */
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
insert_args (struct exec_tracee *tracee, USER_REGS_STRUCT *regs,
|
2023-05-31 11:27:19 +08:00
|
|
|
|
const char *arg1, const char *arg2, const char *arg3)
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
{
|
|
|
|
|
USER_WORD argv, argc, word, new;
|
2023-05-31 11:27:19 +08:00
|
|
|
|
USER_WORD new1, new2, new3, i;
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
size_t text_size, effective_size;
|
|
|
|
|
USER_REGS_STRUCT original;
|
|
|
|
|
|
|
|
|
|
/* First, get a pointer to the current argument vector. */
|
|
|
|
|
argv = regs->SYSCALL_ARG1_REG;
|
|
|
|
|
|
|
|
|
|
/* Now figure out how many arguments there are. */
|
|
|
|
|
argc = 0;
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
/* Clear errno. PTRACE_PEEKDATA returns the word read the same
|
|
|
|
|
way failure indications are returned, so the only way to
|
|
|
|
|
catch IO errors is by clearing errno before the call to
|
|
|
|
|
ptrace and checking it afterwards. */
|
|
|
|
|
|
|
|
|
|
errno = 0;
|
|
|
|
|
word = ptrace (PTRACE_PEEKDATA, tracee->pid,
|
|
|
|
|
(void *) argv, NULL);
|
|
|
|
|
argv += sizeof (USER_WORD);
|
|
|
|
|
|
|
|
|
|
if (errno)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
if (!word)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
++argc;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Allocate enough to hold that many arguments, alongside the argc
|
|
|
|
|
text. */
|
|
|
|
|
|
|
|
|
|
text_size = (strlen (arg1) + 1
|
2023-05-31 11:27:19 +08:00
|
|
|
|
+ (arg2 ? strlen (arg2) + 1 : 0)
|
|
|
|
|
+ strlen (arg3) + 1);
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
|
|
|
|
/* Round it up to the user word size. */
|
|
|
|
|
text_size += sizeof (USER_WORD) - 1;
|
|
|
|
|
text_size &= ~(sizeof (USER_WORD) - 1);
|
|
|
|
|
|
2023-05-31 11:27:19 +08:00
|
|
|
|
/* Now allocate the new argv. Make sure argc is at least 1; it
|
|
|
|
|
needs to hold ARG3. */
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
2023-05-31 11:27:19 +08:00
|
|
|
|
effective_size = sizeof word * (MAX (1, argc) + 2) + text_size;
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
|
|
|
|
if (arg2)
|
|
|
|
|
effective_size += sizeof word;
|
|
|
|
|
|
|
|
|
|
/* Copy regs to original so that user_alloca knows it should append
|
|
|
|
|
the ABI red zone. */
|
|
|
|
|
|
|
|
|
|
memcpy (&original, regs, sizeof *regs);
|
|
|
|
|
new = user_alloca (tracee, &original, regs,
|
|
|
|
|
effective_size);
|
|
|
|
|
|
|
|
|
|
if (!new)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
/* Figure out where argv starts. */
|
|
|
|
|
|
2023-05-31 11:27:19 +08:00
|
|
|
|
new3 = new + text_size;
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
2023-05-31 11:27:19 +08:00
|
|
|
|
/* Now write the first two strings. */
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
|
|
|
|
new1 = new + strlen (arg1) + 1;
|
2023-05-31 11:27:19 +08:00
|
|
|
|
new2 = new1 + (arg2 ? strlen (arg2) + 1 : 0);
|
|
|
|
|
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
if (user_copy (tracee, (const unsigned char *) arg1,
|
|
|
|
|
new, new1 - new))
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
if (arg2 && user_copy (tracee, (const unsigned char *) arg2,
|
|
|
|
|
new1, new2 - new1))
|
|
|
|
|
goto fail;
|
|
|
|
|
|
2023-05-31 11:27:19 +08:00
|
|
|
|
/* Write the replacement arg3, the file name of the executable. */
|
|
|
|
|
|
|
|
|
|
if (user_copy (tracee, (const unsigned char *) arg3,
|
|
|
|
|
new2, new3 - new2))
|
|
|
|
|
goto fail;
|
|
|
|
|
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
/* Start copying argv back to new2. First, write the one or two new
|
|
|
|
|
arguments. */
|
|
|
|
|
|
|
|
|
|
if (ptrace (PTRACE_POKETEXT, tracee->pid,
|
2023-05-31 11:27:19 +08:00
|
|
|
|
(void *) new3, (void *) new))
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
goto fail;
|
|
|
|
|
|
2023-05-31 11:27:19 +08:00
|
|
|
|
new3 += sizeof new3;
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
|
|
|
|
if (arg2 && ptrace (PTRACE_POKETEXT, tracee->pid,
|
2023-05-31 11:27:19 +08:00
|
|
|
|
(void *) new3, (void *) new1))
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
goto fail;
|
|
|
|
|
else if (arg2)
|
2023-05-31 11:27:19 +08:00
|
|
|
|
new3 += sizeof new3;
|
|
|
|
|
|
|
|
|
|
/* Next, write the third argument. */
|
|
|
|
|
|
|
|
|
|
if (ptrace (PTRACE_POKETEXT, tracee->pid, (void *) new3,
|
|
|
|
|
(void *) new2))
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
new3 += sizeof new3;
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
|
|
|
|
/* Copy the remaining arguments back. */
|
|
|
|
|
|
|
|
|
|
argv = regs->SYSCALL_ARG1_REG;
|
|
|
|
|
|
2023-05-31 11:27:19 +08:00
|
|
|
|
if (argc)
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
{
|
2023-05-31 11:27:19 +08:00
|
|
|
|
/* Make sure the trailing NULL is included. */
|
|
|
|
|
argc += 1;
|
|
|
|
|
|
|
|
|
|
/* Now copy each argument in argv, starting from argv[1]. */
|
|
|
|
|
|
|
|
|
|
for (i = 1; i < argc; ++i)
|
|
|
|
|
{
|
|
|
|
|
/* Read one argument. */
|
|
|
|
|
word = ptrace (PTRACE_PEEKDATA, tracee->pid,
|
|
|
|
|
(void *) (argv + i * sizeof argv), NULL);
|
|
|
|
|
|
|
|
|
|
/* Write one argument, then increment new3. */
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
2023-05-31 11:27:19 +08:00
|
|
|
|
if (ptrace (PTRACE_POKETEXT, tracee->pid,
|
|
|
|
|
(void *) new3, (void *) word))
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
new3 += sizeof new3;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Just write the trailing NULL. */
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
|
|
|
|
if (ptrace (PTRACE_POKETEXT, tracee->pid,
|
2023-05-31 11:27:19 +08:00
|
|
|
|
(void *) new3, (void *) 0))
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
goto fail;
|
|
|
|
|
|
2023-05-31 11:27:19 +08:00
|
|
|
|
new3 += sizeof new3;
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-31 11:27:19 +08:00
|
|
|
|
/* Assert that new3 is not out of bounds. */
|
|
|
|
|
assert (new3 == new + effective_size);
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
|
|
|
|
/* And that it is properly aligned. */
|
2023-05-31 11:27:19 +08:00
|
|
|
|
assert (!(new3 & (sizeof new3 - 2)));
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
|
|
|
|
/* Now modify the system call argument to point to new +
|
|
|
|
|
text_size. */
|
|
|
|
|
|
|
|
|
|
regs->SYSCALL_ARG1_REG = new + text_size;
|
|
|
|
|
|
|
|
|
|
#ifdef __aarch64__
|
|
|
|
|
if (aarch64_set_regs (tracee->pid, regs, false))
|
|
|
|
|
goto fail;
|
|
|
|
|
#else /* !__aarch64__ */
|
|
|
|
|
if (ptrace (PTRACE_SETREGS, tracee->pid, NULL, regs))
|
|
|
|
|
goto fail;
|
|
|
|
|
#endif /* __aarch64__ */
|
|
|
|
|
|
|
|
|
|
/* Success. */
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
fail:
|
|
|
|
|
/* Restore the original stack pointer. */
|
|
|
|
|
#ifdef __aarch64__
|
|
|
|
|
aarch64_set_regs (tracee->pid, &original, false);
|
|
|
|
|
#else /* !__aarch64__ */
|
|
|
|
|
ptrace (PTRACE_SETREGS, tracee->pid, NULL, &original);
|
|
|
|
|
#endif /* __aarch64__ */
|
|
|
|
|
errno = ENOMEM;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-05-01 21:23:12 +08:00
|
|
|
|
/* Format PID, an unsigned process identifier, in base 10. Place the
|
|
|
|
|
result in *IN, and return a pointer to the byte after the
|
|
|
|
|
result. REM should be NULL. */
|
|
|
|
|
|
2024-03-14 13:45:48 +08:00
|
|
|
|
char *
|
2023-05-01 21:23:12 +08:00
|
|
|
|
format_pid (char *in, unsigned int pid)
|
|
|
|
|
{
|
|
|
|
|
unsigned int digits[32], *fill;
|
|
|
|
|
|
|
|
|
|
fill = digits;
|
|
|
|
|
|
|
|
|
|
for (; pid != 0; pid = pid / 10)
|
|
|
|
|
*fill++ = pid % 10;
|
|
|
|
|
|
|
|
|
|
/* Insert 0 if the number would otherwise be empty. */
|
|
|
|
|
|
|
|
|
|
if (fill == digits)
|
|
|
|
|
*fill++ = 0;
|
|
|
|
|
|
|
|
|
|
while (fill != digits)
|
|
|
|
|
{
|
|
|
|
|
--fill;
|
|
|
|
|
*in++ = '0' + *fill;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*in = '\0';
|
|
|
|
|
return in;
|
|
|
|
|
}
|
|
|
|
|
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
/* Return a sequence of actions required to load the executable under
|
|
|
|
|
the file NAME for the given TRACEE. First, see if the file starts
|
|
|
|
|
with #!; in that case, find the program to open and use that
|
|
|
|
|
instead.
|
|
|
|
|
|
|
|
|
|
Next, read the executable header, and add the necessary memory
|
|
|
|
|
mappings for each file. Finally, return the action data and its
|
|
|
|
|
size in *SIZE.
|
|
|
|
|
|
|
|
|
|
Finally, use REGS to add the required interpreter arguments to the
|
|
|
|
|
caller's argv.
|
|
|
|
|
|
|
|
|
|
Value is NULL upon failure, with errno set accordingly. */
|
|
|
|
|
|
|
|
|
|
char *
|
2023-05-02 20:45:57 +08:00
|
|
|
|
exec_0 (char *name, struct exec_tracee *tracee,
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
size_t *size, USER_REGS_STRUCT *regs)
|
|
|
|
|
{
|
|
|
|
|
int fd, rc, i;
|
|
|
|
|
elf_header header;
|
|
|
|
|
const char *interpreter_name, *extra;
|
|
|
|
|
program_header program;
|
|
|
|
|
USER_WORD entry, program_entry, offset;
|
|
|
|
|
USER_WORD header_offset;
|
|
|
|
|
struct exec_jump_command jump;
|
|
|
|
|
#if defined __mips__ && !defined MIPS_NABI
|
|
|
|
|
int fpu_mode;
|
|
|
|
|
#endif /* defined __mips__ && !defined MIPS_NABI */
|
2023-05-02 20:45:57 +08:00
|
|
|
|
char buffer[80], buffer1[PATH_MAX + 80], *rewrite;
|
|
|
|
|
ssize_t link_size;
|
2023-05-01 21:23:12 +08:00
|
|
|
|
size_t remaining;
|
|
|
|
|
|
2023-05-05 12:10:14 +08:00
|
|
|
|
/* If the process is trying to run /proc/self/exe, make it run
|
|
|
|
|
itself instead. */
|
2023-05-01 21:23:12 +08:00
|
|
|
|
|
2023-05-05 12:10:14 +08:00
|
|
|
|
if (!strcmp (name, "/proc/self/exe") && tracee->exec_file)
|
2023-05-01 21:23:12 +08:00
|
|
|
|
{
|
2023-05-05 12:10:14 +08:00
|
|
|
|
strncpy (name, tracee->exec_file, PATH_MAX - 1);
|
|
|
|
|
name[PATH_MAX] = '\0';
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* If name is not absolute, then make it relative to TRACEE's
|
2023-08-12 12:50:15 -07:00
|
|
|
|
cwd. Do not use sprintf at it is not reentrant and it
|
|
|
|
|
mishandles results longer than INT_MAX. */
|
2023-05-01 21:23:12 +08:00
|
|
|
|
|
2023-05-05 12:10:14 +08:00
|
|
|
|
if (name[0] && name[0] != '/')
|
|
|
|
|
{
|
2023-08-12 12:50:15 -07:00
|
|
|
|
/* Clear both buffers. */
|
2023-05-05 12:10:14 +08:00
|
|
|
|
memset (buffer, 0, sizeof buffer);
|
2023-08-12 12:50:15 -07:00
|
|
|
|
memset (buffer1, 0, sizeof buffer1);
|
2023-05-02 20:45:57 +08:00
|
|
|
|
|
2023-05-05 12:10:14 +08:00
|
|
|
|
/* Copy over /proc, the PID, and /cwd/. */
|
|
|
|
|
rewrite = stpcpy (buffer, "/proc/");
|
|
|
|
|
rewrite = format_pid (rewrite, tracee->pid);
|
2023-05-23 09:22:19 +08:00
|
|
|
|
strcpy (rewrite, "/cwd");
|
2023-05-02 20:45:57 +08:00
|
|
|
|
|
2023-05-05 12:10:14 +08:00
|
|
|
|
/* Resolve this symbolic link. */
|
2023-05-02 20:45:57 +08:00
|
|
|
|
|
2023-05-05 12:10:14 +08:00
|
|
|
|
link_size = readlink (buffer, buffer1,
|
|
|
|
|
PATH_MAX + 1);
|
2023-05-02 20:45:57 +08:00
|
|
|
|
|
2023-05-05 12:10:14 +08:00
|
|
|
|
if (link_size < 0)
|
|
|
|
|
return NULL;
|
2023-05-02 20:45:57 +08:00
|
|
|
|
|
2023-05-05 12:10:14 +08:00
|
|
|
|
/* Check that the name is a reasonable size. */
|
2023-05-02 20:45:57 +08:00
|
|
|
|
|
2023-05-05 12:10:14 +08:00
|
|
|
|
if (link_size > PATH_MAX)
|
|
|
|
|
{
|
|
|
|
|
/* The name is too long. */
|
|
|
|
|
errno = ENAMETOOLONG;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Add a directory separator if necessary. */
|
2023-08-12 13:42:14 -04:00
|
|
|
|
|
2023-05-05 12:10:14 +08:00
|
|
|
|
if (!link_size || buffer1[link_size - 1] != '/')
|
|
|
|
|
buffer1[link_size] = '/', link_size++;
|
2023-05-01 21:23:12 +08:00
|
|
|
|
|
2023-05-05 12:10:14 +08:00
|
|
|
|
rewrite = buffer1 + link_size;
|
|
|
|
|
remaining = buffer1 + sizeof buffer1 - rewrite - 1;
|
2023-08-12 12:50:15 -07:00
|
|
|
|
memcpy (rewrite, name, strnlen (name, remaining));
|
2024-07-01 22:55:03 +08:00
|
|
|
|
|
|
|
|
|
/* Replace name with buffer1. */
|
|
|
|
|
strcpy (name, buffer1);
|
2023-05-05 12:10:14 +08:00
|
|
|
|
}
|
2023-05-01 21:23:12 +08:00
|
|
|
|
}
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
|
2023-05-05 12:10:14 +08:00
|
|
|
|
/* Check that the file is accessible and executable. */
|
|
|
|
|
|
|
|
|
|
if (access (name, X_OK))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
fd = open (name, O_RDONLY);
|
|
|
|
|
if (fd < 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
/* Now read the header. */
|
|
|
|
|
|
|
|
|
|
extra = NULL;
|
|
|
|
|
interpreter_name = check_interpreter (name, fd, &extra);
|
|
|
|
|
if (!interpreter_name)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
/* Open the interpreter instead, if necessary. */
|
|
|
|
|
if (interpreter_name != name)
|
|
|
|
|
{
|
|
|
|
|
close (fd);
|
|
|
|
|
fd = open (interpreter_name, O_RDONLY);
|
|
|
|
|
if (fd < 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
/* Now, rewrite the argument list to include `interpreter_name'
|
|
|
|
|
and perhaps `extra'. */
|
|
|
|
|
|
|
|
|
|
if (insert_args (tracee, regs, interpreter_name,
|
2023-05-31 11:27:19 +08:00
|
|
|
|
extra, name))
|
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
2023-04-30 21:37:19 +08:00
|
|
|
|
goto fail1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rc = read (fd, &header, sizeof header);
|
|
|
|
|
|
|
|
|
|
if (rc < sizeof header)
|
|
|
|
|
goto fail1;
|
|
|
|
|
|
|
|
|
|
/* Verify that this is indeed an ELF file. */
|
|
|
|
|
|
|
|
|
|
if (header.e_ident[0] != 0x7f
|
|
|
|
|
|| header.e_ident[1] != 'E'
|
|
|
|
|
|| header.e_ident[2] != 'L'
|
|
|
|
|
|| header.e_ident[3] != 'F')
|
|
|
|
|
goto fail1;
|
|
|
|
|
|
|
|
|
|
/* Now check that the class is correct. */
|
|
|
|
|
#ifdef EXEC_64
|
|
|
|
|
if (header.e_ident[4] != 2)
|
|
|
|
|
goto fail1;
|
|
|
|
|
#else /* !EXEC_64 */
|
|
|
|
|
if (header.e_ident[4] != 1)
|
|
|
|
|
goto fail1;
|
|
|
|
|
#endif /* EXEC_64 */
|
|
|
|
|
|
|
|
|
|
/* And the endianness. */
|
|
|
|
|
#ifndef WORDS_BIGENDIAN
|
|
|
|
|
if (header.e_ident[5] != 1)
|
|
|
|
|
goto fail1;
|
|
|
|
|
#else /* WORDS_BIGENDIAN */
|
|
|
|
|
if (header.e_ident[5] != 2)
|
|
|
|
|
goto fail1;
|
|
|
|
|
#endif /* EXEC_64 */
|
|
|
|
|
|
|
|
|
|
/* Check that this is an executable. */
|
|
|
|
|
if (header.e_type != 2 && header.e_type != 3)
|
|
|
|
|
goto fail1;
|
|
|
|
|
|
|
|
|
|
/* Now check that the ELF program header makes sense. */
|
|
|
|
|
if (header.e_phnum > 0xffff
|
|
|
|
|
|| (header.e_phentsize
|
|
|
|
|
!= sizeof (program_header)))
|
|
|
|
|
goto fail1;
|
|
|
|
|
|
|
|
|
|
/* Seek to the first program header and read each one. */
|
|
|
|
|
rc = lseek (fd, header.e_phoff, SEEK_SET);
|
|
|
|
|
if (rc < 0)
|
|
|
|
|
goto fail1;
|
|
|
|
|
loader_area_used = 0;
|
|
|
|
|
|
|
|
|
|
/* Write the command used to open the executable. */
|
|
|
|
|
if (write_open_command (interpreter_name, false))
|
|
|
|
|
goto fail1;
|
|
|
|
|
|
|
|
|
|
/* Apply base addresses for PIC code. */
|
|
|
|
|
|
|
|
|
|
if (header.e_type == 3) /* ET_DYN */
|
|
|
|
|
offset = EXECUTABLE_BASE;
|
|
|
|
|
else
|
|
|
|
|
offset = 0;
|
|
|
|
|
|
|
|
|
|
/* entry and program_entry are initially the same, but entry may be
|
|
|
|
|
set to that of the interpreter if one is present. */
|
|
|
|
|
|
|
|
|
|
entry = header.e_entry + offset;
|
|
|
|
|
program_entry = header.e_entry;
|
|
|
|
|
|
|
|
|
|
#if defined __mips__ && !defined MIPS_NABI
|
|
|
|
|
/* Clear MIPS ABI flags. */
|
|
|
|
|
exec_abiflags = NULL;
|
|
|
|
|
interpreter_abiflags = NULL;
|
|
|
|
|
interpreter_header = NULL;
|
|
|
|
|
#endif /* defined __mips__ && !defined MIPS_NABI */
|
|
|
|
|
|
|
|
|
|
/* Set header_offset to -1; `process_program_header' then updates it
|
|
|
|
|
to that of the first mapping. */
|
|
|
|
|
header_offset = -1;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < header.e_phnum; ++i)
|
|
|
|
|
{
|
|
|
|
|
rc = read (fd, &program, sizeof program);
|
|
|
|
|
if (rc < sizeof program)
|
|
|
|
|
goto fail1;
|
|
|
|
|
|
|
|
|
|
if (process_program_header (interpreter_name, fd,
|
|
|
|
|
&program, &header,
|
|
|
|
|
&entry, &header_offset))
|
|
|
|
|
goto fail1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Write the entry point and program entry. */
|
|
|
|
|
|
|
|
|
|
jump.command = 3;
|
|
|
|
|
jump.entry = entry;
|
|
|
|
|
|
|
|
|
|
/* Now calculate values for the aux vector. */
|
|
|
|
|
|
|
|
|
|
jump.at_entry = program_entry + offset;
|
|
|
|
|
jump.at_phent = header.e_phentsize;
|
|
|
|
|
jump.at_phnum = header.e_phnum;
|
|
|
|
|
jump.at_base = (entry == header.e_entry + offset
|
|
|
|
|
? EXECUTABLE_BASE
|
|
|
|
|
: INTERPRETER_BASE);
|
|
|
|
|
|
|
|
|
|
#if defined __mips__ && !defined MIPS_NABI
|
|
|
|
|
/* Finally, calculate the FPU mode wanted by the executable. */
|
|
|
|
|
|
|
|
|
|
if (determine_fpu_mode (&header, interpreter_header,
|
|
|
|
|
&fpu_mode, exec_abiflags,
|
|
|
|
|
interpreter_abiflags))
|
|
|
|
|
/* N.B. that `determine_fpu_mode' sets errno. */
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
/* If the processor is too new to support FR0 operation, place the
|
|
|
|
|
executable in floating point emulation mode. */
|
|
|
|
|
|
|
|
|
|
if (fpu_mode == FP_FR0 && !cpu_supports_fr0_p ())
|
|
|
|
|
fpu_mode = FP_FRE;
|
|
|
|
|
|
|
|
|
|
jump.fpu_mode = fpu_mode;
|
|
|
|
|
#endif /* defined __mips__ && !defined MIPS_NABI */
|
|
|
|
|
|
|
|
|
|
/* The offset used for at_phdr should be that of the first
|
|
|
|
|
mapping. */
|
|
|
|
|
|
|
|
|
|
if (header_offset == (USER_WORD) -1)
|
|
|
|
|
header_offset = 0;
|
|
|
|
|
|
|
|
|
|
jump.at_phdr = header.e_phoff + header_offset;
|
|
|
|
|
|
|
|
|
|
if (sizeof loader_area - loader_area_used < sizeof jump)
|
|
|
|
|
goto fail1;
|
|
|
|
|
|
|
|
|
|
memcpy (loader_area + loader_area_used, &jump,
|
|
|
|
|
sizeof jump);
|
|
|
|
|
loader_area_used += sizeof jump;
|
|
|
|
|
|
|
|
|
|
/* Close the file descriptor and return the number of bytes
|
|
|
|
|
used. */
|
|
|
|
|
|
|
|
|
|
close (fd);
|
|
|
|
|
*size = loader_area_used;
|
|
|
|
|
|
|
|
|
|
/* Make sure the loader area is properly aligned. */
|
|
|
|
|
assert (!(loader_area_used & (sizeof (USER_WORD) - 1)));
|
|
|
|
|
return loader_area;
|
|
|
|
|
|
|
|
|
|
fail1:
|
|
|
|
|
errno = ENOEXEC;
|
|
|
|
|
fail:
|
|
|
|
|
close (fd);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|