|
@@ -26,65 +26,13 @@ struct kinfo_proc;
|
|
|
|
|
|
#include "qemu.h"
|
|
|
|
|
|
-/*
|
|
|
- * Get the filename for the given file descriptor.
|
|
|
- * Note that this may return NULL (fail) if no longer cached in the kernel.
|
|
|
- */
|
|
|
-static char *
|
|
|
-get_filename_from_fd(pid_t pid, int fd, char *filename, size_t len)
|
|
|
-{
|
|
|
- char *ret = NULL;
|
|
|
- unsigned int cnt;
|
|
|
- struct procstat *procstat = NULL;
|
|
|
- struct kinfo_proc *kp = NULL;
|
|
|
- struct filestat_list *head = NULL;
|
|
|
- struct filestat *fst;
|
|
|
-
|
|
|
- procstat = procstat_open_sysctl();
|
|
|
- if (procstat == NULL) {
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- kp = procstat_getprocs(procstat, KERN_PROC_PID, pid, &cnt);
|
|
|
- if (kp == NULL) {
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- head = procstat_getfiles(procstat, kp, 0);
|
|
|
- if (head == NULL) {
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- STAILQ_FOREACH(fst, head, next) {
|
|
|
- if (fd == fst->fs_fd) {
|
|
|
- if (fst->fs_path != NULL) {
|
|
|
- (void)strlcpy(filename, fst->fs_path, len);
|
|
|
- ret = filename;
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-out:
|
|
|
- if (head != NULL) {
|
|
|
- procstat_freefiles(procstat, head);
|
|
|
- }
|
|
|
- if (kp != NULL) {
|
|
|
- procstat_freeprocs(procstat, kp);
|
|
|
- }
|
|
|
- if (procstat != NULL) {
|
|
|
- procstat_close(procstat);
|
|
|
- }
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* execve/fexecve
|
|
|
*/
|
|
|
abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp,
|
|
|
abi_ulong guest_envp, int do_fexec)
|
|
|
{
|
|
|
- char **argp, **envp, **qargp, **qarg1, **qarg0, **qargend;
|
|
|
+ char **argp, **envp, **qarg0;
|
|
|
int argc, envc;
|
|
|
abi_ulong gp;
|
|
|
abi_ulong addr;
|
|
@@ -117,9 +65,7 @@ abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp,
|
|
|
qarg0 = argp = g_new0(char *, argc + 9);
|
|
|
/* save the first argument for the emulator */
|
|
|
*argp++ = (char *)getprogname();
|
|
|
- qargp = argp;
|
|
|
*argp++ = (char *)getprogname();
|
|
|
- qarg1 = argp;
|
|
|
envp = g_new0(char *, envc + 1);
|
|
|
for (gp = guest_argp, q = argp; gp; gp += sizeof(abi_ulong), q++) {
|
|
|
if (get_user_ual(addr, gp)) {
|
|
@@ -137,7 +83,6 @@ abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp,
|
|
|
total_size += strlen(*q) + 1;
|
|
|
}
|
|
|
*q++ = NULL;
|
|
|
- qargend = q;
|
|
|
|
|
|
for (gp = guest_envp, q = envp; gp; gp += sizeof(abi_ulong), q++) {
|
|
|
if (get_user_ual(addr, gp)) {
|
|
@@ -166,71 +111,14 @@ abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp,
|
|
|
}
|
|
|
|
|
|
if (do_fexec) {
|
|
|
- if (((int)path_or_fd > 0 &&
|
|
|
- is_target_elf_binary((int)path_or_fd)) == 1) {
|
|
|
- char execpath[PATH_MAX];
|
|
|
-
|
|
|
- /*
|
|
|
- * The executable is an elf binary for the target
|
|
|
- * arch. execve() it using the emulator if we can
|
|
|
- * determine the filename path from the fd.
|
|
|
- */
|
|
|
- if (get_filename_from_fd(getpid(), (int)path_or_fd, execpath,
|
|
|
- sizeof(execpath)) != NULL) {
|
|
|
- memmove(qarg1 + 2, qarg1, (qargend - qarg1) * sizeof(*qarg1));
|
|
|
- qarg1[1] = qarg1[0];
|
|
|
- qarg1[0] = (char *)"-0";
|
|
|
- qarg1 += 2;
|
|
|
- qargend += 2;
|
|
|
- *qarg1 = execpath;
|
|
|
-#ifndef DONT_INHERIT_INTERP_PREFIX
|
|
|
- memmove(qarg1 + 2, qarg1, (qargend - qarg1) * sizeof(*qarg1));
|
|
|
- *qarg1++ = (char *)"-L";
|
|
|
- *qarg1++ = (char *)interp_prefix;
|
|
|
-#endif
|
|
|
- ret = get_errno(execve(qemu_proc_pathname, qargp, envp));
|
|
|
- } else {
|
|
|
- /* Getting the filename path failed. */
|
|
|
- ret = -TARGET_EBADF;
|
|
|
- goto execve_end;
|
|
|
- }
|
|
|
- } else {
|
|
|
- ret = get_errno(fexecve((int)path_or_fd, argp, envp));
|
|
|
- }
|
|
|
+ ret = get_errno(fexecve((int)path_or_fd, argp, envp));
|
|
|
} else {
|
|
|
- int fd;
|
|
|
-
|
|
|
p = lock_user_string(path_or_fd);
|
|
|
if (p == NULL) {
|
|
|
ret = -TARGET_EFAULT;
|
|
|
goto execve_end;
|
|
|
}
|
|
|
-
|
|
|
- /*
|
|
|
- * Check the header and see if it a target elf binary. If so
|
|
|
- * then execute using qemu user mode emulator.
|
|
|
- */
|
|
|
- fd = open(p, O_RDONLY | O_CLOEXEC);
|
|
|
- if (fd > 0 && is_target_elf_binary(fd) == 1) {
|
|
|
- close(fd);
|
|
|
- /* execve() as a target binary using emulator. */
|
|
|
- memmove(qarg1 + 2, qarg1, (qargend - qarg1) * sizeof(*qarg1));
|
|
|
- qarg1[1] = qarg1[0];
|
|
|
- qarg1[0] = (char *)"-0";
|
|
|
- qarg1 += 2;
|
|
|
- qargend += 2;
|
|
|
- *qarg1 = (char *)p;
|
|
|
-#ifndef DONT_INHERIT_INTERP_PREFIX
|
|
|
- memmove(qarg1 + 2, qarg1, (qargend - qarg1) * sizeof(*qarg1));
|
|
|
- *qarg1++ = (char *)"-L";
|
|
|
- *qarg1++ = (char *)interp_prefix;
|
|
|
-#endif
|
|
|
- ret = get_errno(execve(qemu_proc_pathname, qargp, envp));
|
|
|
- } else {
|
|
|
- close(fd);
|
|
|
- /* Execve() as a host native binary. */
|
|
|
- ret = get_errno(execve(p, argp, envp));
|
|
|
- }
|
|
|
+ ret = get_errno(execve(p, argp, envp));
|
|
|
unlock_user(p, path_or_fd, 0);
|
|
|
}
|
|
|
|