mirror of
https://github.com/darlinghq/darling.git
synced 2024-11-27 06:10:36 +00:00
Add sys_execve()
This commit is contained in:
parent
038afe83f0
commit
0deb8e9122
@ -57,6 +57,7 @@ set(emulation_sources
|
||||
process/fork.c
|
||||
process/wait4.c
|
||||
process/waitid.c
|
||||
process/execve.c
|
||||
signal/duct_signals.c
|
||||
signal/kill.c
|
||||
signal/sigaltstack.c
|
||||
|
86
src/kernel/emulation/linux/process/execve.c
Normal file
86
src/kernel/emulation/linux/process/execve.c
Normal file
@ -0,0 +1,86 @@
|
||||
#include "execve.h"
|
||||
#include "../base.h"
|
||||
#include "../errno.h"
|
||||
#include <asm/unistd.h>
|
||||
#include "../fcntl/open.h"
|
||||
#include "../unistd/read.h"
|
||||
#include "../unistd/close.h"
|
||||
#include "../unistd/readlink.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define MH_MAGIC 0xfeedface
|
||||
#define MH_CIGAM 0xcefaedfe
|
||||
#define MH_MAGIC_64 0xfeedfacf
|
||||
#define MH_CIGAM_64 0xcffaedfe
|
||||
#define FAT_MAGIC 0xcafebabe
|
||||
#define FAT_CIGAM 0xbebafeca
|
||||
|
||||
extern int strcmp(const char *s1, const char *s2);
|
||||
|
||||
long sys_execve(char* fname, char** argvp, char** envp)
|
||||
{
|
||||
int ret, fd;
|
||||
uint32_t magic;
|
||||
char dyld_path[256];
|
||||
|
||||
// Ideally, if everybody used binfmt_misc to allow direct
|
||||
// execution of Mach-O binaries under Darling, this wouldn't
|
||||
// be necessary. But we cannot rely on that.
|
||||
|
||||
fd = sys_open(fname, BSD_O_RDONLY, 0);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
ret = sys_read(fd, &magic, sizeof(magic));
|
||||
if (ret != 4)
|
||||
goto no_macho;
|
||||
|
||||
if (magic == MH_MAGIC || magic == MH_CIGAM
|
||||
|| magic == MH_MAGIC_64 || magic == MH_CIGAM_64
|
||||
|| magic == FAT_MAGIC || magic == FAT_CIGAM)
|
||||
{
|
||||
// It is a Mach-O file
|
||||
int len, i;
|
||||
char** modargvp;
|
||||
|
||||
len = sys_readlink("/proc/self/exe", dyld_path, sizeof(dyld_path)-1);
|
||||
if (len < 0)
|
||||
goto no_macho;
|
||||
|
||||
dyld_path[len] = '\0';
|
||||
|
||||
// Remove 64 or 32 suffix if present
|
||||
if (strcmp(&dyld_path[len - 2], "32") == 0
|
||||
|| strcmp(&dyld_path[len - 2], "64") == 0)
|
||||
{
|
||||
dyld_path[len-2] = '\0';
|
||||
}
|
||||
|
||||
// Prepend dyld path
|
||||
len = 0;
|
||||
|
||||
// Count arguments
|
||||
while (argvp[len++]);
|
||||
|
||||
// Allocate a new argvp, execute dyld_path
|
||||
modargvp = (char**) __builtin_alloca(sizeof(void*) * (len+1));
|
||||
modargvp[0] = dyld_path;
|
||||
modargvp[1] = fname;
|
||||
|
||||
for (i = 2; i < len+1; i++)
|
||||
modargvp[i] = argvp[i-1];
|
||||
|
||||
argvp = modargvp;
|
||||
fname = dyld_path;
|
||||
}
|
||||
|
||||
no_macho:
|
||||
sys_close(fd);
|
||||
|
||||
ret = LINUX_SYSCALL(__NR_execve, fname, argvp, envp);
|
||||
if (ret < 0)
|
||||
ret = errno_linux_to_bsd(ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
7
src/kernel/emulation/linux/process/execve.h
Normal file
7
src/kernel/emulation/linux/process/execve.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef LINUX_EXECVE_H
|
||||
#define LINUX_EXECVE_H
|
||||
|
||||
long sys_execve(char* fname, char** argvp, char** envp);
|
||||
|
||||
#endif
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "process/vfork.h"
|
||||
#include "process/wait4.h"
|
||||
#include "process/waitid.h"
|
||||
#include "process/execve.h"
|
||||
#include "misc/ioctl.h"
|
||||
#include "misc/getrlimit.h"
|
||||
#include "misc/thread_selfid.h"
|
||||
@ -116,6 +117,7 @@ void* __bsd_syscall_table[512] = {
|
||||
[54] = sys_ioctl,
|
||||
[57] = sys_symlink,
|
||||
[58] = sys_readlink,
|
||||
[59] = sys_execve,
|
||||
[60] = sys_umask,
|
||||
[61] = sys_chroot,
|
||||
[66] = sys_vfork,
|
||||
|
Loading…
Reference in New Issue
Block a user