Revert the rest of the COMPAT_MODE changes (back to hrev52003.)

This reverts commit 458e758f37.
This reverts commit ce5eb94a82.
This reverts commit aac8d4c317.
This reverts commit c70cba914a.
This reverts commit 2ffbe7aaca
This reverts commit c6e120e2d2.
This commit is contained in:
Augustin Cavalier
2018-06-15 00:20:56 -04:00
parent 513403d420
commit 4f7b9506fd
20 changed files with 122 additions and 1721 deletions
-6
View File
@@ -31,12 +31,6 @@ bool arch_on_signal_stack(Thread *thread);
status_t arch_setup_signal_frame(Thread *thread, struct sigaction *action,
struct signal_frame_data *signalFrameData);
int64 arch_restore_signal_frame(struct signal_frame_data* signalFrameData);
#ifdef _COMPAT_MODE
status_t arch_setup_compat_signal_frame(Thread *thread,
struct sigaction *action, struct compat_signal_frame_data *signalFrameData);
int64 arch_restore_compat_signal_frame(
struct compat_signal_frame_data* signalFrameData);
#endif
void arch_store_fork_frame(struct arch_fork_arg *arg);
void arch_restore_fork_frame(struct arch_fork_arg *arg);
@@ -51,30 +51,6 @@ arch_thread_set_current_thread(Thread* t)
}
#ifdef _COMPAT_MODE
static inline void
arch_thread_set_ds(unsigned short ds)
{
asm volatile("mov %0, %%ds" : : "r" (ds) : "memory");
}
static inline void
arch_thread_set_es(unsigned short es)
{
asm volatile("mov %0, %%es" : : "r" (es) : "memory");
}
// override empty macro
#undef arch_syscall_64_bit_return_value
void arch_syscall_64_bit_return_value(void);
#endif // _COMPAT_MODE
#else // __x86_64__
-277
View File
@@ -1,277 +0,0 @@
/*
* Copyright 2018, Haiku Inc. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_COMPAT_OS_H
#define _KERNEL_COMPAT_OS_H
typedef struct {
bigtime_t boot_time; /* time of boot (usecs since 1/1/1970) */
uint32 cpu_count; /* number of cpus */
uint64 max_pages; /* total # of accessible pages */
uint64 used_pages; /* # of accessible pages in use */
uint64 cached_pages;
uint64 block_cache_pages;
uint64 ignored_pages; /* # of ignored/inaccessible pages */
uint64 needed_memory;
uint64 free_memory;
uint64 max_swap_pages;
uint64 free_swap_pages;
uint32 page_faults; /* # of page faults */
uint32 max_sems;
uint32 used_sems;
uint32 max_ports;
uint32 used_ports;
uint32 max_threads;
uint32 used_threads;
uint32 max_teams;
uint32 used_teams;
char kernel_name[B_FILE_NAME_LENGTH];
char kernel_build_date[B_OS_NAME_LENGTH];
char kernel_build_time[B_OS_NAME_LENGTH];
int64 kernel_version;
uint32 abi; /* the system API */
} _PACKED compat_system_info;
static_assert(sizeof(compat_system_info) == 0x1c4,
"size of compat_system_info mismatch");
inline status_t
copy_ref_var_to_user(system_info &info, system_info* userInfo)
{
if (!IS_USER_ADDRESS(userInfo))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
compat_system_info compat_info;
compat_info.boot_time = info.boot_time;
compat_info.cpu_count = info.cpu_count;
compat_info.max_pages = info.max_pages;
compat_info.used_pages = info.used_pages;
compat_info.cached_pages = info.cached_pages;
compat_info.block_cache_pages = info.block_cache_pages;
compat_info.ignored_pages = info.ignored_pages;
compat_info.needed_memory = info.needed_memory;
compat_info.free_memory = info.free_memory;
compat_info.needed_memory = info.needed_memory;
compat_info.max_swap_pages = info.max_swap_pages;
compat_info.free_swap_pages = info.free_swap_pages;
compat_info.max_sems = info.max_sems;
compat_info.used_sems = info.used_sems;
compat_info.max_ports = info.max_ports;
compat_info.used_ports = info.used_ports;
compat_info.max_threads = info.max_threads;
compat_info.used_threads = info.used_threads;
compat_info.max_teams = info.max_teams;
compat_info.used_teams = info.used_teams;
strlcpy(compat_info.kernel_name, info.kernel_name, B_FILE_NAME_LENGTH);
strlcpy(compat_info.kernel_build_date, info.kernel_build_date,
B_OS_NAME_LENGTH);
strlcpy(compat_info.kernel_build_time, info.kernel_build_time,
B_OS_NAME_LENGTH);
compat_info.kernel_version = info.kernel_version;
compat_info.abi = info.abi;
if (user_memcpy(userInfo, &compat_info, sizeof(compat_info)) < B_OK)
return B_BAD_ADDRESS;
} else if (user_memcpy(userInfo, &info, sizeof(system_info)) < B_OK)
return B_BAD_ADDRESS;
return B_OK;
}
#define compat_size_t uint32
#define compat_ptr_t uint32
typedef struct compat_area_info {
area_id area;
char name[B_OS_NAME_LENGTH];
compat_size_t size;
uint32 lock;
uint32 protection;
team_id team;
uint32 ram_size;
uint32 copy_count;
uint32 in_count;
uint32 out_count;
compat_ptr_t address;
} _PACKED compat_area_info;
static_assert(sizeof(compat_area_info) == 0x48,
"size of compat_area_info mismatch");
inline status_t
copy_ref_var_to_user(area_info &info, area_info* userInfo)
{
if (!IS_USER_ADDRESS(userInfo))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
compat_area_info compatInfo;
compatInfo.area = info.area;
strlcpy(compatInfo.name, info.name, B_OS_NAME_LENGTH);
compatInfo.size = info.size;
compatInfo.lock = info.lock;
compatInfo.protection = info.protection;
compatInfo.team = info.team;
compatInfo.ram_size = info.ram_size;
compatInfo.copy_count = info.copy_count;
compatInfo.in_count = info.in_count;
compatInfo.out_count = info.out_count;
compatInfo.address = (compat_ptr_t)(addr_t)info.address;
if (user_memcpy(userInfo, &compatInfo, sizeof(compatInfo)) < B_OK)
return B_BAD_ADDRESS;
} else if (user_memcpy(userInfo, &info, sizeof(info)) < B_OK) {
return B_BAD_ADDRESS;
}
return B_OK;
}
typedef struct {
thread_id thread;
team_id team;
char name[B_OS_NAME_LENGTH];
thread_state state;
int32 priority;
sem_id sem;
bigtime_t user_time;
bigtime_t kernel_time;
uint32 stack_base;
uint32 stack_end;
} _PACKED compat_thread_info;
static_assert(sizeof(compat_thread_info) == 76,
"size of compat_thread_info mismatch");
inline status_t
copy_ref_var_to_user(void* &addr, void** userAddr)
{
if (!IS_USER_ADDRESS(userAddr))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
compat_ptr_t compatAddr = (uint32)(addr_t)addr;
if (user_memcpy(userAddr, &compatAddr, sizeof(compatAddr)) < B_OK)
return B_BAD_ADDRESS;
} else if (user_memcpy(userAddr, &addr, sizeof(addr)) < B_OK) {
return B_BAD_ADDRESS;
}
return B_OK;
}
inline status_t
copy_ref_var_from_user(void** userAddr, void* &addr)
{
if (!IS_USER_ADDRESS(userAddr))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
compat_ptr_t compatAddr;
if (user_memcpy(&compatAddr, userAddr, sizeof(compatAddr)) < B_OK)
return B_BAD_ADDRESS;
addr = (void*)(addr_t)compatAddr;
} else if (user_memcpy(&addr, userAddr, sizeof(addr)) < B_OK) {
return B_BAD_ADDRESS;
}
return B_OK;
}
inline status_t
copy_ref_var_to_user(addr_t &addr, addr_t* userAddr)
{
if (!IS_USER_ADDRESS(userAddr))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
uint32 compatAddr = (uint32)addr;
if (user_memcpy(userAddr, &compatAddr, sizeof(compatAddr)) < B_OK)
return B_BAD_ADDRESS;
} else if (user_memcpy(userAddr, &addr, sizeof(addr)) < B_OK) {
return B_BAD_ADDRESS;
}
return B_OK;
}
inline status_t
copy_ref_var_from_user(addr_t* userAddr, addr_t &addr)
{
if (!IS_USER_ADDRESS(userAddr))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
uint32 compatAddr;
if (user_memcpy(&compatAddr, userAddr, sizeof(compatAddr)) < B_OK)
return B_BAD_ADDRESS;
addr = (addr_t)compatAddr;
} else if (user_memcpy(&addr, userAddr, sizeof(addr)) < B_OK) {
return B_BAD_ADDRESS;
}
return B_OK;
}
inline status_t
copy_ref_var_to_user(ssize_t &size, ssize_t* userSize)
{
if (!IS_USER_ADDRESS(userSize))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
int32 compatSize = (int32)size;
if (user_memcpy(userSize, &compatSize, sizeof(compatSize)) < B_OK)
return B_BAD_ADDRESS;
} else if (user_memcpy(userSize, &size, sizeof(size)) < B_OK) {
return B_BAD_ADDRESS;
}
return B_OK;
}
inline status_t
copy_ref_var_from_user(ssize_t* userSize, ssize_t &size)
{
if (!IS_USER_ADDRESS(userSize))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
int32 compatSize;
if (user_memcpy(&compatSize, userSize, sizeof(compatSize)) < B_OK)
return B_BAD_ADDRESS;
size = (ssize_t)compatSize;
} else if (user_memcpy(&size, userSize, sizeof(size)) < B_OK) {
return B_BAD_ADDRESS;
}
return B_OK;
}
#endif // _KERNEL_COMPAT_OS_H
@@ -1,113 +0,0 @@
/*
* Copyright 2018, Haiku Inc. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_COMPAT_ARCH_SIGNAL_H
#define _KERNEL_COMPAT_ARCH_SIGNAL_H
typedef struct packed_fp_stack {
unsigned char st0[10];
unsigned char st1[10];
unsigned char st2[10];
unsigned char st3[10];
unsigned char st4[10];
unsigned char st5[10];
unsigned char st6[10];
unsigned char st7[10];
} packed_fp_stack;
typedef struct packed_mmx_regs {
unsigned char mm0[10];
unsigned char mm1[10];
unsigned char mm2[10];
unsigned char mm3[10];
unsigned char mm4[10];
unsigned char mm5[10];
unsigned char mm6[10];
unsigned char mm7[10];
} packed_mmx_regs;
typedef struct xmmx_regs {
unsigned char xmm0[16];
unsigned char xmm1[16];
unsigned char xmm2[16];
unsigned char xmm3[16];
unsigned char xmm4[16];
unsigned char xmm5[16];
unsigned char xmm6[16];
unsigned char xmm7[16];
} xmmx_regs;
typedef struct compat_stack_t {
uint32 ss_sp;
uint32 ss_size;
int ss_flags;
} compat_stack_t;
typedef struct compat_old_extended_regs {
unsigned short fp_control;
unsigned short _reserved1;
unsigned short fp_status;
unsigned short _reserved2;
unsigned short fp_tag;
unsigned short _reserved3;
uint32 fp_eip;
unsigned short fp_cs;
unsigned short fp_opcode;
uint32 fp_datap;
unsigned short fp_ds;
unsigned short _reserved4;
union {
packed_fp_stack fp;
packed_mmx_regs mmx;
} fp_mmx;
} compat_old_extended_regs;
typedef struct compat_new_extended_regs {
unsigned short fp_control;
unsigned short fp_status;
unsigned short fp_tag;
unsigned short fp_opcode;
uint32 fp_eip;
unsigned short fp_cs;
unsigned short res_14_15;
uint32 fp_datap;
unsigned short fp_ds;
unsigned short _reserved_22_23;
uint32 mxcsr;
uint32 _reserved_28_31;
union {
fp_stack fp;
mmx_regs mmx;
} fp_mmx;
xmmx_regs xmmx;
unsigned char _reserved_288_511[224];
} compat_new_extended_regs;
typedef struct compat_extended_regs {
union {
compat_old_extended_regs old_format;
compat_new_extended_regs new_format;
} state;
uint32 format;
} compat_extended_regs;
struct compat_vregs {
uint32 eip;
uint32 eflags;
uint32 eax;
uint32 ecx;
uint32 edx;
uint32 esp;
uint32 ebp;
uint32 _reserved_1;
compat_extended_regs xregs;
uint32 edi;
uint32 esi;
uint32 ebx;
};
#endif // _KERNEL_COMPAT_ARCH_SIGNAL_H
@@ -1,74 +0,0 @@
/*
* Copyright 2018, Haiku Inc. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_COMPAT_FCNTL_H
#define _KERNEL_COMPAT_FCNTL_H
#include <fcntl.h>
struct compat_flock {
short l_type;
short l_whence;
off_t l_start;
off_t l_len;
pid_t l_pid;
} _PACKED;
static_assert(sizeof(struct compat_flock) == 24,
"size of compat_flock mismatch");
inline status_t
copy_ref_var_from_user(struct flock* userFlock, struct flock &flock)
{
if (!IS_USER_ADDRESS(userFlock))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
compat_flock compat_flock;
if (user_memcpy(&compat_flock, userFlock, sizeof(compat_flock)) < B_OK)
return B_BAD_ADDRESS;
flock.l_type = compat_flock.l_type;
flock.l_whence = compat_flock.l_whence;
flock.l_start = compat_flock.l_start;
flock.l_len = compat_flock.l_len;
flock.l_pid = compat_flock.l_pid;
} else {
if (user_memcpy(&flock, userFlock, sizeof(struct flock)) < B_OK)
return B_BAD_ADDRESS;
}
return B_OK;
}
inline status_t
copy_ref_var_to_user(struct flock &flock, struct flock* userFlock)
{
if (!IS_USER_ADDRESS(userFlock))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
compat_flock compat_flock;
compat_flock.l_type = flock.l_type;
compat_flock.l_whence = flock.l_whence;
compat_flock.l_start = flock.l_start;
compat_flock.l_len = flock.l_len;
compat_flock.l_pid = flock.l_pid;
if (user_memcpy(userFlock, &compat_flock, sizeof(compat_flock)) < B_OK)
return B_BAD_ADDRESS;
} else {
if (user_memcpy(userFlock, &flock, sizeof(flock)) < B_OK)
return B_BAD_ADDRESS;
}
return B_OK;
}
#endif // _KERNEL_COMPAT_FCNTL_H
@@ -1,44 +0,0 @@
/*
* Copyright 2018, Haiku Inc. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_COMPAT_FS_ATTR_H
#define _KERNEL_COMPAT_FS_ATTR_H
#include <fs_attr.h>
struct compat_attr_info {
uint32 type;
off_t size;
} _PACKED;
static_assert(sizeof(compat_attr_info) == 12,
"size of compat_attr_info mismatch");
inline status_t
copy_ref_var_to_user(attr_info &info, attr_info* userInfo)
{
if (!IS_USER_ADDRESS(userInfo))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
compat_attr_info compat_info;
compat_info.type = info.type;
compat_info.size = info.size;
if (user_memcpy(userInfo, &compat_info, sizeof(compat_info)) < B_OK)
return B_BAD_ADDRESS;
} else {
if (user_memcpy(userInfo, &info, sizeof(info)) < B_OK)
return B_BAD_ADDRESS;
}
return B_OK;
}
#endif // _KERNEL_COMPAT_FS_ATTR_H
@@ -1,94 +0,0 @@
/*
* Copyright 2018, Haiku Inc. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_COMPAT_FS_INFO_H
#define _KERNEL_COMPAT_FS_INFO_H
#include <fs_info.h>
typedef struct compat_fs_info {
dev_t dev; /* volume dev_t */
ino_t root; /* root ino_t */
uint32 flags; /* flags (see above) */
off_t block_size; /* fundamental block size */
off_t io_size; /* optimal i/o size */
off_t total_blocks; /* total number of blocks */
off_t free_blocks; /* number of free blocks */
off_t total_nodes; /* total number of nodes */
off_t free_nodes; /* number of free nodes */
char device_name[128]; /* device holding fs */
char volume_name[B_FILE_NAME_LENGTH]; /* volume name */
char fsh_name[B_OS_NAME_LENGTH]; /* name of fs handler */
} _PACKED compat_fs_info;
static_assert(sizeof(compat_fs_info) == 480,
"size of compat_fs_info mismatch");
inline status_t
copy_ref_var_to_user(fs_info &info, fs_info* userInfo)
{
if (!IS_USER_ADDRESS(userInfo))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
compat_fs_info compat_info;
compat_info.dev = info.dev;
compat_info.root = info.root;
compat_info.flags = info.flags;
compat_info.block_size = info.block_size;
compat_info.io_size = info.io_size;
compat_info.total_blocks = info.total_blocks;
compat_info.free_blocks = info.free_blocks;
compat_info.total_nodes = info.total_nodes;
compat_info.free_nodes = info.free_nodes;
strlcpy(compat_info.device_name, info.device_name, 128);
strlcpy(compat_info.volume_name, info.volume_name, B_FILE_NAME_LENGTH);
strlcpy(compat_info.fsh_name, info.fsh_name, B_OS_NAME_LENGTH);
if (user_memcpy(userInfo, &compat_info, sizeof(compat_info)) < B_OK)
return B_BAD_ADDRESS;
} else {
if (user_memcpy(userInfo, &info, sizeof(info)) < B_OK)
return B_BAD_ADDRESS;
}
return B_OK;
}
inline status_t
copy_ref_var_from_user(fs_info* userInfo, fs_info &info)
{
if (!IS_USER_ADDRESS(userInfo))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
compat_fs_info compat_info;
if (user_memcpy(&compat_info, userInfo, sizeof(compat_info)) < B_OK)
return B_BAD_ADDRESS;
info.dev = compat_info.dev;
info.root = compat_info.root;
info.flags = compat_info.flags;
info.block_size = compat_info.block_size;
info.io_size = compat_info.io_size;
info.total_blocks = compat_info.total_blocks;
info.free_blocks = compat_info.free_blocks;
info.total_nodes = compat_info.total_nodes;
info.free_nodes = compat_info.free_nodes;
strlcpy(info.device_name, compat_info.device_name, 128);
strlcpy(info.volume_name, compat_info.volume_name, B_FILE_NAME_LENGTH);
strlcpy(info.fsh_name, compat_info.fsh_name, B_OS_NAME_LENGTH);
} else if (user_memcpy(&info, userInfo, sizeof(info)) < B_OK) {
return B_BAD_ADDRESS;
}
return B_OK;
}
#endif // _KERNEL_COMPAT_FS_INFO_H
@@ -1,129 +0,0 @@
/*
* Copyright 2018, Haiku Inc. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_COMPAT_IMAGE_H
#define _KERNEL_COMPAT_IMAGE_H
#include <image.h>
#define compat_uintptr_t uint32
typedef struct {
image_id id;
image_type type;
int32 sequence;
int32 init_order;
compat_uintptr_t init_routine;
compat_uintptr_t term_routine;
dev_t device;
ino_t node;
char name[MAXPATHLEN];
compat_uintptr_t text;
compat_uintptr_t data;
int32 text_size;
int32 data_size;
/* Haiku R1 extensions */
int32 api_version; /* the Haiku API version used by the image */
int32 abi; /* the Haiku ABI used by the image */
} _PACKED compat_image_info;
typedef struct {
compat_image_info basic_info;
int32 text_delta;
compat_uintptr_t symbol_table;
compat_uintptr_t symbol_hash;
compat_uintptr_t string_table;
} _PACKED compat_extended_image_info;
static_assert(sizeof(compat_image_info) == 1084,
"size of compat_image_info mismatch");
static_assert(sizeof(compat_extended_image_info) == 1100,
"size of compat_extended_image_info mismatch");
inline status_t
copy_ref_var_to_user(image_info &info, image_info* userInfo, size_t size)
{
if (!IS_USER_ADDRESS(userInfo))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
if (size > sizeof(compat_image_info))
return B_BAD_VALUE;
compat_image_info compat_info;
compat_info.id = info.id;
compat_info.type = info.type;
compat_info.sequence = info.sequence;
compat_info.init_order = info.init_order;
compat_info.init_routine = (uint32)(addr_t)info.init_routine;
compat_info.term_routine = (uint32)(addr_t)info.term_routine;
compat_info.device = info.device;
compat_info.node = info.node;
strlcpy(compat_info.name, info.name, MAXPATHLEN);
compat_info.text = (uint32)(addr_t)info.text;
compat_info.data = (uint32)(addr_t)info.data;
compat_info.text_size = info.text_size;
compat_info.data_size = info.data_size;
if (user_memcpy(userInfo, &compat_info, size) < B_OK)
return B_BAD_ADDRESS;
} else {
if (size > sizeof(image_info))
return B_BAD_VALUE;
if (user_memcpy(userInfo, &info, size) < B_OK)
return B_BAD_ADDRESS;
}
return B_OK;
}
inline status_t
copy_ref_var_from_user(extended_image_info* userInfo,
extended_image_info &info, size_t size)
{
if (!IS_USER_ADDRESS(userInfo))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
compat_extended_image_info compat_info;
if (size != sizeof(compat_info))
return B_BAD_VALUE;
if (user_memcpy(&compat_info, userInfo, size) < B_OK)
return B_BAD_ADDRESS;
info.basic_info.id = compat_info.basic_info.id;
info.basic_info.type = compat_info.basic_info.type;
info.basic_info.sequence = compat_info.basic_info.sequence;
info.basic_info.init_order = compat_info.basic_info.init_order;
info.basic_info.init_routine = (void(*)())(addr_t)compat_info.basic_info.init_routine;
info.basic_info.term_routine = (void(*)())(addr_t)compat_info.basic_info.term_routine;
info.basic_info.device = compat_info.basic_info.device;
info.basic_info.node = compat_info.basic_info.node;
strlcpy(info.basic_info.name, compat_info.basic_info.name, MAXPATHLEN);
info.basic_info.text = (void*)(addr_t)compat_info.basic_info.text;
info.basic_info.data = (void*)(addr_t)compat_info.basic_info.data;
info.basic_info.text_size = compat_info.basic_info.text_size;
info.basic_info.data_size = compat_info.basic_info.data_size;
info.text_delta = compat_info.text_delta;
info.symbol_table = (void*)(addr_t)compat_info.symbol_table;
info.symbol_hash = (void*)(addr_t)compat_info.symbol_hash;
info.string_table = (void*)(addr_t)compat_info.string_table;
} else {
if (size != sizeof(info))
return B_BAD_VALUE;
if (user_memcpy(&info, userInfo, size) < B_OK)
return B_BAD_ADDRESS;
}
return B_OK;
}
#endif // _KERNEL_COMPAT_IMAGE_H
@@ -1,165 +0,0 @@
/*
* Copyright 2018, Haiku Inc. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_COMPAT_KSIGNAL_H
#define _KERNEL_COMPAT_KSIGNAL_H
#include <compat/signal_compat.h>
#include <compat/arch/x86/signal_compat.h>
typedef struct compat_vregs compat_mcontext_t;
typedef struct __compat_ucontext_t {
uint32 uc_link;
sigset_t uc_sigmask;
compat_stack_t uc_stack;
compat_mcontext_t uc_mcontext;
} _PACKED compat_ucontext_t;
union compat_sigval {
int sival_int;
uint32 sival_ptr;
};
typedef struct __compat_siginfo_t {
int si_signo; /* signal number */
int si_code; /* signal code */
int si_errno; /* if non zero, an error number associated with
this signal */
pid_t si_pid; /* sending process ID */
uid_t si_uid; /* real user ID of sending process */
uint32 si_addr; /* address of faulting instruction */
int si_status; /* exit value or signal */
uint32 si_band; /* band event for SIGPOLL */
union compat_sigval si_value; /* signal value */
} compat_siginfo_t;
struct compat_signal_frame_data {
compat_siginfo_t info;
compat_ucontext_t context;
uint32 user_data;
uint32 handler;
bool siginfo_handler;
char _pad[3];
int32 thread_flags;
uint64 syscall_restart_return_value;
uint8 syscall_restart_parameters[SYSCALL_RESTART_PARAMETER_SIZE];
uint32 commpage_address;
} _PACKED;
static_assert(sizeof(compat_stack_t) == 12,
"size of compat_stack_t mismatch");
static_assert(sizeof(compat_mcontext_t) == 560,
"size of compat_mcontext_t mismatch");
static_assert(sizeof(compat_ucontext_t) == 584,
"size of compat_ucontext_t mismatch");
static_assert(sizeof(compat_siginfo_t) == 36,
"size of compat_siginfo_t mismatch");
static_assert(sizeof(struct compat_signal_frame_data) == 680,
"size of compat_signal_frame_data mismatch");
inline status_t
copy_ref_var_from_user(union sigval* userSigval, union sigval &sigval)
{
if (!IS_USER_ADDRESS(userSigval))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
compat_sigval compat_sigval;
if (user_memcpy(&compat_sigval, userSigval, sizeof(compat_sigval))
< B_OK) {
return B_BAD_ADDRESS;
}
sigval.sival_ptr = (void*)(addr_t)compat_sigval.sival_ptr;
} else if (user_memcpy(&sigval, userSigval, sizeof(union sigval)) < B_OK) {
return B_BAD_ADDRESS;
}
return B_OK;
}
inline status_t
copy_ref_var_to_user(siginfo_t &info, siginfo_t* userInfo)
{
if (!IS_USER_ADDRESS(userInfo))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
compat_siginfo_t compat_info;
compat_info.si_signo = info.si_signo;
compat_info.si_code = info.si_code;
compat_info.si_errno = info.si_errno;
compat_info.si_pid = info.si_pid;
compat_info.si_uid = info.si_uid;
compat_info.si_addr = (addr_t)info.si_addr;
compat_info.si_status = info.si_status;
compat_info.si_band = info.si_band;
compat_info.si_value.sival_ptr = (addr_t)info.si_value.sival_ptr;
if (user_memcpy(userInfo, &compat_info, sizeof(compat_info))
< B_OK) {
return B_BAD_ADDRESS;
}
} else if (user_memcpy(userInfo, &info, sizeof(info)) < B_OK) {
return B_BAD_ADDRESS;
}
return B_OK;
}
inline status_t
copy_ref_var_from_user(stack_t* userStack, stack_t &stack)
{
if (!IS_USER_ADDRESS(userStack))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
compat_stack_t compatStack;
if (user_memcpy(&compatStack, userStack, sizeof(compatStack))
< B_OK) {
return B_BAD_ADDRESS;
}
stack.ss_sp = (void*)(addr_t)compatStack.ss_sp;
stack.ss_size = compatStack.ss_size;
stack.ss_flags = compatStack.ss_flags;
} else if (user_memcpy(&stack, userStack, sizeof(stack_t)) < B_OK) {
return B_BAD_ADDRESS;
}
return B_OK;
}
inline status_t
copy_ref_var_to_user(stack_t &stack, stack_t* userStack)
{
if (!IS_USER_ADDRESS(userStack))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
compat_stack_t compatStack;
compatStack.ss_sp = (addr_t)stack.ss_sp;
compatStack.ss_size = stack.ss_size;
compatStack.ss_flags = stack.ss_flags;
if (user_memcpy(userStack, &compatStack, sizeof(compatStack))
< B_OK) {
return B_BAD_ADDRESS;
}
} else if (user_memcpy(userStack, &stack, sizeof(stack)) < B_OK) {
return B_BAD_ADDRESS;
}
return B_OK;
}
#endif // _KERNEL_COMPAT_KSIGNAL_H
@@ -1,70 +0,0 @@
/*
* Copyright 2018, Haiku Inc. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_COMPAT_SIGNAL_H
#define _KERNEL_COMPAT_SIGNAL_H
struct compat_sigaction {
union {
uint32 sa_handler;
uint32 sa_sigaction;
};
sigset_t sa_mask;
int sa_flags;
uint32 sa_userdata; /* will be passed to the signal
handler, BeOS extension */
} _PACKED;
inline status_t
copy_ref_var_from_user(struct sigaction* userAction, struct sigaction &action)
{
if (!IS_USER_ADDRESS(userAction))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
struct compat_sigaction compat_action;
if (user_memcpy(&compat_action, userAction, sizeof(compat_sigaction))
< B_OK) {
return B_BAD_ADDRESS;
}
action.sa_handler = (__sighandler_t)(addr_t)compat_action.sa_handler;
action.sa_mask = compat_action.sa_mask;
action.sa_flags = compat_action.sa_flags;
action.sa_userdata = (void*)(addr_t)compat_action.sa_userdata;
} else if (user_memcpy(&action, userAction, sizeof(action)) < B_OK) {
return B_BAD_ADDRESS;
}
return B_OK;
}
inline status_t
copy_ref_var_to_user(struct sigaction &action, struct sigaction* userAction)
{
if (!IS_USER_ADDRESS(userAction))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
struct compat_sigaction compat_action;
compat_action.sa_handler = (addr_t)action.sa_handler;
compat_action.sa_mask = action.sa_mask;
compat_action.sa_flags = action.sa_flags;
compat_action.sa_userdata = (addr_t)action.sa_userdata;
if (user_memcpy(userAction, &compat_action, sizeof(compat_action))
< B_OK) {
return B_BAD_ADDRESS;
}
} else if (user_memcpy(userAction, &action, sizeof(action)) < B_OK) {
return B_BAD_ADDRESS;
}
return B_OK;
}
#endif // _KERNEL_COMPAT_SIGNAL_H
-117
View File
@@ -1,117 +0,0 @@
/*
* Copyright 2018, Haiku Inc. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_COMPAT_STAT_H
#define _KERNEL_COMPAT_STAT_H
#include <sys/stat.h>
#include <time_compat.h>
struct compat_stat {
dev_t st_dev; /* device ID that this file resides on */
ino_t st_ino; /* this file's serial inode ID */
mode_t st_mode; /* file mode (rwx for user, group, etc) */
nlink_t st_nlink; /* number of hard links to this file */
uid_t st_uid; /* user ID of the owner of this file */
gid_t st_gid; /* group ID of the owner of this file */
off_t st_size; /* size in bytes of this file */
dev_t st_rdev; /* device type (not used) */
blksize_t st_blksize; /* preferred block size for I/O */
struct compat_timespec st_atim; /* last access time */
struct compat_timespec st_mtim; /* last modification time */
struct compat_timespec st_ctim; /* last change time, not creation time */
struct compat_timespec st_crtim; /* creation time */
__haiku_uint32 st_type; /* attribute/index type */
blkcnt_t st_blocks; /* number of blocks allocated for object */
} _PACKED;
static_assert(sizeof(struct compat_stat) == 88,
"size of struct compat_stat mismatch");
inline status_t
copy_ref_var_to_user(struct stat &stat, struct stat* userStat, size_t size)
{
if (!IS_USER_ADDRESS(userStat))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
if (size > sizeof(compat_stat))
return B_BAD_VALUE;
struct compat_stat compat_stat;
compat_stat.st_dev = stat.st_dev;
compat_stat.st_ino = stat.st_ino;
compat_stat.st_mode = stat.st_mode;
compat_stat.st_nlink = stat.st_nlink;
compat_stat.st_uid = stat.st_gid;
compat_stat.st_size = stat.st_size;
compat_stat.st_rdev = stat.st_rdev;
compat_stat.st_blksize = stat.st_blksize;
compat_stat.st_atim.tv_sec = stat.st_atim.tv_sec;
compat_stat.st_atim.tv_nsec = stat.st_atim.tv_nsec;
compat_stat.st_mtim.tv_sec = stat.st_mtim.tv_sec;
compat_stat.st_mtim.tv_nsec = stat.st_mtim.tv_nsec;
compat_stat.st_ctim.tv_sec = stat.st_ctim.tv_sec;
compat_stat.st_ctim.tv_nsec = stat.st_ctim.tv_nsec;
compat_stat.st_crtim.tv_sec = stat.st_crtim.tv_sec;
compat_stat.st_crtim.tv_nsec = stat.st_crtim.tv_nsec;
compat_stat.st_type = stat.st_type;
compat_stat.st_blocks = stat.st_blocks;
if (user_memcpy(userStat, &compat_stat, size) < B_OK)
return B_BAD_ADDRESS;
} else {
if (size > sizeof(struct stat))
return B_BAD_VALUE;
if (user_memcpy(userStat, &stat, size) < B_OK)
return B_BAD_ADDRESS;
}
return B_OK;
}
inline status_t
copy_ref_var_to_user(struct stat &stat, struct stat* userStat)
{
if (!IS_USER_ADDRESS(userStat))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
struct compat_stat compat_stat;
compat_stat.st_dev = stat.st_dev;
compat_stat.st_ino = stat.st_ino;
compat_stat.st_mode = stat.st_mode;
compat_stat.st_nlink = stat.st_nlink;
compat_stat.st_uid = stat.st_gid;
compat_stat.st_size = stat.st_size;
compat_stat.st_rdev = stat.st_rdev;
compat_stat.st_blksize = stat.st_blksize;
compat_stat.st_atim.tv_sec = stat.st_atim.tv_sec;
compat_stat.st_atim.tv_nsec = stat.st_atim.tv_nsec;
compat_stat.st_mtim.tv_sec = stat.st_mtim.tv_sec;
compat_stat.st_mtim.tv_nsec = stat.st_mtim.tv_nsec;
compat_stat.st_ctim.tv_sec = stat.st_ctim.tv_sec;
compat_stat.st_ctim.tv_nsec = stat.st_ctim.tv_nsec;
compat_stat.st_crtim.tv_sec = stat.st_crtim.tv_sec;
compat_stat.st_crtim.tv_nsec = stat.st_crtim.tv_nsec;
compat_stat.st_type = stat.st_type;
compat_stat.st_blocks = stat.st_blocks;
if (user_memcpy(userStat, &compat_stat, sizeof(compat_stat)) < B_OK)
return B_BAD_ADDRESS;
} else {
if (user_memcpy(userStat, &stat, sizeof(stat)) < B_OK)
return B_BAD_ADDRESS;
}
return B_OK;
}
#endif // _KERNEL_COMPAT_STAT_H
@@ -1,19 +0,0 @@
/*
* Copyright 2018, Haiku Inc. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_COMPAT_TIME_H
#define _KERNEL_COMPAT_TIME_H
#include <time.h>
struct compat_timespec {
uint32 tv_sec; /* seconds */
uint32 tv_nsec; /* and nanoseconds */
};
#endif // _KERNEL_COMPAT_TIME_H
@@ -1,79 +0,0 @@
/*
* Copyright 2018, Haiku Inc. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_COMPAT_VFS_DEFS_H
#define _KERNEL_COMPAT_VFS_DEFS_H
#include <vfs_defs.h>
struct compat_fd_info {
int number;
int32 open_mode;
dev_t device;
ino_t node;
} _PACKED;
static_assert(sizeof(compat_fd_info) == 20,
"size of compat_fd_info mismatch");
inline status_t
copy_ref_var_to_user(attr_info &info, attr_info* userInfo, size_t size)
{
if (!IS_USER_ADDRESS(userInfo))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
if (size != sizeof(compat_fd_info))
return B_BAD_VALUE;
compat_fd_info compat_info;
compat_info.number = info.number;
compat_info.open_mode = info.open_mode;
compat_info.device = info.device;
compat_info.node = info.node;
if (user_memcpy(userInfo, &compat_info, size) < B_OK)
return B_BAD_ADDRESS;
} else {
if (size != sizeof(fd_info))
return B_BAD_VALUE;
if (user_memcpy(userInfo, &info, size) < B_OK)
return B_BAD_ADDRESS;
}
return B_OK;
}
inline status_t
copy_ref_var_from_user(fd_info* userInfo, fd_info &info, size_t size)
{
if (!IS_USER_ADDRESS(userInfo))
return B_BAD_ADDRESS;
Thread* thread = thread_get_current_thread();
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
if (compatMode) {
if (size != sizeof(compat_fd_info))
return B_BAD_VALUE;
compat_fd_info compat_info;
if (user_memcpy(&compat_info, userInfo, size) < B_OK)
return B_BAD_ADDRESS;
info.number = compat_info.number;
info.open_mode = compat_info.open_mode;
info.device = compat_info.device;
info.node = compat_info.node;
} else {
if (size != sizeof(fd_info))
return B_BAD_VALUE;
if (user_memcpy(&info, userInfo, size) < B_OK)
return B_BAD_ADDRESS;
}
return B_OK;
}
#endif // _KERNEL_COMPAT_VFS_DEFS_H
@@ -23,18 +23,6 @@ copy_ref_var_from_user(T *user, T &kernel)
return user_memcpy(&kernel, user, sizeof(T));
}
template<typename T>
inline
status_t
copy_ref_var_from_user(T *user, T &kernel, size_t size)
{
if (size != sizeof(T))
return B_BAD_VALUE;
return copy_ref_var_from_user(user, kernel);
}
// copy_ref_var_to_user
template<typename T>
inline
@@ -47,17 +35,4 @@ copy_ref_var_to_user(T &kernel, T *user)
}
template<typename T>
inline
status_t
copy_ref_var_to_user(T &kernel, T *user, size_t size)
{
if (size > sizeof(T))
return B_BAD_VALUE;
if (!IS_USER_ADDRESS(user))
return B_BAD_ADDRESS;
return user_memcpy(user, &kernel, size);
}
#endif // _SYSCALL_ARGS_H