mirror of
https://github.com/darlinghq/darling-xnu.git
synced 2024-11-26 22:10:24 +00:00
[WIP] Reorganise Emulation Code
The goal of this commit is to have a buildable proof-of-concept for how I plan to reorganize the syscall code (and other miscellaneous code) in the emulation folder. Note, It not expected for Darling to sucessfully execute the shell in this commit.
This commit is contained in:
parent
814a90cae0
commit
a3bfa8cca1
@ -8,7 +8,7 @@ endif(COMMAND cmake_policy)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
add_subdirectory(emulation/linux)
|
||||
add_subdirectory(emulation)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse -msse2 -msse3 -w -fblocks -ffreestanding")
|
||||
|
||||
@ -41,8 +41,11 @@ add_circular(system_kernel FAT
|
||||
$<TARGET_OBJECTS:libsyscall>
|
||||
$<TARGET_OBJECTS:libsyscall_dynamic>
|
||||
#$<TARGET_OBJECTS:kqueue>
|
||||
$<TARGET_OBJECTS:emulation>
|
||||
$<TARGET_OBJECTS:mach_server_client>
|
||||
$<TARGET_OBJECTS:emulation_common>
|
||||
$<TARGET_OBJECTS:emulation_conversion>
|
||||
$<TARGET_OBJECTS:emulation_darling>
|
||||
$<TARGET_OBJECTS:emulation_linux_api>
|
||||
$<TARGET_OBJECTS:emulation_xnu_syscall>
|
||||
SIBLINGS
|
||||
system_c
|
||||
compiler_rt
|
||||
@ -56,15 +59,21 @@ make_fat(system_kernel)
|
||||
add_library(system_kernel_static32 STATIC
|
||||
$<TARGET_OBJECTS:libsyscall_32>
|
||||
$<TARGET_OBJECTS:libsyscall>
|
||||
$<TARGET_OBJECTS:emulation_dyld>
|
||||
$<TARGET_OBJECTS:mach_server_client_dyld>
|
||||
$<TARGET_OBJECTS:emulation_common>
|
||||
$<TARGET_OBJECTS:emulation_conversion>
|
||||
$<TARGET_OBJECTS:emulation_darling_dyld>
|
||||
$<TARGET_OBJECTS:emulation_linux_api>
|
||||
$<TARGET_OBJECTS:emulation_xnu_syscall_dyld>
|
||||
)
|
||||
|
||||
add_library(system_kernel_static64 STATIC
|
||||
$<TARGET_OBJECTS:libsyscall_64>
|
||||
$<TARGET_OBJECTS:libsyscall>
|
||||
$<TARGET_OBJECTS:emulation_dyld>
|
||||
$<TARGET_OBJECTS:mach_server_client_dyld>
|
||||
$<TARGET_OBJECTS:emulation_common>
|
||||
$<TARGET_OBJECTS:emulation_conversion>
|
||||
$<TARGET_OBJECTS:emulation_darling_dyld>
|
||||
$<TARGET_OBJECTS:emulation_linux_api>
|
||||
$<TARGET_OBJECTS:emulation_xnu_syscall_dyld>
|
||||
)
|
||||
|
||||
target_link_libraries(system_kernel_static32 PRIVATE
|
||||
|
24
darling/src/libsystem_kernel/emulation/CMakeLists.txt
Normal file
24
darling/src/libsystem_kernel/emulation/CMakeLists.txt
Normal file
@ -0,0 +1,24 @@
|
||||
project(emulation)
|
||||
|
||||
# By default we don't want to expose these methods to normal macOS apps/frameworks
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-int-conversion -Wno-compare-distinct-pointer-types")
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
${CMAKE_BINARY_DIR}/src/startup # include src/startup for rtsig.h
|
||||
${CMAKE_BINARY_DIR}/src/external/darlingserver/include
|
||||
${CMAKE_SOURCE_DIR}/src/external/darlingserver/include
|
||||
|
||||
${CMAKE_SOURCE_DIR}/src/libsimple/include
|
||||
)
|
||||
|
||||
# Some projects may include build time checks for `VARIANT_DYLD`. It's important that
|
||||
# those projects also have a `*_dyld` varient as well.
|
||||
|
||||
add_subdirectory(common)
|
||||
add_subdirectory(conversion)
|
||||
add_subdirectory(darling)
|
||||
add_subdirectory(linux_api)
|
||||
add_subdirectory(xnu_syscall)
|
@ -0,0 +1,8 @@
|
||||
project(emulation_common)
|
||||
|
||||
set(common_sources
|
||||
simple.c
|
||||
)
|
||||
|
||||
add_darling_object_library(emulation_common ${common_sources})
|
||||
make_fat(emulation_common)
|
15
darling/src/libsystem_kernel/emulation/common/base.h
Normal file
15
darling/src/libsystem_kernel/emulation/common/base.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef DARLING_EMULATION_COMMON_BASE_H
|
||||
#define DARLING_EMULATION_COMMON_BASE_H
|
||||
|
||||
#define VISIBLE __attribute__((visibility("default")))
|
||||
#define WEAK __attribute__((weak))
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define CPP_EXTERN_C_BEGIN extern "C" {
|
||||
#define CPP_EXTERN_C_END }
|
||||
#else
|
||||
#define CPP_EXTERN_C_BEGIN
|
||||
#define CPP_EXTERN_C_END
|
||||
#endif
|
||||
|
||||
#endif // DARLING_EMULATION_COMMON_BASE_H
|
@ -1,17 +1,19 @@
|
||||
#include "base.h"
|
||||
#include "simple.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <linux-syscalls/linux.h>
|
||||
#include "mach/lkm.h"
|
||||
#include "signal/kill.h"
|
||||
#include "unistd/getpid.h"
|
||||
#include <sys/signal.h>
|
||||
|
||||
#include <darlingserver/rpc.h>
|
||||
|
||||
#include <emulation/common/base.h>
|
||||
#include <emulation/linux_api/linux_syscall.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/signal/kill.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/unistd/getpid.h>
|
||||
|
||||
extern char* memchr(char* buf, int c, __SIZE_TYPE__ n);
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
VISIBLE
|
||||
int __simple_strlen(const char* text)
|
||||
{
|
||||
int len = 0;
|
||||
@ -30,7 +32,7 @@ if (VALUE != NULL) { \
|
||||
DO; \
|
||||
}
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
VISIBLE
|
||||
int __simple_vsnprintf(char* buf, size_t max_length, const char* format, va_list vl)
|
||||
{
|
||||
size_t offset = 0;
|
||||
@ -358,13 +360,13 @@ int __simple_vsnprintf(char* buf, size_t max_length, const char* format, va_list
|
||||
return offset;
|
||||
}
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
VISIBLE
|
||||
int __simple_vsprintf(char* buf, const char* format, va_list vl)
|
||||
{
|
||||
return __simple_vsnprintf(buf, SIZE_MAX, format, vl);
|
||||
}
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
VISIBLE
|
||||
void __simple_printf(const char* format, ...)
|
||||
{
|
||||
char buffer[512];
|
||||
@ -377,7 +379,7 @@ void __simple_printf(const char* format, ...)
|
||||
LINUX_SYSCALL3(__NR_write, 1, buffer, __simple_strlen(buffer));
|
||||
}
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
VISIBLE
|
||||
void __simple_kprintf(const char* format, ...)
|
||||
{
|
||||
va_list vl;
|
||||
@ -386,7 +388,7 @@ void __simple_kprintf(const char* format, ...)
|
||||
va_end(vl);
|
||||
}
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
VISIBLE
|
||||
void __simple_fprintf(int fd, const char* format, ...)
|
||||
{
|
||||
char buffer[512];
|
||||
@ -399,7 +401,7 @@ void __simple_fprintf(int fd, const char* format, ...)
|
||||
LINUX_SYSCALL3(__NR_write, fd, buffer, __simple_strlen(buffer));
|
||||
}
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
VISIBLE
|
||||
void __simple_vprintf(const char* format, va_list args)
|
||||
{
|
||||
char buffer[512];
|
||||
@ -407,7 +409,7 @@ void __simple_vprintf(const char* format, va_list args)
|
||||
LINUX_SYSCALL3(__NR_write, 1, buffer, __simple_strlen(buffer));
|
||||
}
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
VISIBLE
|
||||
void __simple_vkprintf(const char* format, va_list args)
|
||||
{
|
||||
char buffer[512];
|
||||
@ -415,7 +417,7 @@ void __simple_vkprintf(const char* format, va_list args)
|
||||
dserver_rpc_kprintf(buffer, __simple_strlen(buffer));
|
||||
}
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
VISIBLE
|
||||
void __simple_vfprintf(int fd, const char* format, va_list args)
|
||||
{
|
||||
char buffer[512];
|
||||
@ -423,7 +425,7 @@ void __simple_vfprintf(int fd, const char* format, va_list args)
|
||||
LINUX_SYSCALL3(__NR_write, fd, buffer, __simple_strlen(buffer));
|
||||
}
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
VISIBLE
|
||||
int __simple_sprintf(char *buffer, const char* format, ...)
|
||||
{
|
||||
va_list vl;
|
||||
@ -435,7 +437,7 @@ int __simple_sprintf(char *buffer, const char* format, ...)
|
||||
return ret;
|
||||
}
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
VISIBLE
|
||||
int __simple_snprintf(char* buffer, size_t max_length, const char* format, ...)
|
||||
{
|
||||
va_list args;
|
||||
@ -467,7 +469,7 @@ static int isdigit16(char c)
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
VISIBLE
|
||||
unsigned long long __simple_atoi(const char* str, const char** endp)
|
||||
{
|
||||
unsigned long long value = 0;
|
||||
@ -484,7 +486,7 @@ unsigned long long __simple_atoi(const char* str, const char** endp)
|
||||
return value;
|
||||
}
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
VISIBLE
|
||||
unsigned long long __simple_atoi16(const char* str, const char** endp)
|
||||
{
|
||||
unsigned long long value = 0;
|
||||
@ -516,13 +518,13 @@ extern long sys_read(int fd, void* buf, __SIZE_TYPE__ n);
|
||||
# define min(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
VISIBLE
|
||||
void __simple_readline_init(struct simple_readline_buf* buf)
|
||||
{
|
||||
buf->used = 0;
|
||||
}
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
VISIBLE
|
||||
char* __simple_readline(int fd, struct simple_readline_buf* buf, char* out, int max_out)
|
||||
{
|
||||
char* nl = NULL;
|
||||
@ -573,7 +575,7 @@ have_nl:
|
||||
return out;
|
||||
}
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
VISIBLE
|
||||
void __simple_abort(void) {
|
||||
sys_kill(sys_getpid(), SIGABRT, 1);
|
||||
__builtin_unreachable();
|
@ -1,14 +1,14 @@
|
||||
#ifndef LINUX_DEBUG_H
|
||||
#define LINUX_DEBUG_H
|
||||
#ifndef DARLING_EMULATION_COMMON_SIMPLE_H
|
||||
#define DARLING_EMULATION_COMMON_SIMPLE_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <darling/emulation/common/base.h>
|
||||
|
||||
// everything in this header can be used outside of libsystem_kernel
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
CPP_EXTERN_C_BEGIN
|
||||
|
||||
void __simple_printf(const char* format, ...) __attribute__((format(printf, 1, 2)));
|
||||
void __simple_kprintf(const char* format, ...) __attribute__((format(printf, 1, 2)));
|
||||
@ -37,9 +37,6 @@ char* __simple_readline(int fd, struct simple_readline_buf* buf, char* out, int
|
||||
__attribute__((noreturn))
|
||||
void __simple_abort(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
CPP_EXTERN_C_END
|
||||
|
||||
#endif // DARLING_EMULATION_COMMON_SIMPLE_H
|
@ -0,0 +1,15 @@
|
||||
project(emulation_conversion)
|
||||
|
||||
set(conversion_sources
|
||||
at.c
|
||||
errno.c
|
||||
signal.c
|
||||
stat.c
|
||||
network/common.c
|
||||
signal/context.c
|
||||
signal/sigaction.c
|
||||
signal/sigexc.c
|
||||
)
|
||||
|
||||
add_darling_object_library(emulation_conversion ${conversion_sources})
|
||||
make_fat(emulation_conversion)
|
@ -1,5 +1,4 @@
|
||||
#include "common_at.h"
|
||||
#include "bsdthread/per_thread_wd.h"
|
||||
#include "at.h"
|
||||
|
||||
int atflags_bsd_to_linux(int flags)
|
||||
{
|
||||
@ -25,10 +24,3 @@ int atflags_bsd_to_linux(int flags)
|
||||
|
||||
return linux_flags;
|
||||
}
|
||||
|
||||
int atfd(int fd)
|
||||
{
|
||||
if (fd == BSD_AT_FDCWD)
|
||||
return get_perthread_wd();
|
||||
return fd;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
#ifndef _COMMON_AT_H
|
||||
#define _COMMON_AT_H
|
||||
#ifndef DARLING_EMULATION_CONVERSION_AT_H
|
||||
#define DARLING_EMULATION_CONVERSION_AT_H
|
||||
|
||||
// Common declarations for the *at family of system calls
|
||||
|
||||
@ -23,5 +23,4 @@ int atflags_bsd_to_linux(int flags);
|
||||
|
||||
int atfd(int fd);
|
||||
|
||||
#endif
|
||||
|
||||
#endif // DARLING_EMULATION_CONVERSION_AT_H
|
@ -1,10 +1,9 @@
|
||||
#include "errno.h"
|
||||
#include "base.h"
|
||||
#include "duct_errno.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
static const int linux_to_darwin[512] = {
|
||||
|
||||
[LINUX_EPERM] = EPERM,
|
||||
[LINUX_ENOENT] = ENOENT,
|
||||
[LINUX_ESRCH] = ESRCH,
|
134
darling/src/libsystem_kernel/emulation/conversion/errno.h
Normal file
134
darling/src/libsystem_kernel/emulation/conversion/errno.h
Normal file
@ -0,0 +1,134 @@
|
||||
#ifndef DARLING_EMULATION_CONVERSION_ERRNO_H
|
||||
#define DARLING_EMULATION_CONVERSION_ERRNO_H
|
||||
|
||||
#define LINUX_EPERM 1
|
||||
#define LINUX_ENOENT 2
|
||||
#define LINUX_ESRCH 3
|
||||
#define LINUX_EINTR 4
|
||||
#define LINUX_EIO 5
|
||||
#define LINUX_ENXIO 6
|
||||
#define LINUX_ENOEXEC 8
|
||||
#define LINUX_EBADF 9
|
||||
#define LINUX_ECHILD 10
|
||||
#define LINUX_EAGAIN 11
|
||||
#define LINUX_ENOMEM 12
|
||||
#define LINUX_EACCES 13
|
||||
#define LINUX_EFAULT 14
|
||||
#define LINUX_ENOTBLK 15
|
||||
#define LINUX_EBUSY 16
|
||||
#define LINUX_EEXIST 17
|
||||
#define LINUX_EXDEV 18
|
||||
#define LINUX_ENODEV 19
|
||||
#define LINUX_ENOTDIR 20
|
||||
#define LINUX_EISDIR 21
|
||||
#define LINUX_EINVAL 22
|
||||
#define LINUX_ENFILE 23
|
||||
#define LINUX_EMFILE 24
|
||||
#define LINUX_ENOTTY 25
|
||||
#define LINUX_ETXTBSY 26
|
||||
#define LINUX_EFBIG 27
|
||||
#define LINUX_ENOSPC 28
|
||||
#define LINUX_ESPIPE 29
|
||||
#define LINUX_EROFS 30
|
||||
#define LINUX_EMLINK 31
|
||||
#define LINUX_EPIPE 32
|
||||
#define LINUX_EDOM 33
|
||||
#define LINUX_ERANGE 34
|
||||
#define LINUX_EDEADLK 35
|
||||
#define LINUX_ENAMETOOLONG 36
|
||||
#define LINUX_ENOLCK 37
|
||||
#define LINUX_ENOSYS 38
|
||||
#define LINUX_ENOTEMPTY 39
|
||||
#define LINUX_ELOOP 40
|
||||
#define LINUX_ENOMSG 42
|
||||
#define LINUX_EIDRM 43
|
||||
#define LINUX_ECHRNG 44
|
||||
#define LINUX_ELNRNG 48
|
||||
#define LINUX_EUNATCH 49
|
||||
#define LINUX_ENOCSI 50
|
||||
#define LINUX_EBADE 52
|
||||
#define LINUX_EBADR 53
|
||||
#define LINUX_EXFULL 54
|
||||
#define LINUX_ENOANO 55
|
||||
#define LINUX_EBADRQC 56
|
||||
#define LINUX_EBADSLT 57
|
||||
#define LINUX_EBFONT 59
|
||||
#define LINUX_ENOSTR 60
|
||||
#define LINUX_ENODATA 61
|
||||
#define LINUX_ETIME 62
|
||||
#define LINUX_ENOSR 63
|
||||
#define LINUX_ENONET 64
|
||||
#define LINUX_ENOPKG 65
|
||||
#define LINUX_EREMOTE 66
|
||||
#define LINUX_ENOLINK 67
|
||||
#define LINUX_EADV 68
|
||||
#define LINUX_ESRMNT 69
|
||||
#define LINUX_ECOMM 70
|
||||
#define LINUX_EPROTO 71
|
||||
#define LINUX_EMULTIHOP 72
|
||||
#define LINUX_EDOTDOT 73
|
||||
#define LINUX_EBADMSG 74
|
||||
#define LINUX_EOVERFLOW 75
|
||||
#define LINUX_ENOTUNIQ 76
|
||||
#define LINUX_EBADFD 77
|
||||
#define LINUX_EREMCHG 78
|
||||
#define LINUX_ELIBACC 79
|
||||
#define LINUX_ELIBBAD 80
|
||||
#define LINUX_ELIBSCN 81
|
||||
#define LINUX_ELIBMAX 82
|
||||
#define LINUX_ELIBEXEC 83
|
||||
#define LINUX_EILSEQ 84
|
||||
#define LINUX_ERESTART 85
|
||||
#define LINUX_ESTRPIPE 86
|
||||
#define LINUX_EUSERS 87
|
||||
#define LINUX_ENOTSOCK 88
|
||||
#define LINUX_EDESTADDRREQ 89
|
||||
#define LINUX_EMSGSIZE 90
|
||||
#define LINUX_EPROTOTYPE 91
|
||||
#define LINUX_ENOPROTOOPT 92
|
||||
#define LINUX_EPROTONOSUPPORT 93
|
||||
#define LINUX_ESOCKTNOSUPPORT 94
|
||||
#define LINUX_EOPNOTSUPP 95
|
||||
#define LINUX_EPFNOSUPPORT 96
|
||||
#define LINUX_EAFNOSUPPORT 97
|
||||
#define LINUX_EADDRINUSE 98
|
||||
#define LINUX_EADDRNOTAVAIL 99
|
||||
#define LINUX_ENETDOWN 100
|
||||
#define LINUX_ENETUNREACH 101
|
||||
#define LINUX_ENETRESET 102
|
||||
#define LINUX_ECONNABORTED 103
|
||||
#define LINUX_ECONNRESET 104
|
||||
#define LINUX_ENOBUFS 105
|
||||
#define LINUX_EISCONN 106
|
||||
#define LINUX_ENOTCONN 107
|
||||
#define LINUX_ESHUTDOWN 108
|
||||
#define LINUX_ETOOMANYREFS 109
|
||||
#define LINUX_ETIMEDOUT 110
|
||||
#define LINUX_ECONNREFUSED 111
|
||||
#define LINUX_EHOSTDOWN 112
|
||||
#define LINUX_EHOSTUNREACH 113
|
||||
#define LINUX_EALREADY 114
|
||||
#define LINUX_EINPROGRESS 115
|
||||
#define LINUX_ESTALE 116
|
||||
#define LINUX_EUCLEAN 117
|
||||
#define LINUX_ENOTNAM 118
|
||||
#define LINUX_ENAVAIL 119
|
||||
#define LINUX_EISNAM 120
|
||||
#define LINUX_EREMOTEIO 121
|
||||
#define LINUX_EDQUOT 122
|
||||
#define LINUX_ENOMEDIUM 123
|
||||
#define LINUX_EMEDIUMTYPE 124
|
||||
#define LINUX_ECANCELED 125
|
||||
#define LINUX_ENOKEY 126
|
||||
#define LINUX_EKEYEXPIRED 127
|
||||
#define LINUX_EKEYREVOKED 128
|
||||
#define LINUX_EKEYREJECTED 129
|
||||
#define LINUX_EOWNERDEAD 130
|
||||
#define LINUX_ENOTRECOVERABLE 131
|
||||
#define LINUX_ERFKILL 132
|
||||
#define LINUX_EHWPOISON 133
|
||||
#define LINUX_ENOTSUP LINUX_EOPNOTSUPP
|
||||
|
||||
int errno_linux_to_bsd(int err);
|
||||
|
||||
#endif // DARLING_EMULATION_CONVERSION_ERRNO_H
|
@ -1,5 +1,5 @@
|
||||
#ifndef DUCT_MMAN_H
|
||||
#define DUCT_MMAN_H
|
||||
#ifndef DARLING_EMULATION_CONVERSION_MMAN_H
|
||||
#define DARLING_EMULATION_CONVERSION_MMAN_H
|
||||
|
||||
#define LINUX_PROT_READ 0x1
|
||||
#define LINUX_PROT_WRITE 0x2
|
||||
@ -50,5 +50,4 @@
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
#endif
|
||||
|
||||
#endif // DARLING_EMULATION_CONVERSION_MMAN_H
|
@ -1,5 +1,5 @@
|
||||
#ifndef NETWORK_DUCT_H
|
||||
#define NETWORK_DUCT_H
|
||||
#ifndef DARLING_EMULATION_CONVERSION_NETWORK_H
|
||||
#define DARLING_EMULATION_CONVERSION_NETWORK_H
|
||||
|
||||
int sfamily_linux_to_bsd(int family);
|
||||
int sfamily_bsd_to_linux(int family);
|
||||
@ -69,5 +69,4 @@ int sockaddr_fixup_from_linux(struct sockaddr_fixup* out, const void* linux_sock
|
||||
#define BSD_MSG_RCVMORE 0x4000
|
||||
#define BSD_MSG_NEEDSA 0x10000
|
||||
|
||||
#endif
|
||||
|
||||
#endif // DARLING_EMULATION_CONVERSION_NETWORK_H
|
@ -1,9 +1,12 @@
|
||||
#include "duct.h"
|
||||
#include "../errno.h"
|
||||
#include "../vchroot_expand.h"
|
||||
#include "../bsdthread/per_thread_wd.h"
|
||||
#include "../network.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <emulation/conversion/errno.h>
|
||||
#include <emulation/darling/server/vchroot_userspace.h>
|
||||
#include <emulation/darling/tsd/perthread_wd.h>
|
||||
#include <emulation/xnu_syscall/shared/bsdthread/cancelable.h>
|
||||
|
||||
int sfamily_linux_to_bsd(int family)
|
||||
{
|
||||
switch (family)
|
||||
@ -141,4 +144,4 @@ int sockaddr_fixup_from_linux(struct sockaddr_fixup* out, const void* linux_sock
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
#include "duct_signals.h"
|
||||
#include "signal.h"
|
||||
|
||||
int signum_linux_to_bsd(int signum)
|
||||
{
|
@ -1,5 +1,6 @@
|
||||
#ifndef LINUX_DUCT_SIGNALS_H
|
||||
#define LINUX_DUCT_SIGNALS_H
|
||||
#ifndef DARLING_EMULATION_CONVERSION_SIGNAL_H
|
||||
#define DARLING_EMULATION_CONVERSION_SIGNAL_H
|
||||
|
||||
#define __sigset_t_defined
|
||||
#include <sys/signal.h>
|
||||
|
||||
@ -38,6 +39,7 @@
|
||||
#define LINUX_SIGPWR 30
|
||||
#define LINUX_SIGSYS 31
|
||||
#define LINUX_SIGUNUSED 31
|
||||
#define LINUX_SIGRTMIN 32
|
||||
#define LINUX_SA_NOCLDSTOP 0x00000001u
|
||||
#define LINUX_SA_NOCLDWAIT 0x00000002u
|
||||
#define LINUX_SA_SIGINFO 0x00000004u
|
||||
@ -60,5 +62,4 @@ int signum_bsd_to_linux(int signum);
|
||||
void sigset_linux_to_bsd(const linux_sigset_t* linux, sigset_t* bsd);
|
||||
void sigset_bsd_to_linux(const sigset_t* bsd, linux_sigset_t* linux);
|
||||
|
||||
#endif
|
||||
|
||||
#endif // DARLING_EMULATION_CONVERSION_SIGNAL_H
|
@ -0,0 +1,280 @@
|
||||
#include <emulation/common/simple.h>
|
||||
#include <emulation/conversion/signal/sigexc.h>
|
||||
|
||||
#define DEBUG_SIGEXC
|
||||
#ifdef DEBUG_SIGEXC
|
||||
#define kern_printf(...) __simple_kprintf(__VA_ARGS__)
|
||||
#else
|
||||
#define kern_printf(...)
|
||||
#endif
|
||||
|
||||
#define DUMPREG(regname) kern_printf("sigexc: " #regname ": 0x%llx\n", regs->regname);
|
||||
|
||||
// TODO: The code here is copied from both sigaction.c and sigexc.c, one thing that bothers me is that
|
||||
// there is a lot of unnecessary code duplication...
|
||||
|
||||
void ucontext_linux_to_bsd(const struct linux_ucontext* lc, struct bsd_ucontext* bc, struct bsd_mcontext* bm)
|
||||
{
|
||||
bc->uc_onstack = 1;
|
||||
bc->uc_mcsize = sizeof(struct bsd_mcontext);
|
||||
bc->uc_mcontext = bm;
|
||||
|
||||
sigset_linux_to_bsd(&lc->uc_sigmask, &bc->uc_sigmask);
|
||||
|
||||
bc->uc_stack.ss_flags = lc->uc_stack.ss_flags;
|
||||
bc->uc_stack.ss_size = lc->uc_stack.ss_size;
|
||||
bc->uc_stack.ss_sp = lc->uc_stack.ss_sp;
|
||||
|
||||
bm->es.trapno = lc->uc_mcontext.gregs.trapno;
|
||||
bm->es.cpu = 0;
|
||||
bm->es.err = lc->uc_mcontext.gregs.err;
|
||||
#ifdef __x86_64__
|
||||
bm->es.faultvaddr = lc->uc_mcontext.gregs.rip;
|
||||
#else
|
||||
bm->es.faultvaddr = lc->uc_mcontext.gregs.eip;
|
||||
#endif
|
||||
|
||||
#define copyreg(__name) bm->ss.__name = lc->uc_mcontext.gregs.__name
|
||||
|
||||
#ifdef __x86_64__
|
||||
copyreg(rax); copyreg(rbx); copyreg(rcx); copyreg(rdx); copyreg(rdi); copyreg(rsi);
|
||||
copyreg(rbp); copyreg(rsp); copyreg(r8); copyreg(r9); copyreg(r10);
|
||||
copyreg(r11); copyreg(r12); copyreg(r13); copyreg(r14); copyreg(r15); copyreg(rip);
|
||||
copyreg(cs); copyreg(fs); copyreg(gs);
|
||||
bm->ss.rflags = lc->uc_mcontext.gregs.efl;
|
||||
|
||||
#elif defined(__i386__)
|
||||
copyreg(eax); copyreg(ebx); copyreg(ecx); copyreg(edx); copyreg(edi); copyreg(esi);
|
||||
copyreg(ebp); copyreg(esp);
|
||||
copyreg(eip); copyreg(cs); copyreg(ds); copyreg(es); copyreg(fs); copyreg(gs);
|
||||
bm->ss.eflags = lc->uc_mcontext.gregs.efl;
|
||||
bm->ss.ss = 0;
|
||||
|
||||
#else
|
||||
#warning Missing code for current arch
|
||||
#endif
|
||||
|
||||
#undef copyreg
|
||||
}
|
||||
|
||||
void mcontext_bsd_to_linux(const struct bsd_mcontext* bm, struct linux_mcontext* lm)
|
||||
{
|
||||
#define copyreg(__name) lm->gregs.__name = bm->ss.__name
|
||||
|
||||
#ifdef __x86_64__
|
||||
copyreg(rax); copyreg(rbx); copyreg(rcx); copyreg(rdx); copyreg(rdi); copyreg(rsi);
|
||||
copyreg(rbp); copyreg(rsp); copyreg(r8); copyreg(r9); copyreg(r10);
|
||||
copyreg(r11); copyreg(r12); copyreg(r13); copyreg(r14); copyreg(r15); copyreg(rip);
|
||||
copyreg(cs); copyreg(fs); copyreg(gs);
|
||||
lm->gregs.efl = bm->ss.rflags;
|
||||
|
||||
#elif defined(__i386__)
|
||||
copyreg(eax); copyreg(ebx); copyreg(ecx); copyreg(edx); copyreg(edi); copyreg(esi);
|
||||
copyreg(ebp); copyreg(esp);
|
||||
copyreg(eip); copyreg(cs); copyreg(ds); copyreg(es); copyreg(fs); copyreg(gs);
|
||||
lm->gregs.efl = bm->ss.eflags;
|
||||
|
||||
#else
|
||||
#warning Missing code for current arch
|
||||
#endif
|
||||
|
||||
#undef copyreg
|
||||
}
|
||||
|
||||
#if defined(__x86_64__)
|
||||
void mcontext_to_thread_state(const struct linux_gregset* regs, x86_thread_state64_t* s)
|
||||
{
|
||||
s->__rax = regs->rax;
|
||||
s->__rbx = regs->rbx;
|
||||
s->__rcx = regs->rcx;
|
||||
s->__rdx = regs->rdx;
|
||||
s->__rdi = regs->rdi;
|
||||
s->__rsi = regs->rsi;
|
||||
s->__rbp = regs->rbp;
|
||||
s->__rsp = regs->rsp;
|
||||
s->__r8 = regs->r8;
|
||||
s->__r9 = regs->r9;
|
||||
s->__r10 = regs->r10;
|
||||
s->__r11 = regs->r11;
|
||||
s->__r12 = regs->r12;
|
||||
s->__r13 = regs->r13;
|
||||
s->__r14 = regs->r14;
|
||||
s->__r15 = regs->r15;
|
||||
s->__rip = regs->rip;
|
||||
s->__rflags = regs->efl;
|
||||
s->__cs = regs->cs;
|
||||
s->__fs = regs->fs;
|
||||
s->__gs = regs->gs;
|
||||
|
||||
kern_printf("sigexc: saving to kernel:\n");
|
||||
DUMPREG(rip);
|
||||
DUMPREG(efl);
|
||||
DUMPREG(rax);
|
||||
DUMPREG(rbx);
|
||||
DUMPREG(rcx);
|
||||
DUMPREG(rdx);
|
||||
DUMPREG(rdi);
|
||||
DUMPREG(rsi);
|
||||
DUMPREG(rbp);
|
||||
DUMPREG(rsp);
|
||||
}
|
||||
|
||||
void mcontext_to_float_state(const linux_fpregset_t fx, x86_float_state64_t* s)
|
||||
{
|
||||
// fpregs is NULL on WSL1. See https://github.com/microsoft/WSL/issues/2555.
|
||||
if (fx == NULL)
|
||||
{
|
||||
memset(s, 0, sizeof(x86_float_state64_t));
|
||||
return;
|
||||
}
|
||||
|
||||
kern_printf("sigexc: fcw out: 0x%x", fx->cwd);
|
||||
kern_printf("sigexc: xmm0 out: 0x%x", fx->_xmm[0].element[0]);
|
||||
*((uint16_t*)&s->__fpu_fcw) = fx->cwd;
|
||||
*((uint16_t*)&s->__fpu_fsw) = fx->swd;
|
||||
s->__fpu_ftw = fx->ftw;
|
||||
s->__fpu_fop = fx->fop;
|
||||
s->__fpu_ip = fx->rip;
|
||||
s->__fpu_cs = 0;
|
||||
s->__fpu_dp = fx->rdp;
|
||||
s->__fpu_ds = 0;
|
||||
s->__fpu_mxcsr = fx->mxcsr;
|
||||
s->__fpu_mxcsrmask = fx->mxcr_mask;
|
||||
|
||||
memcpy(&s->__fpu_stmm0, fx->_st, 128);
|
||||
memcpy(&s->__fpu_xmm0, fx->_xmm, 256);
|
||||
}
|
||||
|
||||
void thread_state_to_mcontext(const x86_thread_state64_t* s, struct linux_gregset* regs)
|
||||
{
|
||||
regs->rax = s->__rax;
|
||||
regs->rbx = s->__rbx;
|
||||
regs->rcx = s->__rcx;
|
||||
regs->rdx = s->__rdx;
|
||||
regs->rdi = s->__rdi;
|
||||
regs->rsi = s->__rsi;
|
||||
regs->rbp = s->__rbp;
|
||||
regs->rsp = s->__rsp;
|
||||
regs->r8 = s->__r8;
|
||||
regs->r9 = s->__r9;
|
||||
regs->r10 = s->__r10;
|
||||
regs->r11 = s->__r11;
|
||||
regs->r12 = s->__r12;
|
||||
regs->r13 = s->__r13;
|
||||
regs->r14 = s->__r14;
|
||||
regs->r15 = s->__r15;
|
||||
regs->rip = s->__rip;
|
||||
regs->efl = s->__rflags;
|
||||
regs->cs = s->__cs;
|
||||
regs->fs = s->__fs;
|
||||
regs->gs = s->__gs;
|
||||
|
||||
kern_printf("sigexc: restored from kernel:\n");
|
||||
DUMPREG(rip);
|
||||
DUMPREG(efl);
|
||||
DUMPREG(rax);
|
||||
DUMPREG(rbx);
|
||||
DUMPREG(rcx);
|
||||
DUMPREG(rdx);
|
||||
DUMPREG(rdi);
|
||||
DUMPREG(rsi);
|
||||
DUMPREG(rbp);
|
||||
DUMPREG(rsp);
|
||||
}
|
||||
|
||||
void float_state_to_mcontext(const x86_float_state64_t* s, linux_fpregset_t fx)
|
||||
{
|
||||
if (fx == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
fx->cwd = *((uint16_t*)&s->__fpu_fcw);
|
||||
fx->swd = *((uint16_t*)&s->__fpu_fsw);
|
||||
fx->ftw = s->__fpu_ftw;
|
||||
fx->fop = s->__fpu_fop;
|
||||
fx->rip = s->__fpu_ip;
|
||||
fx->rdp = s->__fpu_dp;
|
||||
fx->mxcsr = s->__fpu_mxcsr;
|
||||
fx->mxcr_mask = s->__fpu_mxcsrmask;
|
||||
|
||||
memcpy(fx->_st, &s->__fpu_stmm0, 128);
|
||||
memcpy(fx->_xmm, &s->__fpu_xmm0, 256);
|
||||
kern_printf("sigexc: fcw in: 0x%x", fx->cwd);
|
||||
kern_printf("sigexc: xmm0 in: 0x%x", fx->_xmm[0].element[0]);
|
||||
}
|
||||
|
||||
#elif defined(__i386__)
|
||||
void mcontext_to_thread_state(const struct linux_gregset* regs, x86_thread_state32_t* s)
|
||||
{
|
||||
s->__eax = regs->eax;
|
||||
s->__ebx = regs->ebx;
|
||||
s->__ecx = regs->ecx;
|
||||
s->__edx = regs->edx;
|
||||
s->__edi = regs->edi;
|
||||
s->__esi = regs->esi;
|
||||
s->__ebp = regs->ebp;
|
||||
s->__esp = regs->esp;
|
||||
s->__ss = regs->ss;
|
||||
s->__eflags = regs->efl;
|
||||
s->__eip = regs->eip;
|
||||
s->__cs = regs->cs;
|
||||
s->__ds = regs->ds;
|
||||
s->__es = regs->es;
|
||||
s->__fs = regs->fs;
|
||||
s->__gs = regs->gs;
|
||||
}
|
||||
|
||||
void mcontext_to_float_state(const linux_fpregset_t fx, x86_float_state32_t* s)
|
||||
{
|
||||
*((uint16_t*)&s->__fpu_fcw) = fx->cw;
|
||||
*((uint16_t*)&s->__fpu_fsw) = fx->sw;
|
||||
s->__fpu_ftw = fx->tag;
|
||||
s->__fpu_fop = 0;
|
||||
s->__fpu_ip = fx->ipoff;
|
||||
s->__fpu_cs = fx->cssel;
|
||||
s->__fpu_dp = fx->dataoff;
|
||||
s->__fpu_ds = fx->datasel;
|
||||
s->__fpu_mxcsr = fx->mxcsr;
|
||||
s->__fpu_mxcsrmask = 0;
|
||||
|
||||
memcpy(&s->__fpu_stmm0, fx->_st, 128);
|
||||
memcpy(&s->__fpu_xmm0, fx->_xmm, 128);
|
||||
memset(((char*) &s->__fpu_xmm0) + 128, 0, 128);
|
||||
}
|
||||
|
||||
void thread_state_to_mcontext(const x86_thread_state32_t* s, struct linux_gregset* regs)
|
||||
{
|
||||
regs->eax = s->__eax;
|
||||
regs->ebx = s->__ebx;
|
||||
regs->ecx = s->__ecx;
|
||||
regs->edx = s->__edx;
|
||||
regs->edi = s->__edi;
|
||||
regs->esi = s->__esi;
|
||||
regs->ebp = s->__ebp;
|
||||
regs->esp = s->__esp;
|
||||
regs->ss = s->__ss;
|
||||
regs->efl = s->__eflags;
|
||||
regs->eip = s->__eip;
|
||||
regs->cs = s->__cs;
|
||||
regs->ds = s->__ds;
|
||||
regs->es = s->__es;
|
||||
regs->fs = s->__fs;
|
||||
regs->gs = s->__gs;
|
||||
}
|
||||
|
||||
void float_state_to_mcontext(const x86_float_state32_t* s, linux_fpregset_t fx)
|
||||
{
|
||||
fx->cw = *((uint16_t*)&s->__fpu_fcw);
|
||||
fx->sw = *((uint16_t*)&s->__fpu_fsw);
|
||||
fx->tag = s->__fpu_ftw;
|
||||
fx->ipoff = s->__fpu_ip;
|
||||
fx->cssel = s->__fpu_cs;
|
||||
fx->dataoff = s->__fpu_dp;
|
||||
fx->datasel = s->__fpu_ds;
|
||||
fx->mxcsr = s->__fpu_mxcsr;
|
||||
|
||||
memcpy(fx->_st, &s->__fpu_stmm0, 128);
|
||||
memcpy(fx->_xmm, &s->__fpu_xmm0, 128);
|
||||
}
|
||||
#endif
|
@ -1,106 +1,14 @@
|
||||
#ifndef LINUX_SIGACTION_H
|
||||
#define LINUX_SIGACTION_H
|
||||
#include "duct_signals.h"
|
||||
#include "sigaltstack.h"
|
||||
#ifndef DARLING_EMULATION_CONVERSION_CONTEXT_H
|
||||
#define DARLING_EMULATION_CONVERSION_CONTEXT_H
|
||||
|
||||
#undef sa_sigaction
|
||||
#include <_libkernel_init.h>
|
||||
|
||||
#define BSD_SA_ONSTACK 0x0001
|
||||
#define BSD_SA_RESTART 0x0002
|
||||
#define BSD_SA_RESETHAND 0x0004
|
||||
#define BSD_SA_NOCLDSTOP 0x0008
|
||||
#define BSD_SA_NODEFER 0x0010
|
||||
#define BSD_SA_NOCLDWAIT 0x0020
|
||||
#define BSD_SA_SIGINFO 0x0040
|
||||
#include <emulation/conversion/signal.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/signal/sigaltstack.h>
|
||||
|
||||
#define LINUX_SA_NOCLDSTOP 0x00000001u
|
||||
#define LINUX_SA_NOCLDWAIT 0x00000002u
|
||||
#define LINUX_SA_SIGINFO 0x00000004u
|
||||
#define LINUX_SA_ONSTACK 0x08000000u
|
||||
#define LINUX_SA_RESTART 0x10000000u
|
||||
#define LINUX_SA_NODEFER 0x40000000u
|
||||
#define LINUX_SA_RESETHAND 0x80000000u
|
||||
|
||||
struct bsd_siginfo
|
||||
{
|
||||
int si_signo;
|
||||
int si_errno;
|
||||
int si_code;
|
||||
unsigned int si_pid;
|
||||
unsigned int si_uid;
|
||||
int si_status;
|
||||
void* si_addr;
|
||||
void* si_val_ptr;
|
||||
long si_band;
|
||||
unsigned long __pad[7];
|
||||
};
|
||||
|
||||
# define __SI_MAX_SIZE 128
|
||||
# if defined (__x86_64__)
|
||||
# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 4)
|
||||
# else
|
||||
# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3)
|
||||
# endif
|
||||
|
||||
struct linux_siginfo
|
||||
{
|
||||
int si_signo;
|
||||
int si_errno;
|
||||
int si_code;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
int si_pid;
|
||||
int si_uid;
|
||||
};
|
||||
void* si_addr;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
int _pad[__SI_PAD_SIZE];
|
||||
unsigned long si_value;
|
||||
};
|
||||
};
|
||||
|
||||
typedef void (bsd_sig_handler)(int, struct bsd_siginfo*, void*);
|
||||
typedef void (linux_sig_handler)(int, struct linux_siginfo*, void*);
|
||||
|
||||
#ifndef SIG_DFL
|
||||
#define SIG_DFL (bsd_sig_handler*)0
|
||||
#endif
|
||||
#ifndef SIG_IGN
|
||||
#define SIG_IGN (bsd_sig_handler*)1
|
||||
#endif
|
||||
#ifndef SIG_ERR
|
||||
#define SIG_ERR ((bsd_sig_handler*)-1l)
|
||||
#endif
|
||||
|
||||
struct bsd_sigaction
|
||||
{
|
||||
bsd_sig_handler* sa_sigaction;
|
||||
unsigned int sa_mask;
|
||||
int sa_flags;
|
||||
};
|
||||
|
||||
struct bsd___sigaction
|
||||
{
|
||||
bsd_sig_handler* sa_sigaction;
|
||||
void (*sa_tramp)(void*, int, int, struct bsd_siginfo*, void*);
|
||||
unsigned int sa_mask;
|
||||
int sa_flags;
|
||||
};
|
||||
|
||||
struct linux_sigaction
|
||||
{
|
||||
linux_sig_handler* sa_sigaction;
|
||||
int sa_flags;
|
||||
void (*sa_restorer)(void);
|
||||
linux_sigset_t sa_mask;
|
||||
};
|
||||
|
||||
long sys_sigaction(int signum, const struct bsd___sigaction* nsa, struct bsd_sigaction* osa);
|
||||
//
|
||||
// Linux Context
|
||||
//
|
||||
|
||||
#ifdef __x86_64__
|
||||
typedef struct _fpstate {
|
||||
@ -124,8 +32,7 @@ struct linux_gregset
|
||||
long long err, trapno, oldmask, cr2;
|
||||
};
|
||||
|
||||
#else // now the i386 version
|
||||
|
||||
#elif defined(__i386__) // now the i386 version
|
||||
typedef struct _fpstate {
|
||||
unsigned long cw, sw, tag, ipoff, cssel, dataoff, datasel;
|
||||
struct {
|
||||
@ -151,6 +58,9 @@ struct linux_gregset
|
||||
int trapno, err, eip, cs, efl, uesp;
|
||||
int ss;
|
||||
};
|
||||
|
||||
#else
|
||||
#error "Missing Register Set for Arch"
|
||||
#endif
|
||||
|
||||
struct linux_mcontext
|
||||
@ -175,6 +85,10 @@ struct linux_ucontext
|
||||
// linux_libc_fpstate fpregs_mem;
|
||||
};
|
||||
|
||||
//
|
||||
// BSD States
|
||||
//
|
||||
|
||||
struct bsd_exception_state
|
||||
{
|
||||
unsigned short trapno;
|
||||
@ -188,9 +102,11 @@ struct bsd_thread_state
|
||||
#ifdef __x86_64__
|
||||
long long rax, rbx, rcx, rdx, rdi, rsi, rbp, rsp, r8, r9, r10;
|
||||
long long r11, r12, r13, r14, r15, rip, rflags, cs, fs, gs;
|
||||
#else
|
||||
#elif defined(__i386__)
|
||||
int eax, ebx, ecx, edx, edi, esi, ebp, esp, ss, eflags;
|
||||
int eip, cs, ds, es, fs, gs;
|
||||
#else
|
||||
#error "Missing BSD Thread State for Arch"
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -216,10 +132,19 @@ struct bsd_ucontext
|
||||
struct bsd_mcontext* uc_mcontext;
|
||||
};
|
||||
|
||||
void handler_linux_to_bsd(int linux_signum, struct linux_siginfo* info, void* ctxt);
|
||||
extern bsd_sig_handler* sig_handlers[32];
|
||||
extern int sig_flags[32];
|
||||
extern unsigned int sig_masks[32];
|
||||
void ucontext_linux_to_bsd(const struct linux_ucontext* lc, struct bsd_ucontext* bc, struct bsd_mcontext* bm);
|
||||
void mcontext_bsd_to_linux(const struct bsd_mcontext* bm, struct linux_mcontext* lm);
|
||||
|
||||
#if defined(__x86_64__)
|
||||
void mcontext_to_thread_state(const struct linux_gregset* regs, x86_thread_state64_t* s);
|
||||
void mcontext_to_float_state(const linux_fpregset_t fx, x86_float_state64_t* s);
|
||||
void thread_state_to_mcontext(const x86_thread_state64_t* s, struct linux_gregset* regs);
|
||||
void float_state_to_mcontext(const x86_float_state64_t* s, linux_fpregset_t fx);
|
||||
#elif defined(__i386__)
|
||||
void mcontext_to_thread_state(const struct linux_gregset* regs, x86_thread_state32_t* s);
|
||||
void mcontext_to_float_state(const linux_fpregset_t fx, x86_float_state32_t* s);
|
||||
void thread_state_to_mcontext(const x86_thread_state32_t* s, struct linux_gregset* regs);
|
||||
void float_state_to_mcontext(const x86_float_state32_t* s, linux_fpregset_t fx);
|
||||
#endif
|
||||
|
||||
#endif // DARLING_EMULATION_CONVERSION_CONTEXT_H
|
@ -0,0 +1,125 @@
|
||||
#include "sigaction.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include <emulation/common/simple.h>
|
||||
#include <emulation/conversion/errno.h>
|
||||
#include <emulation/conversion/signal/context.h>
|
||||
#include <emulation/conversion/signal/sigexc.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/signal/sigaction.h>
|
||||
|
||||
#undef memset
|
||||
// extern void* memcpy(void* dest, const void* src, __SIZE_TYPE__ len);
|
||||
extern void* memset(void* dest, int v, __SIZE_TYPE__ len);
|
||||
|
||||
int sig_flags[32];
|
||||
unsigned int sig_masks[32];
|
||||
|
||||
|
||||
void handler_linux_to_bsd(int linux_signum, struct linux_siginfo* info, void* ctxt)
|
||||
{
|
||||
int bsd_signum;
|
||||
struct bsd_siginfo binfo;
|
||||
struct linux_ucontext* lc = (struct linux_ucontext*) ctxt;
|
||||
struct bsd_ucontext bc;
|
||||
|
||||
bsd_signum = signum_linux_to_bsd(linux_signum);
|
||||
|
||||
if (info)
|
||||
{
|
||||
memset(&binfo, 0, sizeof(binfo));
|
||||
binfo.si_signo = signum_linux_to_bsd(info->si_signo);
|
||||
binfo.si_errno = errno_linux_to_bsd(info->si_errno);
|
||||
binfo.si_code = info->si_code;
|
||||
binfo.si_pid = info->si_pid;
|
||||
binfo.si_uid = info->si_uid;
|
||||
binfo.si_addr = info->si_addr;
|
||||
binfo.si_val_ptr = (void*) info->si_value;
|
||||
|
||||
// TODO: The following exist on Linux, but it's a mess to extract them
|
||||
binfo.si_status = 0;
|
||||
binfo.si_band = 0;
|
||||
}
|
||||
|
||||
if (lc != NULL)
|
||||
{
|
||||
ucontext_linux_to_bsd(lc, &bc, (struct bsd_mcontext*) __builtin_alloca(sizeof(struct bsd_mcontext)));
|
||||
if (lc->uc_link != NULL)
|
||||
{
|
||||
struct bsd_ucontext* bc_link = (struct bsd_ucontext*) __builtin_alloca(sizeof(struct bsd_ucontext));
|
||||
|
||||
ucontext_linux_to_bsd(lc->uc_link, bc_link, (struct bsd_mcontext*) __builtin_alloca(sizeof(struct bsd_mcontext)));
|
||||
|
||||
bc.uc_link = bc_link;
|
||||
bc_link->uc_link = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// __simple_printf("Handling signal %d\n", linux_signum);
|
||||
|
||||
bsd_sig_handler* handler = sig_handlers[linux_signum];
|
||||
if (sig_flags[linux_signum] & LINUX_SA_RESETHAND)
|
||||
{
|
||||
switch (linux_signum)
|
||||
{
|
||||
case LINUX_SIGWINCH:
|
||||
case LINUX_SIGCHLD:
|
||||
case LINUX_SIGURG:
|
||||
sig_handlers[linux_signum] = (bsd_sig_handler*)BSD_SIG_IGN;
|
||||
break;
|
||||
default:
|
||||
sig_handlers[linux_signum] = NULL; // BSD_SIG_DFL
|
||||
}
|
||||
}
|
||||
|
||||
handler(bsd_signum, info ? &binfo : NULL, (lc != NULL) ? &bc : NULL);
|
||||
|
||||
if (lc != NULL)
|
||||
{
|
||||
mcontext_bsd_to_linux(bc.uc_mcontext, &lc->uc_mcontext);
|
||||
}
|
||||
|
||||
// __simple_printf("Signal handled\n");
|
||||
}
|
||||
|
||||
int sigflags_bsd_to_linux(int flags)
|
||||
{
|
||||
int linux_flags = LINUX_SA_SIGINFO;
|
||||
|
||||
if (flags & BSD_SA_NOCLDSTOP)
|
||||
linux_flags |= LINUX_SA_NOCLDSTOP;
|
||||
if (flags & BSD_SA_NOCLDWAIT)
|
||||
linux_flags |= LINUX_SA_NOCLDWAIT;
|
||||
if (flags & BSD_SA_ONSTACK)
|
||||
linux_flags |= LINUX_SA_ONSTACK;
|
||||
if (flags & BSD_SA_NODEFER)
|
||||
linux_flags |= LINUX_SA_NODEFER;
|
||||
if (flags & BSD_SA_RESETHAND)
|
||||
linux_flags |= LINUX_SA_RESETHAND;
|
||||
if (flags & BSD_SA_RESTART)
|
||||
linux_flags |= LINUX_SA_RESTART;
|
||||
|
||||
return linux_flags;
|
||||
}
|
||||
|
||||
int sigflags_linux_to_bsd(int flags)
|
||||
{
|
||||
int bsd_flags = 0;
|
||||
|
||||
if (flags & LINUX_SA_NOCLDSTOP)
|
||||
bsd_flags |= BSD_SA_NOCLDSTOP;
|
||||
if (flags & LINUX_SA_NOCLDWAIT)
|
||||
bsd_flags |= BSD_SA_NOCLDWAIT;
|
||||
if (flags & LINUX_SA_ONSTACK)
|
||||
bsd_flags |= BSD_SA_ONSTACK;
|
||||
if (flags & LINUX_SA_NODEFER)
|
||||
bsd_flags |= BSD_SA_NODEFER;
|
||||
if (flags & LINUX_SA_RESETHAND)
|
||||
bsd_flags |= BSD_SA_RESETHAND;
|
||||
if (flags & LINUX_SA_RESTART)
|
||||
bsd_flags |= BSD_SA_RESTART;
|
||||
|
||||
return bsd_flags;
|
||||
}
|
||||
|
@ -0,0 +1,72 @@
|
||||
#ifndef DARLING_EMULATION_CONVERSION_SIGACTION_H
|
||||
#define DARLING_EMULATION_CONVERSION_SIGACTION_H
|
||||
|
||||
#include <emulation/conversion/signal.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/signal/sigaltstack.h>
|
||||
|
||||
#undef sa_sigaction
|
||||
|
||||
#define BSD_SA_ONSTACK 0x0001
|
||||
#define BSD_SA_RESTART 0x0002
|
||||
#define BSD_SA_RESETHAND 0x0004
|
||||
#define BSD_SA_NOCLDSTOP 0x0008
|
||||
#define BSD_SA_NODEFER 0x0010
|
||||
#define BSD_SA_NOCLDWAIT 0x0020
|
||||
#define BSD_SA_SIGINFO 0x0040
|
||||
|
||||
#define LINUX_SA_NOCLDSTOP 0x00000001u
|
||||
#define LINUX_SA_NOCLDWAIT 0x00000002u
|
||||
#define LINUX_SA_SIGINFO 0x00000004u
|
||||
#define LINUX_SA_ONSTACK 0x08000000u
|
||||
#define LINUX_SA_RESTART 0x10000000u
|
||||
#define LINUX_SA_NODEFER 0x40000000u
|
||||
#define LINUX_SA_RESETHAND 0x80000000u
|
||||
|
||||
# define __SI_MAX_SIZE 128
|
||||
# if defined (__x86_64__)
|
||||
# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 4)
|
||||
# else
|
||||
# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3)
|
||||
# endif
|
||||
|
||||
struct linux_siginfo
|
||||
{
|
||||
int si_signo;
|
||||
int si_errno;
|
||||
int si_code;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
int si_pid;
|
||||
int si_uid;
|
||||
};
|
||||
void* si_addr;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
int _pad[__SI_PAD_SIZE];
|
||||
unsigned long si_value;
|
||||
};
|
||||
};
|
||||
|
||||
typedef void (linux_sig_handler)(int, struct linux_siginfo*, void*);
|
||||
|
||||
struct linux_sigaction
|
||||
{
|
||||
linux_sig_handler* sa_sigaction;
|
||||
int sa_flags;
|
||||
void (*sa_restorer)(void);
|
||||
linux_sigset_t sa_mask;
|
||||
};
|
||||
|
||||
void handler_linux_to_bsd(int linux_signum, struct linux_siginfo* info, void* ctxt);
|
||||
|
||||
extern int sig_flags[32];
|
||||
extern unsigned int sig_masks[32];
|
||||
|
||||
extern int sigflags_bsd_to_linux(int flags);
|
||||
extern int sigflags_linux_to_bsd(int flags);
|
||||
|
||||
#endif // DARLING_EMULATION_CONVERSION_SIGACTION_H
|
@ -0,0 +1,305 @@
|
||||
#include "sigexc.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/signal.h>
|
||||
|
||||
// #include "../mach/lkm.h"
|
||||
#include <_libkernel_init.h>
|
||||
|
||||
#include <darlingserver/rpc.h>
|
||||
|
||||
#include <emulation/conversion/signal/sigaction.h>
|
||||
|
||||
#include <emulation/common/simple.h>
|
||||
#include <emulation/linux_api/linux_syscall.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/mman/mman.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/signal/sigaction.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/signal/sigaltstack.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/unistd/exit.h>
|
||||
|
||||
// Support for Darwin debugging.
|
||||
// Unlike other Unix-like systems, macOS doesn't use wait() to handle events in the debugged process.
|
||||
// wait() only receives termination events.
|
||||
|
||||
static void sigexc_fake_suspend(struct linux_ucontext* ctxt);
|
||||
extern void linux_sig_restorer(void);
|
||||
extern int getpid(void);
|
||||
|
||||
extern _libkernel_functions_t _libkernel_functions;
|
||||
|
||||
void darling_sigexc_uninstall(void);
|
||||
void sigrt_handler(int signum, struct linux_siginfo* info, struct linux_ucontext* ctxt);
|
||||
|
||||
#ifndef SIGALTSTACK_GUARD
|
||||
#define SIGALTSTACK_GUARD 1
|
||||
#endif
|
||||
|
||||
#if SIGALTSTACK_GUARD
|
||||
// align it on a page boundary so mprotect works properly
|
||||
char sigexc_altstack[SIGEXC_STACK_SIZE + 4096ULL] __attribute__((aligned(4096)));
|
||||
#else
|
||||
char sigexc_altstack[SIGEXC_STACK_SIZE];
|
||||
#endif
|
||||
size_t default_sigaltstack_size = SIGEXC_STACK_SIZE;
|
||||
|
||||
static void state_from_kernel(struct linux_ucontext* ctxt, const void* tstate, const void* fstate);
|
||||
static void state_to_kernel(struct linux_ucontext* ctxt, void* tstate, void* fstate);
|
||||
|
||||
#define DEBUG_SIGEXC
|
||||
#ifdef DEBUG_SIGEXC
|
||||
#define kern_printf(...) __simple_kprintf(__VA_ARGS__)
|
||||
#else
|
||||
#define kern_printf(...)
|
||||
#endif
|
||||
|
||||
#define DUMPREG(regname) kern_printf("sigexc: " #regname ": 0x%llx\n", regs->regname);
|
||||
|
||||
static void dump_gregs(const struct linux_gregset* regs)
|
||||
{
|
||||
unsigned long long* p = (unsigned long long*) regs;
|
||||
for (int i = 0; i < 23; i++)
|
||||
{
|
||||
kern_printf("sigexc: gregs 0x%llx\n", p[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void handle_rt_signal(int signum)
|
||||
{
|
||||
int rv;
|
||||
struct linux_sigaction sa;
|
||||
|
||||
sa.sa_sigaction = (linux_sig_handler*)sigrt_handler;
|
||||
sa.sa_mask = (1ull << (SIGNAL_SIGEXC_SUSPEND-1)) | (1ull << (signum-1));
|
||||
sa.sa_flags = LINUX_SA_RESTORER | LINUX_SA_SIGINFO | LINUX_SA_RESTART | LINUX_SA_ONSTACK;
|
||||
sa.sa_restorer = linux_sig_restorer;
|
||||
|
||||
rv = LINUX_SYSCALL(__NR_rt_sigaction, signum,
|
||||
&sa, NULL,
|
||||
sizeof(sa.sa_mask));
|
||||
|
||||
//char buf[128];
|
||||
//__simple_sprintf(xyzbuf, "Setting handler for RT signal %d: %d", signum, rv);
|
||||
//external/lkm_call(0x1028, buf);
|
||||
}
|
||||
|
||||
void sigrt_handler(int signum, struct linux_siginfo* info, struct linux_ucontext* ctxt)
|
||||
{
|
||||
int status = dserver_rpc_interrupt_enter();
|
||||
|
||||
if (status != 0) {
|
||||
__simple_printf("*** dserver_rpc_interrupt_enter failed with code %d ***\n", status);
|
||||
__simple_abort();
|
||||
}
|
||||
|
||||
if (signum == SIGNAL_SIGEXC_SUSPEND) {
|
||||
#if defined(__x86_64__)
|
||||
x86_thread_state64_t tstate;
|
||||
x86_float_state64_t fstate;
|
||||
#elif defined(__i386__)
|
||||
x86_thread_state32_t tstate;
|
||||
x86_float_state32_t fstate;
|
||||
#endif
|
||||
|
||||
kern_printf("sigexc: sigrt_handler SUSPEND\n");
|
||||
|
||||
thread_t thread = mach_thread_self();
|
||||
state_to_kernel(ctxt, &tstate, &fstate);
|
||||
|
||||
int ret = dserver_rpc_thread_suspended(&tstate, &fstate);
|
||||
if (ret < 0) {
|
||||
__simple_printf("dserver_rpc_thread_suspended failed internally: %d", ret);
|
||||
__simple_abort();
|
||||
}
|
||||
|
||||
state_from_kernel(ctxt, &tstate, &fstate);
|
||||
} else if (signum == SIGNAL_S2C) {
|
||||
__simple_kprintf("sigexc: sigrt_handler S2C");
|
||||
|
||||
int ret = dserver_rpc_s2c_perform();
|
||||
if (ret < 0) {
|
||||
__simple_printf("dserver_rpc_s2c_perform failed internally: %d", ret);
|
||||
__simple_abort();
|
||||
}
|
||||
} else {
|
||||
__simple_printf("Unknown/unrecognized real-time signal: %d", signum);
|
||||
}
|
||||
|
||||
status = dserver_rpc_interrupt_exit();
|
||||
|
||||
if (status != 0) {
|
||||
__simple_printf("*** dserver_rpc_interrupt_exit failed with code %d ***\n", status);
|
||||
__simple_abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void state_to_kernel(struct linux_ucontext* ctxt, void* tstate, void* fstate)
|
||||
{
|
||||
#if defined(__x86_64__)
|
||||
|
||||
dump_gregs(&ctxt->uc_mcontext.gregs);
|
||||
mcontext_to_thread_state(&ctxt->uc_mcontext.gregs, (x86_thread_state64_t*) tstate);
|
||||
mcontext_to_float_state(ctxt->uc_mcontext.fpregs, (x86_float_state64_t*) fstate);
|
||||
|
||||
#elif defined(__i386__)
|
||||
mcontext_to_thread_state(&ctxt->uc_mcontext.gregs, (x86_thread_state32_t*) tstate);
|
||||
mcontext_to_float_state(ctxt->uc_mcontext.fpregs, (x86_float_state32_t*) fstate);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void state_from_kernel(struct linux_ucontext* ctxt, const void* tstate, const void* fstate)
|
||||
{
|
||||
#if defined(__x86_64__)
|
||||
|
||||
thread_state_to_mcontext((const x86_thread_state64_t*) tstate, &ctxt->uc_mcontext.gregs);
|
||||
float_state_to_mcontext((const x86_float_state64_t*) fstate, ctxt->uc_mcontext.fpregs);
|
||||
|
||||
dump_gregs(&ctxt->uc_mcontext.gregs);
|
||||
|
||||
#elif defined(__i386__)
|
||||
thread_state_to_mcontext((const x86_thread_state32_t*) tstate, &ctxt->uc_mcontext.gregs);
|
||||
float_state_to_mcontext((const x86_float_state32_t*) fstate, ctxt->uc_mcontext.fpregs);
|
||||
#endif
|
||||
}
|
||||
|
||||
void sigexc_handler(int linux_signum, struct linux_siginfo* info, struct linux_ucontext* ctxt)
|
||||
{
|
||||
int status = dserver_rpc_interrupt_enter();
|
||||
|
||||
if (status != 0) {
|
||||
__simple_printf("*** dserver_rpc_interrupt_enter failed with code %d ***\n", status);
|
||||
__simple_abort();
|
||||
}
|
||||
|
||||
kern_printf("sigexc_handler(%d, %p, %p)\n", linux_signum, info, ctxt);
|
||||
|
||||
|
||||
if (linux_signum == LINUX_SIGCONT)
|
||||
goto out;
|
||||
|
||||
int bsd_signum = signum_linux_to_bsd(linux_signum);
|
||||
if (bsd_signum <= 0)
|
||||
{
|
||||
kern_printf("sigexc: Unmapped signal!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
kern_printf("sigexc: have RIP 0x%llx\n", ctxt->uc_mcontext.gregs.rip);
|
||||
#endif
|
||||
|
||||
thread_t thread = mach_thread_self();
|
||||
|
||||
#if defined(__x86_64__)
|
||||
x86_thread_state64_t tstate;
|
||||
x86_float_state64_t fstate;
|
||||
#elif defined(__i386__)
|
||||
x86_thread_state32_t tstate;
|
||||
x86_float_state32_t fstate;
|
||||
#endif
|
||||
|
||||
state_to_kernel(ctxt, &tstate, &fstate);
|
||||
int ret = dserver_rpc_sigprocess(bsd_signum, linux_signum, info->si_pid, info->si_code, info->si_addr, &tstate, &fstate, &bsd_signum);
|
||||
if (ret < 0) {
|
||||
__simple_printf("sigprocess failed internally while processing Linux signal %d: %d", linux_signum, ret);
|
||||
__simple_abort();
|
||||
}
|
||||
state_from_kernel(ctxt, &tstate, &fstate);
|
||||
|
||||
if (!bsd_signum)
|
||||
{
|
||||
kern_printf("sigexc: drop signal\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
linux_signum = signum_bsd_to_linux(bsd_signum);
|
||||
|
||||
if (sig_handlers[linux_signum] != BSD_SIG_IGN)
|
||||
{
|
||||
if (sig_handlers[linux_signum])
|
||||
{
|
||||
kern_printf("sigexc: will forward signal to app handler (%p)\n", sig_handlers[linux_signum]);
|
||||
|
||||
// Update the signal mask to what the application actually wanted
|
||||
linux_sigset_t set = sig_masks[linux_signum];
|
||||
|
||||
// Keep the current signal blocked, which is the default behavior
|
||||
if (!(sig_flags[linux_signum] & LINUX_SA_NODEFER))
|
||||
set |= (1ull << (linux_signum-1));
|
||||
|
||||
LINUX_SYSCALL(__NR_rt_sigprocmask, 2 /* LINUX_SIG_SETMASK */,
|
||||
&set, NULL, sizeof(linux_sigset_t));
|
||||
|
||||
handler_linux_to_bsd(linux_signum, info, ctxt);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bsd_signum == SIGTSTP || bsd_signum == SIGSTOP)
|
||||
{
|
||||
kern_printf("sigexc: emulating SIGTSTP/SIGSTOP\n");
|
||||
LINUX_SYSCALL(__NR_kill, 0, LINUX_SIGSTOP);
|
||||
}
|
||||
else
|
||||
{
|
||||
kern_printf("sigexc: emulating default signal effects\n");
|
||||
// Set handler to BSD_SIG_DFL
|
||||
struct linux_sigaction sa;
|
||||
sa.sa_sigaction = (linux_sig_handler*) NULL; // BSD_SIG_DFL
|
||||
sa.sa_mask = 0x7fffffff; // all other standard Unix signals should be blocked while the handler is run
|
||||
sa.sa_flags = LINUX_SA_RESTORER | LINUX_SA_SIGINFO | LINUX_SA_RESTART | LINUX_SA_ONSTACK;
|
||||
sa.sa_restorer = linux_sig_restorer;
|
||||
|
||||
LINUX_SYSCALL(__NR_rt_sigaction, linux_signum,
|
||||
&sa, NULL,
|
||||
sizeof(sa.sa_mask));
|
||||
|
||||
// Resend signal to self
|
||||
LINUX_SYSCALL(__NR_kill, 0, linux_signum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kern_printf("sigexc: handler (%d) returning\n", linux_signum);
|
||||
|
||||
out:
|
||||
status = dserver_rpc_interrupt_exit();
|
||||
|
||||
if (status != 0) {
|
||||
__simple_printf("*** dserver_rpc_interrupt_exit failed with code %d ***\n", status);
|
||||
__simple_abort();
|
||||
}
|
||||
}
|
||||
|
||||
void sigexc_thread_setup(void)
|
||||
{
|
||||
struct bsd_stack newstack = {
|
||||
.ss_size = default_sigaltstack_size,
|
||||
.ss_flags = 0
|
||||
};
|
||||
|
||||
#if SIGALTSTACK_GUARD
|
||||
newstack.ss_sp = (void*) sys_mmap(NULL, newstack.ss_size + 4096, PROT_READ | PROT_WRITE,
|
||||
MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
sys_mprotect(newstack.ss_sp, 4096, PROT_NONE);
|
||||
newstack.ss_sp = (char*)newstack.ss_sp + 4096;
|
||||
#else
|
||||
newstack.ss_sp = (void*) sys_mmap(NULL, newstack.ss_size, PROT_READ | PROT_WRITE,
|
||||
MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
#endif
|
||||
sys_sigaltstack(&newstack, NULL);
|
||||
}
|
||||
|
||||
void sigexc_thread_exit(void)
|
||||
{
|
||||
struct bsd_stack oldstack;
|
||||
sys_sigaltstack(NULL, &oldstack);
|
||||
|
||||
#if SIGALTSTACK_GUARD
|
||||
sys_munmap((char*)oldstack.ss_sp - 4096, oldstack.ss_size + 4096);
|
||||
#else
|
||||
sys_munmap(oldstack.ss_sp, oldstack.ss_size);
|
||||
#endif
|
||||
}
|
||||
|
@ -1,22 +1,25 @@
|
||||
#ifndef _SIGEXC_H
|
||||
#define _SIGEXC_H
|
||||
#ifndef DARLING_EMULATION_CONVERSION_SIGEXC_H
|
||||
#define DARLING_EMULATION_CONVERSION_SIGEXC_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "rtsig.h"
|
||||
#include "sigaction.h"
|
||||
|
||||
#include <emulation/conversion/signal/context.h>
|
||||
#include <emulation/conversion/signal/sigaction.h>
|
||||
|
||||
#define SIGEXC_STACK_SIZE (48ULL * 1024ULL)
|
||||
|
||||
// NOTE: Keep these definitions up to date with lkm/darling/binfmt.c!
|
||||
// Uses one of the below magic values to toggle the debugging state
|
||||
#define SIGNAL_SIGEXC_SUSPEND LINUX_SIGRTMIN
|
||||
#define SIGNAL_S2C (LINUX_SIGRTMIN + 1)
|
||||
|
||||
void sigexc_setup(void);
|
||||
void handle_rt_signal(int signum);
|
||||
extern char sigexc_altstack[];
|
||||
|
||||
// for PT_SIGEXC to handle this operation synchronously
|
||||
void darling_sigexc_self(void);
|
||||
void sigexc_handler(int linux_signum, struct linux_siginfo* info, struct linux_ucontext* ctxt);
|
||||
|
||||
void sigexc_thread_setup(void);
|
||||
void sigexc_thread_exit(void);
|
||||
|
||||
#endif
|
||||
|
||||
#endif // DARLING_EMULATION_CONVERSION_SIGEXC_H
|
@ -1,11 +1,13 @@
|
||||
// This needs be included first, so that "stat.h" can `#undef st_atime` (and more)
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "stat.h"
|
||||
|
||||
// This is needed so stat is not stat64
|
||||
#define _DARWIN_NO_64_BIT_INODE
|
||||
|
||||
// NOTE: in this case, platform-include/sys/stat.h is used
|
||||
#include <sys/stat.h>
|
||||
#include "common.h"
|
||||
#include "../unistd/getuid.h"
|
||||
#include "../unistd/getgid.h"
|
||||
#include <emulation/xnu_syscall/bsd/impl/unistd/getgid.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/unistd/getuid.h>
|
||||
|
||||
void stat_linux_to_bsd(const struct linux_stat* lstat, struct stat* stat)
|
||||
{
|
@ -1,5 +1,5 @@
|
||||
#ifndef LINUX_STAT_COMMON_H
|
||||
#define LINUX_STAT_COMMON_H
|
||||
#ifndef DARLING_EMULATION_CONVERSION_STAT_H
|
||||
#define DARLING_EMULATION_CONVERSION_STAT_H
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
@ -149,5 +149,4 @@ void stat_linux_to_bsd64(const struct linux_stat* lstat, struct stat64* stat);
|
||||
void statfs_linux_to_bsd(const struct linux_statfs64* lstat, struct bsd_statfs* stat);
|
||||
void statfs_linux_to_bsd64(const struct linux_statfs64* lstat, struct bsd_statfs64* stat);
|
||||
|
||||
#endif
|
||||
|
||||
#endif // DARLING_EMULATION_CONVERSION_STAT_H
|
@ -1,5 +1,5 @@
|
||||
#ifndef EXT_UNAME_H
|
||||
#define EXT_UNAME_H
|
||||
#ifndef DARLING_EMULATION_CONVERSION_UTSNAME_H
|
||||
#define DARLING_EMULATION_CONVERSION_UTSNAME_H
|
||||
|
||||
#define LINUX_UTSNAME_LENGTH 65
|
||||
|
||||
@ -15,5 +15,4 @@ struct linux_utsname
|
||||
|
||||
int __linux_uname(struct linux_utsname* p);
|
||||
|
||||
#endif
|
||||
|
||||
#endif // DARLING_EMULATION_CONVERSION_UTSNAME_H
|
@ -0,0 +1,29 @@
|
||||
project(emulation_darling)
|
||||
|
||||
set(darling_sources
|
||||
legacy_lkm.c
|
||||
weak_stubs.c
|
||||
|
||||
c_api/elfcalls_wrapper.c
|
||||
c_api/for_libkqueue.c
|
||||
|
||||
init/mach_driver.c
|
||||
init/sigexc.c
|
||||
|
||||
server/dserver-rpc-defs.c
|
||||
server/vchroot_userspace.c
|
||||
|
||||
${CMAKE_BINARY_DIR}/src/external/darlingserver/src/rpc.c
|
||||
)
|
||||
|
||||
set_source_files_properties(${CMAKE_BINARY_DIR}/src/external/darlingserver/src/rpc.c PROPERTIES
|
||||
GENERATED TRUE
|
||||
COMPILE_FLAGS "-include ${CMAKE_CURRENT_SOURCE_DIR}/server/dserver-rpc-defs.h"
|
||||
)
|
||||
|
||||
add_darling_object_library(emulation_darling ${darling_sources})
|
||||
make_fat(emulation_darling)
|
||||
|
||||
add_darling_object_library(emulation_darling_dyld ${darling_sources})
|
||||
set_target_properties(emulation_darling_dyld PROPERTIES COMPILE_FLAGS "-ffunction-sections -DVARIANT_DYLD")
|
||||
make_fat(emulation_darling_dyld)
|
@ -1,7 +1,9 @@
|
||||
#include "elfcalls_wrapper.h"
|
||||
|
||||
// #include <dlfcn.h>
|
||||
|
||||
#include <elfcalls.h>
|
||||
#include <dlfcn.h>
|
||||
#include "simple.h"
|
||||
#include <emulation/common/simple.h>
|
||||
|
||||
extern struct elf_calls* _elfcalls;
|
||||
|
@ -1,11 +1,11 @@
|
||||
#ifndef _ELFCALLS_WRAPPER_H
|
||||
#define _ELFCALLS_WRAPPER_H
|
||||
#ifndef DARLING_EMULATION_DARLING_ELFCALLS_WRAPPER_H
|
||||
#define DARLING_EMULATION_DARLING_ELFCALLS_WRAPPER_H
|
||||
|
||||
#include <darling/emulation/common/base.h>
|
||||
|
||||
#include <elfcalls.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
CPP_EXTERN_C_BEGIN
|
||||
|
||||
// Native library loading
|
||||
void* native_dlopen(const char* path);
|
||||
@ -37,9 +37,6 @@ int __dserver_get_process_lifetime_pipe(void);
|
||||
int __dserver_process_lifetime_pipe_refresh(void);
|
||||
void __dserver_close_process_lifetime_pipe(int fd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
CPP_EXTERN_C_END
|
||||
|
||||
#endif // DARLING_EMULATION_DARLING_ELFCALLS_WRAPPER_H
|
@ -1,7 +1,8 @@
|
||||
#include "for-libkqueue.h"
|
||||
#include "for_libkqueue.h"
|
||||
|
||||
#include <darlingserver/rpc.h>
|
||||
#include <linux-syscalls/linux.h>
|
||||
#include "../errno.h"
|
||||
#include <emulation/linux_api/linux_syscall.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/unistd/close.h>
|
||||
|
||||
int _dserver_rpc_kqchan_mach_port_open_4libkqueue(uint32_t port_name, void* receive_buffer, uint64_t receive_buffer_size, uint64_t saved_filter_flags, int* out_socket) {
|
||||
return dserver_rpc_kqchan_mach_port_open(port_name, receive_buffer, receive_buffer_size, saved_filter_flags, out_socket);
|
||||
@ -20,3 +21,10 @@ int _dup_4libkqueue(int fd) {
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
// Special variant for libkqueue to avoid recursion into kqueue_close()/kqueue_closed_fd()
|
||||
__attribute__((visibility("default")))
|
||||
long __close_for_kqueue(int fd)
|
||||
{
|
||||
return close_internal(fd);
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
#ifndef _DARLING_EMULATION_FOR_LIBKQUEUE_H_
|
||||
#define _DARLING_EMULATION_FOR_LIBKQUEUE_H_
|
||||
#ifndef DARLING_EMULATION_DARLING_FOR_LIBKQUEUE_H
|
||||
#define DARLING_EMULATION_DARLING_FOR_LIBKQUEUE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <darling/emulation/base.h>
|
||||
#include <darling/emulation/common/base.h>
|
||||
|
||||
VISIBLE
|
||||
int _dserver_rpc_kqchan_mach_port_open_4libkqueue(uint32_t port_name, void* receive_buffer, uint64_t receive_buffer_size, uint64_t saved_filter_flags, int* out_socket);
|
||||
@ -14,4 +14,4 @@ int _dserver_rpc_kqchan_proc_open_4libkqueue(int32_t pid, uint32_t flags, int* o
|
||||
VISIBLE
|
||||
int _dup_4libkqueue(int fd);
|
||||
|
||||
#endif // _DARLING_EMULATION_FOR_LIBKQUEUE_H_
|
||||
#endif // DARLING_EMULATION_DARLING_FOR_LIBKQUEUE_H
|
@ -1,16 +1,18 @@
|
||||
#include "lkm.h"
|
||||
#include "../signal/sigexc.h"
|
||||
#include "../base.h"
|
||||
#include "../linux-syscalls/linux.h"
|
||||
#include "mach_driver.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/resource.h>
|
||||
#include "../../../libsyscall/wrappers/_libkernel_init.h"
|
||||
#include "../simple.h"
|
||||
#include "../misc/ioctl.h"
|
||||
#include <elfcalls.h>
|
||||
#include "../guarded/table.h"
|
||||
#include "../elfcalls_wrapper.h"
|
||||
#include <_libkernel_init.h>
|
||||
|
||||
// #include "../misc/ioctl.h"
|
||||
|
||||
#include <emulation/common/simple.h>
|
||||
#include <emulation/conversion/signal/sigexc.h>
|
||||
#include <emulation/darling/c_api/elfcalls_wrapper.h>
|
||||
#include <emulation/linux_api/linux_syscall.h>
|
||||
#include <emulation/xnu_syscall/shared/guarded/table.h>
|
||||
|
||||
extern int sys_open(const char*, int, int);
|
||||
extern int close_internal(int);
|
||||
@ -95,20 +97,6 @@ void mach_driver_init(const char** applep)
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((visibility("default")))
|
||||
int lkm_call(int call_nr, void* arg)
|
||||
{
|
||||
__simple_printf("Something called the old LKM API (nr = %d)\n", call_nr);
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
__attribute__((visibility("default")))
|
||||
int lkm_call_raw(int call_nr, void* arg)
|
||||
{
|
||||
__simple_printf("Something called the old LKM API (nr = %d)\n", call_nr);
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
VISIBLE
|
||||
int mach_driver_get_fd(void) {
|
||||
return __dserver_per_thread_socket();
|
@ -0,0 +1,8 @@
|
||||
#ifndef DARLING_EMULATION_DARLING_MACH_DRIVER_INIT_H
|
||||
#define DARLING_EMULATION_DARLING_MACH_DRIVER_INIT_H
|
||||
|
||||
void mach_driver_init(const char** applep);
|
||||
int mach_driver_get_fd(void);
|
||||
|
||||
#endif // DARLING_EMULATION_DARLING_MACH_DRIVER_INIT_H
|
||||
|
115
darling/src/libsystem_kernel/emulation/darling/init/sigexc.c
Normal file
115
darling/src/libsystem_kernel/emulation/darling/init/sigexc.c
Normal file
@ -0,0 +1,115 @@
|
||||
#include "sigexc.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <darlingserver/rpc.h>
|
||||
|
||||
#include <emulation/common/simple.h>
|
||||
#include <emulation/conversion/signal.h>
|
||||
#include <emulation/conversion/signal/sigaction.h>
|
||||
#include <emulation/conversion/signal/sigexc.h>
|
||||
#include <emulation/linux_api/linux_syscall.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/signal/kill.h>
|
||||
|
||||
#define DEBUG_SIGEXC
|
||||
#ifdef DEBUG_SIGEXC
|
||||
#define kern_printf(...) __simple_kprintf(__VA_ARGS__)
|
||||
#else
|
||||
#define kern_printf(...)
|
||||
#endif
|
||||
|
||||
extern void linux_sig_restorer(void);
|
||||
|
||||
void sigexc_setup1(void);
|
||||
void sigexc_setup2(void);
|
||||
|
||||
void sigexc_setup(void)
|
||||
{
|
||||
darling_sigexc_self();
|
||||
sigexc_setup1();
|
||||
sigexc_setup2();
|
||||
|
||||
#ifdef VARIANT_DYLD
|
||||
bool started_suspended;
|
||||
int code = dserver_rpc_started_suspended(&started_suspended);
|
||||
if (code < 0) {
|
||||
__simple_printf("Failed to get started_suspended status: %d\n", code);
|
||||
__simple_abort();
|
||||
}
|
||||
if (started_suspended) {
|
||||
kern_printf("sigexc: start_suspended -> suspending (ret to %p)\n", __builtin_return_address(0));
|
||||
task_suspend(mach_task_self());
|
||||
kern_printf("sigexc: start_suspended -> wokenup (ret to %p)\n", __builtin_return_address(0));
|
||||
} else {
|
||||
int32_t tracer;
|
||||
code = dserver_rpc_get_tracer(&tracer);
|
||||
if (code < 0) {
|
||||
__simple_printf("Failed to get tracer status: %d\n", code);
|
||||
__simple_abort();
|
||||
}
|
||||
if (tracer != 0) {
|
||||
kern_printf("sigexc: already traced -> SIGTRAP\n");
|
||||
sys_kill(0, SIGTRAP, 0);
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static volatile bool am_i_ptraced = false;
|
||||
|
||||
void darling_sigexc_self(void)
|
||||
{
|
||||
am_i_ptraced = true;
|
||||
|
||||
__simple_kprintf("darling_sigexc_self()\n");
|
||||
// Make sigexc_handler the handler for all signals in the process
|
||||
for (int i = 1; i <= 31; i++)
|
||||
{
|
||||
if (i == LINUX_SIGSTOP || i == LINUX_SIGKILL || i == LINUX_SIGCHLD)
|
||||
continue;
|
||||
|
||||
struct linux_sigaction sa;
|
||||
sa.sa_sigaction = (linux_sig_handler*) sigexc_handler;
|
||||
sa.sa_mask = 0x7fffffff; // all other standard Unix signals should be blocked while the handler is run
|
||||
sa.sa_mask |= (1ull << (SIGNAL_SIGEXC_SUSPEND-1));
|
||||
sa.sa_flags = LINUX_SA_RESTORER | LINUX_SA_SIGINFO | LINUX_SA_RESTART | LINUX_SA_ONSTACK;
|
||||
sa.sa_restorer = linux_sig_restorer;
|
||||
|
||||
LINUX_SYSCALL(__NR_rt_sigaction, i,
|
||||
&sa, NULL,
|
||||
sizeof(sa.sa_mask));
|
||||
}
|
||||
|
||||
#if SIGALTSTACK_GUARD
|
||||
sys_mprotect(sigexc_altstack, 4096, PROT_NONE);
|
||||
#endif
|
||||
|
||||
struct bsd_stack newstack = {
|
||||
#if SIGALTSTACK_GUARD
|
||||
.ss_sp = sigexc_altstack + 4096,
|
||||
#else
|
||||
.ss_sp = sigexc_altstack,
|
||||
#endif
|
||||
.ss_size = SIGEXC_STACK_SIZE,
|
||||
.ss_flags = 0
|
||||
};
|
||||
sys_sigaltstack(&newstack, NULL);
|
||||
}
|
||||
|
||||
void sigexc_setup1(void)
|
||||
{
|
||||
handle_rt_signal(SIGNAL_SIGEXC_SUSPEND);
|
||||
handle_rt_signal(SIGNAL_S2C);
|
||||
}
|
||||
|
||||
void sigexc_setup2(void)
|
||||
{
|
||||
linux_sigset_t set;
|
||||
set = (1ull << (SIGNAL_SIGEXC_SUSPEND-1));
|
||||
set |= (1ull << (SIGNAL_S2C-1));
|
||||
|
||||
LINUX_SYSCALL(__NR_rt_sigprocmask, 1 /* LINUX_SIG_UNBLOCK */,
|
||||
&set, NULL, sizeof(linux_sigset_t));
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
#ifndef DARLING_EMULATION_DARLING_SIGEXC_H
|
||||
#define DARLING_EMULATION_DARLING_SIGEXC_H
|
||||
|
||||
void sigexc_setup(void);
|
||||
void darling_sigexc_self(void);
|
||||
|
||||
#endif // DARLING_EMULATION_DARLING_SIGEXC_H
|
17
darling/src/libsystem_kernel/emulation/darling/legacy_lkm.c
Normal file
17
darling/src/libsystem_kernel/emulation/darling/legacy_lkm.c
Normal file
@ -0,0 +1,17 @@
|
||||
#include "legacy_lkm.h"
|
||||
|
||||
#include <emulation/common/simple.h>
|
||||
|
||||
__attribute__((visibility("default")))
|
||||
int lkm_call(int call_nr, void* arg)
|
||||
{
|
||||
__simple_printf("Something called the old LKM API (nr = %d)\n", call_nr);
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
__attribute__((visibility("default")))
|
||||
int lkm_call_raw(int call_nr, void* arg)
|
||||
{
|
||||
__simple_printf("Something called the old LKM API (nr = %d)\n", call_nr);
|
||||
__builtin_unreachable();
|
||||
}
|
@ -1,7 +1,5 @@
|
||||
#ifndef _LKM_H
|
||||
#define _LKM_H
|
||||
|
||||
#include <os/tsd.h>
|
||||
#ifndef DARLING_EMULATION_DARLING_LEGACY_LKM_H
|
||||
#define DARLING_EMULATION_DARLING_LEGACY_LKM_H
|
||||
|
||||
#define DARLING_MACH_API_BASE 0x1000
|
||||
enum { NR_get_api_version = DARLING_MACH_API_BASE,
|
||||
@ -90,10 +88,7 @@ enum { NR_get_api_version = DARLING_MACH_API_BASE,
|
||||
};
|
||||
#define DARLING_MACH_API_COUNT (DARLING_MACH_API_ALMOST_COUNT - DARLING_MACH_API_BASE)
|
||||
|
||||
void mach_driver_init(const char** applep);
|
||||
int lkm_call(int call_nr, void* arg);
|
||||
int lkm_call_raw(int call_nr, void* arg); // w/o errno translation
|
||||
int mach_driver_get_fd(void);
|
||||
|
||||
#endif
|
||||
int lkm_call_raw(int call_nr, void* arg);
|
||||
|
||||
#endif // DARLING_EMULATION_DARLING_LEGACY_LKM_H
|
@ -1,11 +1,12 @@
|
||||
#include "dserver-rpc-defs.h"
|
||||
#include <darlingserver/rpc.h>
|
||||
|
||||
#include <libsimple/lock.h>
|
||||
#include "../fcntl/open.h"
|
||||
|
||||
#include "../unistd/pipe.h"
|
||||
#include "../unistd/read.h"
|
||||
#include <darlingserver/rpc.h>
|
||||
|
||||
#include <emulation/xnu_syscall/bsd/impl/fcntl/open.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/unistd/pipe.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/unistd/read.h>
|
||||
|
||||
#ifndef DSERVER_RPC_USE_LOG_FILE
|
||||
// CHANGE TO 0 BEFORE COMMITTING
|
@ -1,21 +1,23 @@
|
||||
#include "../network/recvmsg.h"
|
||||
#include "../network/sendmsg.h"
|
||||
#include "../network/getsockopt.h"
|
||||
#include "../network/sendto.h"
|
||||
#ifndef DARLING_EMULATION_DARLING_DSERVER_RPC_DEFS_H
|
||||
#define DARLING_EMULATION_DARLING_DSERVER_RPC_DEFS_H
|
||||
|
||||
#include <rtsig.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/_types/_iovec_t.h>
|
||||
#include <linux-syscalls/linux.h>
|
||||
#include "../base.h"
|
||||
#include "../duct_errno.h"
|
||||
#include "../mach/lkm.h"
|
||||
#include "../elfcalls_wrapper.h"
|
||||
#include "../simple.h"
|
||||
#include "../signal/sigprocmask.h"
|
||||
#include "../unistd/close.h"
|
||||
|
||||
#include <darlingserver/rpc-supplement.h>
|
||||
|
||||
#include <rtsig.h>
|
||||
#include <emulation/common/simple.h>
|
||||
#include <emulation/darling/c_api/elfcalls_wrapper.h>
|
||||
#include <emulation/darling/init/mach_driver.h>
|
||||
#include <emulation/linux_api/linux_syscall.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/network/getsockopt.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/network/recvmsg.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/network/sendmsg.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/network/sendto.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/signal/sigprocmask.h>
|
||||
#include <emulation/xnu_syscall/bsd/impl/unistd/close.h>
|
||||
|
||||
|
||||
#ifndef DSERVER_RPC_HOOKS_ARCHITECTURE
|
||||
#define DSERVER_RPC_HOOKS_ARCHITECTURE 1
|
||||
@ -294,3 +296,5 @@ static void dserver_rpc_hooks_atomic_end(dserver_rpc_hooks_atomic_save_t* atomic
|
||||
|
||||
extern void __dserver_rpc_hooks_push_reply(int socket, const dserver_rpc_hooks_msghdr_t* reply, size_t size);
|
||||
#define dserver_rpc_hooks_push_reply __dserver_rpc_hooks_push_reply
|
||||
|
||||
#endif // DARLING_EMULATION_DARLING_DSERVER_RPC_DEFS_H
|
@ -1,5 +1,5 @@
|
||||
|
||||
#include "vchroot_expand.h"
|
||||
#include "vchroot_userspace.h"
|
||||
#ifdef TEST
|
||||
# include <unistd.h>
|
||||
# include <sys/stat.h>
|
||||
@ -26,17 +26,15 @@
|
||||
# define linux_dirent64 dirent
|
||||
typedef struct stat stat_t;
|
||||
#else
|
||||
# include "base.h"
|
||||
# include <mach/lkm.h>
|
||||
# include <linux-syscalls/linux.h>
|
||||
# include <fcntl/open.h>
|
||||
# include "simple.h"
|
||||
# include <stdbool.h>
|
||||
# include "errno.h"
|
||||
# include "duct_errno.h"
|
||||
# include "stat/common.h"
|
||||
# include "dirent/getdirentries.h"
|
||||
# include "common_at.h"
|
||||
// # include <mach/lkm.h>
|
||||
# include <emulation/common/simple.h>
|
||||
# include <emulation/conversion/at.h>
|
||||
# include <emulation/conversion/errno.h>
|
||||
# include <emulation/conversion/stat.h>
|
||||
# include <emulation/linux_api/linux_syscall.h>
|
||||
# include <emulation/xnu_syscall/bsd/impl/dirent/getdirentries.h>
|
||||
# include <emulation/xnu_syscall/bsd/impl/fcntl/open.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <darlingserver/rpc.h>
|
@ -1,5 +1,5 @@
|
||||
#ifndef _VCHROOT_EXPAND_H
|
||||
#define _VCHROOT_EXPAND_H
|
||||
#ifndef DARLING_EMULATION_DARLING_VCHROOT_USERSPACE_H
|
||||
#define DARLING_EMULATION_DARLING_VCHROOT_USERSPACE_H
|
||||
|
||||
#define VCHROOT_FOLLOW 1
|
||||
struct vchroot_expand_args
|
||||
@ -25,5 +25,4 @@ int vchroot_expand(struct vchroot_expand_args* args);
|
||||
int vchroot_unexpand(struct vchroot_unexpand_args* args);
|
||||
int vchroot_fdpath(struct vchroot_fdpath_args* args);
|
||||
|
||||
#endif
|
||||
|
||||
#endif // DARLING_EMULATION_DARLING_VCHROOT_USERSPACE_H
|
@ -1,9 +1,11 @@
|
||||
#ifndef _PER_THREAD_WD_H
|
||||
#define _PER_THREAD_WD_H
|
||||
#include "../common_at.h"
|
||||
#include "../tsd.h"
|
||||
#ifndef DARLING_EMULATION_DARLING_PERTHREAD_WD_H
|
||||
#define DARLING_EMULATION_DARLING_PERTHREAD_WD_H
|
||||
|
||||
// We use the following static TSD keys (see `../tsd.h` and `pthread/tsd_private.h`):
|
||||
#include <darling/emulation/darling/tsd/tsd.h>
|
||||
|
||||
#include <darling/emulation/conversion/at.h>
|
||||
|
||||
// We use the following static TSD keys (see `tsd.h` and `pthread/tsd_private.h`):
|
||||
// __PTK_DARLING_PERTHREAD_WD_IS_SET = is __PTK_DARLING_PERTHREAD_WD_FD set? (Because 0 could be a valid FD, theoretically.)
|
||||
// __PTK_DARLING_PERTHREAD_WD_FD = per thread wd file descriptor
|
||||
//
|
||||
@ -26,5 +28,4 @@ static inline void set_perthread_wd(int fd)
|
||||
_pthread_setspecific_direct(__PTK_DARLING_PERTHREAD_WD_FD, fd);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // DARLING_EMULATION_DARLING_PERTHREAD_WD_H
|
@ -1,5 +1,5 @@
|
||||
#ifndef _DARLING_EMULATION_TSD_H_
|
||||
#define _DARLING_EMULATION_TSD_H_
|
||||
#ifndef DARLING_EMULATION_DARLING_TSD_H
|
||||
#define DARLING_EMULATION_DARLING_TSD_H
|
||||
|
||||
#include <pthread/tsd_private.h>
|
||||
|
||||
@ -8,4 +8,4 @@
|
||||
#define __PTK_DARLING_PERTHREAD_WD_FD __PTK_DARLING_KEY2
|
||||
// other __PTK_DARLING_KEYs are currently unused
|
||||
|
||||
#endif // _DARLING_EMULATION_TSD_H_
|
||||
#endif // DARLING_EMULATION_DARLING_TSD_H
|
21
darling/src/libsystem_kernel/emulation/darling/weak_stubs.c
Normal file
21
darling/src/libsystem_kernel/emulation/darling/weak_stubs.c
Normal file
@ -0,0 +1,21 @@
|
||||
#include <emulation/common/base.h>
|
||||
|
||||
#include <os/lock.h>
|
||||
|
||||
WEAK
|
||||
VISIBLE
|
||||
int kqueue_close(int kq) { return 0; }
|
||||
|
||||
WEAK
|
||||
VISIBLE
|
||||
void kqueue_closed_fd(int fd) {}
|
||||
|
||||
WEAK
|
||||
VISIBLE
|
||||
void kqueue_dup(int oldfd, int newfd) { }
|
||||
|
||||
WEAK
|
||||
void os_unfair_lock_unlock(os_unfair_lock_t lock) {}
|
||||
|
||||
WEAK
|
||||
void os_unfair_lock_lock(os_unfair_lock_t lock) {}
|
@ -0,0 +1 @@
|
||||
../../../common/base.h
|
@ -0,0 +1 @@
|
||||
../../../common/simple.h
|
@ -0,0 +1 @@
|
||||
../../../conversion/at.h
|
@ -0,0 +1 @@
|
||||
../../../conversion/errno.h
|
@ -0,0 +1 @@
|
||||
../../../../conversion/mman/mman.h
|
@ -0,0 +1 @@
|
||||
../../../conversion/network.h
|
@ -0,0 +1 @@
|
||||
../../../conversion/signal.h
|
@ -0,0 +1 @@
|
||||
../../../../conversion/signal/sigaction.h
|
@ -0,0 +1 @@
|
||||
../../../../conversion/signal/sigexc.h
|
@ -0,0 +1 @@
|
||||
../../../conversion/stat.h
|
@ -0,0 +1 @@
|
||||
../../../../darling/c_api/elfcalls_wrapper.h
|
@ -0,0 +1 @@
|
||||
../../../../darling/c_api/for_libkqueue.h
|
@ -0,0 +1 @@
|
||||
../../../../darling/init/mach_driver.h
|
@ -0,0 +1 @@
|
||||
../../../../darling/init/sigexc.h
|
@ -0,0 +1 @@
|
||||
../../../darling/legacy_lkm.h
|
@ -0,0 +1 @@
|
||||
../../../../darling/server/dserver-rpc-defs.h
|
@ -0,0 +1 @@
|
||||
../../../../darling/server/vchroot_userspace.h
|
@ -0,0 +1 @@
|
||||
../../../../darling/tsd/perthread_wd.h
|
@ -0,0 +1 @@
|
||||
../../../../darling/tsd/tsd.h
|
@ -0,0 +1 @@
|
||||
../../../../linux_api/c_api/clock.h
|
@ -0,0 +1 @@
|
||||
../../../../linux_api/c_api/fanotify.h
|
@ -0,0 +1 @@
|
||||
../../../../linux_api/c_api/file_handle.h
|
@ -0,0 +1 @@
|
||||
../../../../linux_api/c_api/futex.h
|
@ -0,0 +1 @@
|
||||
../../../../linux_api/c_api/ioctl.h
|
@ -0,0 +1 @@
|
||||
../../../../linux_api/c_api/mremap.h
|
@ -0,0 +1 @@
|
||||
../../../../linux_api/c_api/nanosleep.h
|
@ -0,0 +1 @@
|
||||
../../../../linux_api/c_api/sched_yield.h
|
@ -0,0 +1 @@
|
||||
../../../../../linux_api/c_api/sys/epoll.h
|
@ -0,0 +1 @@
|
||||
../../../../../linux_api/c_api/sys/eventfd.h
|
@ -0,0 +1 @@
|
||||
../../../../../linux_api/c_api/sys/inotify.h
|
@ -0,0 +1 @@
|
||||
../../../../../linux_api/c_api/sys/signalfd.h
|
@ -0,0 +1 @@
|
||||
../../../../../linux_api/c_api/sys/timerfd.h
|
@ -0,0 +1 @@
|
||||
../../../linux_api/linux_syscall.h
|
@ -0,0 +1 @@
|
||||
../../../../linux_api/sysnum/linux_sysnum.h
|
@ -0,0 +1 @@
|
||||
../../../../linux_api/sysnum/linux_sysnum_arm64.h
|
@ -0,0 +1 @@
|
||||
../../../../linux_api/sysnum/linux_sysnum_x86.h
|
@ -0,0 +1 @@
|
||||
../../../../linux_api/sysnum/linux_sysnum_x86_64.h
|
@ -0,0 +1 @@
|
||||
../../../../xnu_syscall/bsd/bsd_syscall.h
|
@ -0,0 +1 @@
|
||||
../../../../xnu_syscall/bsd/bsd_syscall_table.h
|
@ -0,0 +1 @@
|
||||
../../../../../../xnu_syscall/bsd/impl/bsdthread/bsdthread_create.h
|
@ -0,0 +1 @@
|
||||
../../../../../../xnu_syscall/bsd/impl/bsdthread/bsdthread_register.h
|
@ -0,0 +1 @@
|
||||
../../../../../../xnu_syscall/bsd/impl/bsdthread/pthread_canceled.h
|
@ -0,0 +1 @@
|
||||
../../../../../../xnu_syscall/bsd/impl/dirent/getdirentries.h
|
@ -0,0 +1 @@
|
||||
../../../../../../xnu_syscall/bsd/impl/fcntl/fcntl.h
|
@ -0,0 +1 @@
|
||||
../../../../../../xnu_syscall/bsd/impl/fcntl/open.h
|
@ -0,0 +1 @@
|
||||
../../../../../../xnu_syscall/bsd/impl/fcntl/openat.h
|
@ -0,0 +1 @@
|
||||
../../../../../../xnu_syscall/bsd/impl/misc/abort_with_payload.h
|
@ -0,0 +1 @@
|
||||
../../../../../../xnu_syscall/bsd/impl/misc/syscall.h
|
@ -0,0 +1 @@
|
||||
../../../../../../xnu_syscall/bsd/impl/misc/thread_selfid.h
|
@ -0,0 +1 @@
|
||||
../../../../../../xnu_syscall/bsd/impl/mman/mman.h
|
@ -0,0 +1 @@
|
||||
../../../../../../xnu_syscall/bsd/impl/network/getsockopt.h
|
@ -0,0 +1 @@
|
||||
../../../../../../xnu_syscall/bsd/impl/network/recvmsg.h
|
@ -0,0 +1 @@
|
||||
../../../../../../xnu_syscall/bsd/impl/network/sendmsg.h
|
@ -0,0 +1 @@
|
||||
../../../../../../xnu_syscall/bsd/impl/network/sendto.h
|
@ -0,0 +1 @@
|
||||
../../../../../../xnu_syscall/bsd/impl/signal/kill.h
|
@ -0,0 +1 @@
|
||||
../../../../../../xnu_syscall/bsd/impl/signal/sigaltstack.h
|
@ -0,0 +1 @@
|
||||
../../../../../../xnu_syscall/bsd/impl/signal/sigprocmask.h
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user