mirror of
https://github.com/clearlinux/graphene.git
synced 2026-04-28 11:13:41 +00:00
Reformat repository to our C formatting rules (final iteration)
This commit is contained in:
@@ -3,9 +3,9 @@ AlignConsecutiveAssignments: true
|
||||
AlignConsecutiveMacros: true
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
ColumnLimit: 100
|
||||
ColumnLimit: 100
|
||||
DerivePointerAlignment: false
|
||||
IndentWidth: 4
|
||||
IndentWidth: 4
|
||||
ObjCBlockIndentWidth: 4
|
||||
PointerAlignment: Left
|
||||
TabWidth: 4
|
||||
TabWidth: 4
|
||||
|
||||
@@ -4,8 +4,6 @@ Coding style guidelines
|
||||
This document describes coding conventions and formatting styles we use in
|
||||
Graphene. All newly commited code must conform to them to pass a |~| review.
|
||||
|
||||
.. note:: Old code is temporarily excluded from these rules until reformatted.
|
||||
|
||||
Automatic reformatting
|
||||
----------------------
|
||||
|
||||
@@ -31,6 +29,13 @@ recommend you first commit them (or add to `git index
|
||||
:command:`git diff` (or :command:`git diff --cached` if you used :command:`git
|
||||
add`).
|
||||
|
||||
.. warning::
|
||||
|
||||
Because of bugs in clang-format and its questionable reformats in many places
|
||||
(seems it deals with C++ much better than with C) it's intended only as a |~|
|
||||
helper tool. Adding it to git pre-commit hooks is definitely a |~| bad idea,
|
||||
at least currently.
|
||||
|
||||
C
|
||||
-
|
||||
|
||||
@@ -101,6 +106,15 @@ Code formatting
|
||||
external dependencies, like :file:`curl.h`).
|
||||
#. Graphene's headers.
|
||||
|
||||
#. Assignments may be aligned when assigning some structurized data (e.g. struct
|
||||
members). Example::
|
||||
|
||||
int some_int = 0;
|
||||
bool asdf = true;
|
||||
file->size = 123;
|
||||
file->full_path = "/asdf/ghjkl";
|
||||
file->perms = 0644;
|
||||
|
||||
Conventions and high-level style
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
#. Variable and function names should be sane and easy to understand (example:
|
||||
|
||||
@@ -2,10 +2,8 @@
|
||||
/* Copyright (C) 2014 Stony Brook University */
|
||||
|
||||
/*
|
||||
* dl-machine-x86_64.c
|
||||
*
|
||||
* This file contains x64-specific codes for relocating ELF binaries.
|
||||
* Most of the source codes are imported from GNU C library.
|
||||
* This file contains x64-specific code for relocating ELF binaries. Most of the source code was
|
||||
* imported from GNU C library.
|
||||
*/
|
||||
|
||||
#ifndef __DL_MACHINE_H__
|
||||
|
||||
@@ -6,24 +6,24 @@
|
||||
#include "pal.h"
|
||||
|
||||
struct shim_regs {
|
||||
uint64_t orig_rax;
|
||||
uint64_t rsp;
|
||||
uint64_t r15;
|
||||
uint64_t r14;
|
||||
uint64_t r13;
|
||||
uint64_t r12;
|
||||
uint64_t r11;
|
||||
uint64_t r10;
|
||||
uint64_t r9;
|
||||
uint64_t r8;
|
||||
uint64_t rcx;
|
||||
uint64_t rdx;
|
||||
uint64_t rsi;
|
||||
uint64_t rdi;
|
||||
uint64_t rbx;
|
||||
uint64_t rbp;
|
||||
uint64_t rflags;
|
||||
uint64_t rip;
|
||||
uint64_t orig_rax;
|
||||
uint64_t rsp;
|
||||
uint64_t r15;
|
||||
uint64_t r14;
|
||||
uint64_t r13;
|
||||
uint64_t r12;
|
||||
uint64_t r11;
|
||||
uint64_t r10;
|
||||
uint64_t r9;
|
||||
uint64_t r8;
|
||||
uint64_t rcx;
|
||||
uint64_t rdx;
|
||||
uint64_t rsi;
|
||||
uint64_t rdi;
|
||||
uint64_t rbx;
|
||||
uint64_t rbp;
|
||||
uint64_t rflags;
|
||||
uint64_t rip;
|
||||
};
|
||||
|
||||
static inline uint64_t shim_regs_get_sp(struct shim_regs* sr) {
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
#include "shim_tcb-arch.h"
|
||||
|
||||
/* asm/signal.h */
|
||||
#define NUM_SIGS 64
|
||||
#define SIGRTMIN 32
|
||||
#define NUM_SIGS 64
|
||||
#define SIGRTMIN 32
|
||||
|
||||
typedef struct {
|
||||
unsigned long __val[NUM_SIGS / (8 * sizeof(unsigned long))];
|
||||
} __sigset_t;
|
||||
|
||||
#define RED_ZONE_SIZE 128
|
||||
#define RED_ZONE_SIZE 128
|
||||
|
||||
#endif /* _SHIM_TYPES_ARCH_H_ */
|
||||
|
||||
@@ -3,33 +3,33 @@
|
||||
#ifndef _SHIM_UCONTEXT_ARCH_H_
|
||||
#define _SHIM_UCONTEXT_ARCH_H_
|
||||
|
||||
#include <shim_types.h>
|
||||
#include <ucontext.h>
|
||||
#include "shim_types.h"
|
||||
#include "ucontext.h"
|
||||
|
||||
static inline void shim_regs_to_ucontext(ucontext_t* context, struct shim_regs* regs) {
|
||||
context->uc_mcontext.gregs[REG_R8] = regs->r8;
|
||||
context->uc_mcontext.gregs[REG_R9] = regs->r9;
|
||||
context->uc_mcontext.gregs[REG_R10] = regs->r10;
|
||||
context->uc_mcontext.gregs[REG_R11] = regs->r11;
|
||||
context->uc_mcontext.gregs[REG_R12] = regs->r12;
|
||||
context->uc_mcontext.gregs[REG_R13] = regs->r13;
|
||||
context->uc_mcontext.gregs[REG_R14] = regs->r14;
|
||||
context->uc_mcontext.gregs[REG_R15] = regs->r15;
|
||||
context->uc_mcontext.gregs[REG_RDI] = regs->rdi;
|
||||
context->uc_mcontext.gregs[REG_RSI] = regs->rsi;
|
||||
context->uc_mcontext.gregs[REG_RBP] = regs->rbp;
|
||||
context->uc_mcontext.gregs[REG_RBX] = regs->rbx;
|
||||
context->uc_mcontext.gregs[REG_RDX] = regs->rdx;
|
||||
context->uc_mcontext.gregs[REG_RAX] = regs->orig_rax;
|
||||
context->uc_mcontext.gregs[REG_RCX] = regs->rcx;
|
||||
context->uc_mcontext.gregs[REG_RSP] = regs->rsp;
|
||||
context->uc_mcontext.gregs[REG_RIP] = regs->rip;
|
||||
context->uc_mcontext.gregs[REG_EFL] = regs->rflags;
|
||||
context->uc_mcontext.gregs[REG_CSGSFS] = 0;
|
||||
context->uc_mcontext.gregs[REG_ERR] = 0;
|
||||
context->uc_mcontext.gregs[REG_TRAPNO] = 0;
|
||||
context->uc_mcontext.gregs[REG_R8] = regs->r8;
|
||||
context->uc_mcontext.gregs[REG_R9] = regs->r9;
|
||||
context->uc_mcontext.gregs[REG_R10] = regs->r10;
|
||||
context->uc_mcontext.gregs[REG_R11] = regs->r11;
|
||||
context->uc_mcontext.gregs[REG_R12] = regs->r12;
|
||||
context->uc_mcontext.gregs[REG_R13] = regs->r13;
|
||||
context->uc_mcontext.gregs[REG_R14] = regs->r14;
|
||||
context->uc_mcontext.gregs[REG_R15] = regs->r15;
|
||||
context->uc_mcontext.gregs[REG_RDI] = regs->rdi;
|
||||
context->uc_mcontext.gregs[REG_RSI] = regs->rsi;
|
||||
context->uc_mcontext.gregs[REG_RBP] = regs->rbp;
|
||||
context->uc_mcontext.gregs[REG_RBX] = regs->rbx;
|
||||
context->uc_mcontext.gregs[REG_RDX] = regs->rdx;
|
||||
context->uc_mcontext.gregs[REG_RAX] = regs->orig_rax;
|
||||
context->uc_mcontext.gregs[REG_RCX] = regs->rcx;
|
||||
context->uc_mcontext.gregs[REG_RSP] = regs->rsp;
|
||||
context->uc_mcontext.gregs[REG_RIP] = regs->rip;
|
||||
context->uc_mcontext.gregs[REG_EFL] = regs->rflags;
|
||||
context->uc_mcontext.gregs[REG_CSGSFS] = 0;
|
||||
context->uc_mcontext.gregs[REG_ERR] = 0;
|
||||
context->uc_mcontext.gregs[REG_TRAPNO] = 0;
|
||||
context->uc_mcontext.gregs[REG_OLDMASK] = 0;
|
||||
context->uc_mcontext.gregs[REG_CR2] = 0;
|
||||
context->uc_mcontext.gregs[REG_CR2] = 0;
|
||||
}
|
||||
|
||||
#endif /* _SHIM_UCONTEXT_ARCH_H_ */
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
#include "shim_defs.h"
|
||||
#include "shim_ipc.h"
|
||||
|
||||
@@ -58,7 +57,7 @@ struct shim_mem_entry {
|
||||
struct shim_mem_entry* next;
|
||||
void* addr;
|
||||
size_t size;
|
||||
int prot; /* combination of PAL_PROT_* flags */
|
||||
int prot; /* combination of PAL_PROT_* flags */
|
||||
};
|
||||
|
||||
struct shim_palhdl_entry {
|
||||
@@ -278,7 +277,7 @@ struct shim_cp_map_entry* get_cp_map_entry(void* map, void* addr, bool create);
|
||||
|
||||
#define BEGIN_MIGRATION_DEF(name, ...) \
|
||||
int migrate_cp_##name(struct shim_cp_store* store, ##__VA_ARGS__) { \
|
||||
int ret = 0; \
|
||||
int ret = 0; \
|
||||
size_t base = store->base;
|
||||
|
||||
#define END_MIGRATION_DEF(name) \
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#ifndef _SHIM_CONTEXT_H_
|
||||
#define _SHIM_CONTEXT_H_
|
||||
|
||||
#include <shim_tcb.h>
|
||||
#include "shim_tcb.h"
|
||||
|
||||
void restore_context(struct shim_context* context);
|
||||
void fixup_child_context(struct shim_regs* regs);
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
#ifndef _SHIM_DEFS_H_
|
||||
#define _SHIM_DEFS_H_
|
||||
|
||||
#define DEFAULT_HEAP_MIN_SIZE (256 * 1024 * 1024) /* 256MB */
|
||||
#define DEFAULT_MEM_MAX_NPAGES (1024 * 1024) /* 4GB */
|
||||
#define DEFAULT_BRK_MAX_SIZE (256 * 1024) /* 256KB */
|
||||
#define DEFAULT_SYS_STACK_SIZE (256 * 1024) /* 256KB */
|
||||
#define DEFAULT_HEAP_MIN_SIZE (256 * 1024 * 1024) /* 256MB */
|
||||
#define DEFAULT_MEM_MAX_NPAGES (1024 * 1024) /* 4GB */
|
||||
#define DEFAULT_BRK_MAX_SIZE (256 * 1024) /* 256KB */
|
||||
#define DEFAULT_SYS_STACK_SIZE (256 * 1024) /* 256KB */
|
||||
|
||||
#define CP_INIT_VMA_SIZE (64 * 1024 * 1024) /* 64MB */
|
||||
#define CP_INIT_VMA_SIZE (64 * 1024 * 1024) /* 64MB */
|
||||
|
||||
/* debug message printout */
|
||||
#define DEBUGBUF_SIZE 256
|
||||
#define DEBUGBUF_BREAK 0
|
||||
#define DEBUGBUF_SIZE 256
|
||||
#define DEBUGBUF_BREAK 0
|
||||
|
||||
#define DEFAULT_VMA_COUNT 64
|
||||
#define DEFAULT_VMA_COUNT 64
|
||||
|
||||
/* ELF aux vectors */
|
||||
#define REQUIRED_ELF_AUXV 8 /* number of LibOS-supported vectors */
|
||||
#define REQUIRED_ELF_AUXV_SPACE 16 /* extra memory space (in bytes) */
|
||||
#define REQUIRED_ELF_AUXV 8 /* number of LibOS-supported vectors */
|
||||
#define REQUIRED_ELF_AUXV_SPACE 16 /* extra memory space (in bytes) */
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#define LIBOS_SYSCALL_BOUND (340 + 1)
|
||||
#define LIBOS_SYSCALL_BOUND (340 + 1)
|
||||
#endif
|
||||
|
||||
#endif /* _SHIM_DEFS_H_ */
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
#define SHIM_FLAGS_CONV_H
|
||||
|
||||
#include <asm/fcntl.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/mman.h>
|
||||
|
||||
#include "assert.h"
|
||||
#include "pal.h"
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#define _SHIM_FS_H_
|
||||
|
||||
#define __KERNEL__
|
||||
#include <stdbool.h>
|
||||
#include <linux/stat.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "list.h"
|
||||
#include "pal.h"
|
||||
@@ -295,8 +295,6 @@ void put_mount(struct shim_mount* mount);
|
||||
|
||||
struct shim_mount* find_mount_from_uri(const char* uri);
|
||||
|
||||
#include <shim_utils.h>
|
||||
|
||||
static inline void set_handle_fs(struct shim_handle* hdl, struct shim_mount* fs) {
|
||||
get_mount(fs);
|
||||
hdl->fs = fs;
|
||||
@@ -512,7 +510,7 @@ struct pseudo_ent {
|
||||
const char* name;
|
||||
const struct pseudo_name_ops* name_ops;
|
||||
const struct pseudo_fs_ops* fs_ops;
|
||||
const struct pseudo_dir* dir; /* NULL if pseudo-FS entry is a file */
|
||||
const struct pseudo_dir* dir; /* NULL if pseudo-FS entry is a file */
|
||||
int type; /* LINUX_DT_REG, LINUX_DT_CHR, etc (if dir != NULL, then always LINUX_DT_DIR) */
|
||||
};
|
||||
|
||||
|
||||
@@ -12,18 +12,19 @@
|
||||
|
||||
#include <asm/fcntl.h>
|
||||
#include <asm/resource.h>
|
||||
#include <atomic.h> // TODO: migrate to stdatomic.h
|
||||
#include <linux/in.h>
|
||||
#include <linux/in6.h>
|
||||
#include <linux/shm.h>
|
||||
#include <linux/un.h>
|
||||
#include <list.h>
|
||||
#include <pal.h>
|
||||
#include <shim_defs.h>
|
||||
#include <shim_sysv.h>
|
||||
#include <shim_types.h>
|
||||
#include <stdalign.h>
|
||||
|
||||
#include "atomic.h" // TODO: migrate to stdatomic.h
|
||||
#include "list.h"
|
||||
#include "pal.h"
|
||||
#include "shim_defs.h"
|
||||
#include "shim_sysv.h"
|
||||
#include "shim_types.h"
|
||||
|
||||
/* start definition of shim handle */
|
||||
enum shim_handle_type {
|
||||
TYPE_FILE,
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#error "this header file can only be used inside SHIM"
|
||||
#endif
|
||||
|
||||
#define attribute_hidden __attribute__ ((visibility ("hidden")))
|
||||
#define attribute_hidden __attribute__((visibility("hidden")))
|
||||
|
||||
#define ALIAS_STR(name) #name
|
||||
|
||||
@@ -36,12 +36,11 @@ static inline unsigned int get_cur_tid(void) {
|
||||
return SHIM_TCB_GET(tid);
|
||||
}
|
||||
|
||||
#define PAL_NATIVE_ERRNO() SHIM_TCB_GET(pal_errno)
|
||||
#define PAL_NATIVE_ERRNO() SHIM_TCB_GET(pal_errno)
|
||||
|
||||
#define INTERNAL_TID_BASE ((IDTYPE) 1 << (sizeof(IDTYPE) * 8 - 1))
|
||||
#define INTERNAL_TID_BASE ((IDTYPE)1 << (sizeof(IDTYPE) * 8 - 1))
|
||||
|
||||
static inline bool is_internal_tid(unsigned int tid)
|
||||
{
|
||||
static inline bool is_internal_tid(unsigned int tid) {
|
||||
return tid >= INTERNAL_TID_BASE;
|
||||
}
|
||||
|
||||
@@ -51,70 +50,69 @@ struct debug_buf {
|
||||
char buf[DEBUGBUF_SIZE];
|
||||
};
|
||||
|
||||
#include <pal.h>
|
||||
#include <pal_debug.h>
|
||||
#include <pal_error.h>
|
||||
#include "pal.h"
|
||||
#include "pal_debug.h"
|
||||
#include "pal_error.h"
|
||||
|
||||
extern PAL_HANDLE debug_handle;
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
void debug_printf (const char * fmt, ...) __attribute__((format (printf, 1, 2)));
|
||||
void debug_puts (const char * str);
|
||||
void debug_putch (int ch);
|
||||
void debug_vprintf (const char * fmt, va_list ap) __attribute__((format (printf, 1, 0)));
|
||||
void debug_printf(const char* fmt, ...) __attribute__((format(printf, 1, 2)));
|
||||
void debug_puts(const char* str);
|
||||
void debug_putch(int ch);
|
||||
void debug_vprintf(const char* fmt, va_list ap) __attribute__((format(printf, 1, 0)));
|
||||
|
||||
#define debug(fmt, ...) \
|
||||
do { \
|
||||
if (debug_handle) \
|
||||
debug_printf(fmt, ##__VA_ARGS__); \
|
||||
#define debug(fmt, ...) \
|
||||
do { \
|
||||
if (debug_handle) \
|
||||
debug_printf(fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
/* print system messages */
|
||||
#define SYSPRINT_BUFFER_SIZE 256
|
||||
#define SYSPRINT_BUFFER_SIZE 256
|
||||
|
||||
void handle_printf (PAL_HANDLE hdl, const char * fmt, ...) __attribute__((format (printf, 2, 3)));
|
||||
void handle_vprintf (PAL_HANDLE hdl, const char * fmt, va_list ap) __attribute__((format (printf, 2, 0)));
|
||||
void handle_printf(PAL_HANDLE hdl, const char* fmt, ...) __attribute__((format(printf, 2, 3)));
|
||||
void handle_vprintf(PAL_HANDLE hdl, const char* fmt, va_list ap)
|
||||
__attribute__((format(printf, 2, 0)));
|
||||
|
||||
#define __SYS_PRINTF(fmt, ...) \
|
||||
do { \
|
||||
PAL_HANDLE _hdl = __open_shim_stdio(); \
|
||||
if (_hdl) \
|
||||
handle_printf(_hdl, fmt, ##__VA_ARGS__); \
|
||||
#define __SYS_PRINTF(fmt, ...) \
|
||||
do { \
|
||||
PAL_HANDLE _hdl = __open_shim_stdio(); \
|
||||
if (_hdl) \
|
||||
handle_printf(_hdl, fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define __SYS_VPRINTF(fmt, va) \
|
||||
do { \
|
||||
PAL_HANDLE _hdl = __open_shim_stdio(); \
|
||||
if (_hdl) \
|
||||
handle_vprintf(_hdl, fmt, va); \
|
||||
#define __SYS_VPRINTF(fmt, va) \
|
||||
do { \
|
||||
PAL_HANDLE _hdl = __open_shim_stdio(); \
|
||||
if (_hdl) \
|
||||
handle_vprintf(_hdl, fmt, va); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define __SYS_FPRINTF(hdl, fmt, ...) \
|
||||
do { \
|
||||
handle_printf(hdl, fmt, ##__VA_ARGS__); \
|
||||
#define __SYS_FPRINTF(hdl, fmt, ...) \
|
||||
do { \
|
||||
handle_printf(hdl, fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define SYS_PRINTF(fmt, ...) \
|
||||
do { \
|
||||
MASTER_LOCK(); \
|
||||
__SYS_PRINTF(fmt, ##__VA_ARGS__); \
|
||||
MASTER_UNLOCK(); \
|
||||
#define SYS_PRINTF(fmt, ...) \
|
||||
do { \
|
||||
MASTER_LOCK(); \
|
||||
__SYS_PRINTF(fmt, ##__VA_ARGS__); \
|
||||
MASTER_UNLOCK(); \
|
||||
} while (0)
|
||||
|
||||
#define SYS_FPRINTF(hdl, fmt, ...) \
|
||||
do { \
|
||||
MASTER_LOCK(); \
|
||||
__SYS_FPRINTF(hdl, fmt, ##__VA_ARGS__); \
|
||||
MASTER_UNLOCK(); \
|
||||
#define SYS_FPRINTF(hdl, fmt, ...) \
|
||||
do { \
|
||||
MASTER_LOCK(); \
|
||||
__SYS_FPRINTF(hdl, fmt, ##__VA_ARGS__); \
|
||||
MASTER_UNLOCK(); \
|
||||
} while (0)
|
||||
|
||||
extern PAL_HANDLE shim_stdio;
|
||||
|
||||
static inline PAL_HANDLE __open_shim_stdio (void)
|
||||
{
|
||||
if (shim_stdio == (PAL_HANDLE) -1)
|
||||
static inline PAL_HANDLE __open_shim_stdio(void) {
|
||||
if (shim_stdio == (PAL_HANDLE)-1)
|
||||
return NULL;
|
||||
|
||||
if (shim_stdio)
|
||||
@@ -123,7 +121,7 @@ static inline PAL_HANDLE __open_shim_stdio (void)
|
||||
shim_stdio = DkStreamOpen(URI_PREFIX_DEV "tty", PAL_ACCESS_RDWR, 0, 0, 0);
|
||||
|
||||
if (!shim_stdio) {
|
||||
shim_stdio = (PAL_HANDLE) -1;
|
||||
shim_stdio = (PAL_HANDLE)-1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -131,20 +129,22 @@ static inline PAL_HANDLE __open_shim_stdio (void)
|
||||
}
|
||||
|
||||
#if 0
|
||||
# define DEBUG_BREAK_ON_FAILURE() DEBUG_BREAK()
|
||||
#define DEBUG_BREAK_ON_FAILURE() DEBUG_BREAK()
|
||||
#else
|
||||
# define DEBUG_BREAK_ON_FAILURE() do {} while (0)
|
||||
#define DEBUG_BREAK_ON_FAILURE() do {} while (0)
|
||||
#endif
|
||||
|
||||
#define BUG() \
|
||||
do { \
|
||||
__SYS_PRINTF("BUG() " __FILE__ ":%d\n", __LINE__); \
|
||||
DEBUG_BREAK_ON_FAILURE(); \
|
||||
shim_clean_and_exit(-ENOTRECOVERABLE); \
|
||||
#define BUG() \
|
||||
do { \
|
||||
__SYS_PRINTF("BUG() " __FILE__ ":%d\n", __LINE__); \
|
||||
DEBUG_BREAK_ON_FAILURE(); \
|
||||
shim_clean_and_exit(-ENOTRECOVERABLE); \
|
||||
} while (0)
|
||||
|
||||
#define DEBUG_HERE() \
|
||||
do { debug("%s (" __FILE__ ":%d)\n", __func__, __LINE__); } while (0)
|
||||
#define DEBUG_HERE() \
|
||||
do { \
|
||||
debug("%s (" __FILE__ ":%d)\n", __func__, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
/* definition for syscall table */
|
||||
void handle_signals(void);
|
||||
@@ -156,162 +156,161 @@ void syscall_wrapper_after_syscalldb(void);
|
||||
|
||||
#define SHIM_ARG_TYPE long
|
||||
|
||||
static inline int64_t get_cur_preempt (void) {
|
||||
static inline int64_t get_cur_preempt(void) {
|
||||
shim_tcb_t* tcb = shim_get_tcb();
|
||||
assert(tcb);
|
||||
return __atomic_load_n(&tcb->context.preempt.counter, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
#define BEGIN_SHIM(name, args ...) \
|
||||
SHIM_ARG_TYPE __shim_##name(args) { \
|
||||
SHIM_ARG_TYPE ret = 0; \
|
||||
int64_t preempt = get_cur_preempt(); \
|
||||
#define BEGIN_SHIM(name, args...) \
|
||||
SHIM_ARG_TYPE __shim_##name(args) { \
|
||||
SHIM_ARG_TYPE ret = 0; \
|
||||
int64_t preempt = get_cur_preempt(); \
|
||||
__UNUSED(preempt);
|
||||
|
||||
#define END_SHIM(name) \
|
||||
handle_signals(); \
|
||||
assert(preempt == get_cur_preempt()); \
|
||||
return ret; \
|
||||
#define END_SHIM(name) \
|
||||
handle_signals(); \
|
||||
assert(preempt == get_cur_preempt()); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#define DEFINE_SHIM_SYSCALL(name, n, func, ...) \
|
||||
SHIM_SYSCALL_##n (name, func, __VA_ARGS__) \
|
||||
EXPORT_SHIM_SYSCALL (name, n, __VA_ARGS__)
|
||||
#define DEFINE_SHIM_SYSCALL(name, n, func, ...) \
|
||||
SHIM_SYSCALL_##n(name, func, __VA_ARGS__) \
|
||||
EXPORT_SHIM_SYSCALL(name, n, __VA_ARGS__)
|
||||
|
||||
#define PROTO_ARGS_0() void
|
||||
#define PROTO_ARGS_1(t, a) t a
|
||||
#define PROTO_ARGS_2(t, a, rest ...) t a, PROTO_ARGS_1(rest)
|
||||
#define PROTO_ARGS_3(t, a, rest ...) t a, PROTO_ARGS_2(rest)
|
||||
#define PROTO_ARGS_4(t, a, rest ...) t a, PROTO_ARGS_3(rest)
|
||||
#define PROTO_ARGS_5(t, a, rest ...) t a, PROTO_ARGS_4(rest)
|
||||
#define PROTO_ARGS_6(t, a, rest ...) t a, PROTO_ARGS_5(rest)
|
||||
#define PROTO_ARGS_0() void
|
||||
#define PROTO_ARGS_1(t, a) t a
|
||||
#define PROTO_ARGS_2(t, a, rest...) t a, PROTO_ARGS_1(rest)
|
||||
#define PROTO_ARGS_3(t, a, rest...) t a, PROTO_ARGS_2(rest)
|
||||
#define PROTO_ARGS_4(t, a, rest...) t a, PROTO_ARGS_3(rest)
|
||||
#define PROTO_ARGS_5(t, a, rest...) t a, PROTO_ARGS_4(rest)
|
||||
#define PROTO_ARGS_6(t, a, rest...) t a, PROTO_ARGS_5(rest)
|
||||
|
||||
#define CAST_ARGS_0()
|
||||
#define CAST_ARGS_1(t, a) (SHIM_ARG_TYPE) a
|
||||
#define CAST_ARGS_2(t, a, rest ...) (SHIM_ARG_TYPE) a, CAST_ARGS_1(rest)
|
||||
#define CAST_ARGS_3(t, a, rest ...) (SHIM_ARG_TYPE) a, CAST_ARGS_2(rest)
|
||||
#define CAST_ARGS_4(t, a, rest ...) (SHIM_ARG_TYPE) a, CAST_ARGS_3(rest)
|
||||
#define CAST_ARGS_5(t, a, rest ...) (SHIM_ARG_TYPE) a, CAST_ARGS_4(rest)
|
||||
#define CAST_ARGS_6(t, a, rest ...) (SHIM_ARG_TYPE) a, CAST_ARGS_5(rest)
|
||||
#define CAST_ARGS_1(t, a) (SHIM_ARG_TYPE)a
|
||||
#define CAST_ARGS_2(t, a, rest...) (SHIM_ARG_TYPE)a, CAST_ARGS_1(rest)
|
||||
#define CAST_ARGS_3(t, a, rest...) (SHIM_ARG_TYPE)a, CAST_ARGS_2(rest)
|
||||
#define CAST_ARGS_4(t, a, rest...) (SHIM_ARG_TYPE)a, CAST_ARGS_3(rest)
|
||||
#define CAST_ARGS_5(t, a, rest...) (SHIM_ARG_TYPE)a, CAST_ARGS_4(rest)
|
||||
#define CAST_ARGS_6(t, a, rest...) (SHIM_ARG_TYPE)a, CAST_ARGS_5(rest)
|
||||
|
||||
#define DEFINE_SHIM_FUNC(func, n, r, args ...) \
|
||||
r func (PROTO_ARGS_##n (args));
|
||||
#define DEFINE_SHIM_FUNC(func, n, r, args...) \
|
||||
r func(PROTO_ARGS_##n(args));
|
||||
|
||||
#define TYPE_HASH(t) ({ const char * _s = #t; \
|
||||
((uint16_t) _s[0] << 8) + _s[1]; })
|
||||
#define TYPE_HASH(t) \
|
||||
({ \
|
||||
const char* _s = #t; \
|
||||
((uint16_t)_s[0] << 8) + _s[1]; \
|
||||
})
|
||||
|
||||
#define POINTER_TYPE(t) ({ int _h = TYPE_HASH(t); \
|
||||
_h == TYPE_HASH(void *) || _h == TYPE_HASH(char *) || \
|
||||
_h == TYPE_HASH(const); })
|
||||
#define POINTER_TYPE(t) \
|
||||
({ \
|
||||
int _h = TYPE_HASH(t); \
|
||||
_h == TYPE_HASH(void*) || _h == TYPE_HASH(char*) || _h == TYPE_HASH(const); \
|
||||
})
|
||||
|
||||
#define EXPORT_SHIM_SYSCALL(name, n, r, args ...) \
|
||||
r shim_##name (PROTO_ARGS_##n (args)) { \
|
||||
SHIM_ARG_TYPE ret = __shim_##name (CAST_ARGS_##n (args)); \
|
||||
if (POINTER_TYPE(r)) { \
|
||||
if ((uint64_t) ret >= (uint64_t) -4095L) return (r) 0; \
|
||||
} else { \
|
||||
if ((int) ret < 0) return (r) -1; \
|
||||
} \
|
||||
return (r) ret; \
|
||||
#define EXPORT_SHIM_SYSCALL(name, n, r, args...) \
|
||||
r shim_##name(PROTO_ARGS_##n(args)) { \
|
||||
SHIM_ARG_TYPE ret = __shim_##name(CAST_ARGS_##n(args)); \
|
||||
if (POINTER_TYPE(r)) { \
|
||||
if ((uint64_t)ret >= (uint64_t)-4095L) \
|
||||
return (r)0; \
|
||||
} else { \
|
||||
if ((int)ret < 0) \
|
||||
return (r)-1; \
|
||||
} \
|
||||
return (r)ret; \
|
||||
}
|
||||
|
||||
#define PARSE_SYSCALL1(name, ...) \
|
||||
if (debug_handle) \
|
||||
#define PARSE_SYSCALL1(name, ...) \
|
||||
if (debug_handle) \
|
||||
parse_syscall_before(__NR_##name, #name, ##__VA_ARGS__);
|
||||
|
||||
#define PARSE_SYSCALL2(name, ...) \
|
||||
if (debug_handle) \
|
||||
#define PARSE_SYSCALL2(name, ...) \
|
||||
if (debug_handle) \
|
||||
parse_syscall_after(__NR_##name, #name, ##__VA_ARGS__);
|
||||
|
||||
void parse_syscall_before (int sysno, const char * name, int nr, ...);
|
||||
void parse_syscall_after (int sysno, const char * name, int nr, ...);
|
||||
void parse_syscall_before(int sysno, const char* name, int nr, ...);
|
||||
void parse_syscall_after(int sysno, const char* name, int nr, ...);
|
||||
|
||||
#define SHIM_SYSCALL_0(name, func, r) \
|
||||
BEGIN_SHIM(name, void) \
|
||||
PARSE_SYSCALL1(name, 0); \
|
||||
r __ret = (func)(); \
|
||||
PARSE_SYSCALL2(name, 0, #r, __ret); \
|
||||
ret = (SHIM_ARG_TYPE) __ret; \
|
||||
#define SHIM_SYSCALL_0(name, func, r) \
|
||||
BEGIN_SHIM(name, void) \
|
||||
PARSE_SYSCALL1(name, 0); \
|
||||
r __ret = (func)(); \
|
||||
PARSE_SYSCALL2(name, 0, #r, __ret); \
|
||||
ret = (SHIM_ARG_TYPE)__ret; \
|
||||
END_SHIM(name)
|
||||
|
||||
#define SHIM_SYSCALL_1(name, func, r, t1, a1) \
|
||||
BEGIN_SHIM(name, SHIM_ARG_TYPE __arg1) \
|
||||
t1 a1 = (t1) __arg1; \
|
||||
PARSE_SYSCALL1(name, 1, #t1, a1); \
|
||||
r __ret = (func)(a1); \
|
||||
PARSE_SYSCALL2(name, 1, #r, __ret, #t1, a1); \
|
||||
ret = (SHIM_ARG_TYPE) __ret; \
|
||||
#define SHIM_SYSCALL_1(name, func, r, t1, a1) \
|
||||
BEGIN_SHIM(name, SHIM_ARG_TYPE __arg1) \
|
||||
t1 a1 = (t1)__arg1; \
|
||||
PARSE_SYSCALL1(name, 1, #t1, a1); \
|
||||
r __ret = (func)(a1); \
|
||||
PARSE_SYSCALL2(name, 1, #r, __ret, #t1, a1); \
|
||||
ret = (SHIM_ARG_TYPE)__ret; \
|
||||
END_SHIM(name)
|
||||
|
||||
#define SHIM_SYSCALL_2(name, func, r, t1, a1, t2, a2) \
|
||||
BEGIN_SHIM(name, SHIM_ARG_TYPE __arg1, SHIM_ARG_TYPE __arg2) \
|
||||
t1 a1 = (t1) __arg1; \
|
||||
t2 a2 = (t2) __arg2; \
|
||||
PARSE_SYSCALL1(name, 2, #t1, a1, #t2, a2); \
|
||||
r __ret = (func)(a1, a2); \
|
||||
PARSE_SYSCALL2(name, 2, #r, __ret, #t1, a1, #t2, a2); \
|
||||
ret = (SHIM_ARG_TYPE) __ret; \
|
||||
#define SHIM_SYSCALL_2(name, func, r, t1, a1, t2, a2) \
|
||||
BEGIN_SHIM(name, SHIM_ARG_TYPE __arg1, SHIM_ARG_TYPE __arg2) \
|
||||
t1 a1 = (t1)__arg1; \
|
||||
t2 a2 = (t2)__arg2; \
|
||||
PARSE_SYSCALL1(name, 2, #t1, a1, #t2, a2); \
|
||||
r __ret = (func)(a1, a2); \
|
||||
PARSE_SYSCALL2(name, 2, #r, __ret, #t1, a1, #t2, a2); \
|
||||
ret = (SHIM_ARG_TYPE)__ret; \
|
||||
END_SHIM(name)
|
||||
|
||||
#define SHIM_SYSCALL_3(name, func, r, t1, a1, t2, a2, t3, a3) \
|
||||
BEGIN_SHIM(name, SHIM_ARG_TYPE __arg1, SHIM_ARG_TYPE __arg2, \
|
||||
SHIM_ARG_TYPE __arg3) \
|
||||
t1 a1 = (t1) __arg1; \
|
||||
t2 a2 = (t2) __arg2; \
|
||||
t3 a3 = (t3) __arg3; \
|
||||
PARSE_SYSCALL1(name, 3, #t1, a1, #t2, a2, #t3, a3); \
|
||||
r __ret = (func)(a1, a2, a3); \
|
||||
PARSE_SYSCALL2(name, 3, #r, __ret, #t1, a1, #t2, a2, #t3, a3); \
|
||||
ret = (SHIM_ARG_TYPE) __ret; \
|
||||
#define SHIM_SYSCALL_3(name, func, r, t1, a1, t2, a2, t3, a3) \
|
||||
BEGIN_SHIM(name, SHIM_ARG_TYPE __arg1, SHIM_ARG_TYPE __arg2, SHIM_ARG_TYPE __arg3) \
|
||||
t1 a1 = (t1)__arg1; \
|
||||
t2 a2 = (t2)__arg2; \
|
||||
t3 a3 = (t3)__arg3; \
|
||||
PARSE_SYSCALL1(name, 3, #t1, a1, #t2, a2, #t3, a3); \
|
||||
r __ret = (func)(a1, a2, a3); \
|
||||
PARSE_SYSCALL2(name, 3, #r, __ret, #t1, a1, #t2, a2, #t3, a3); \
|
||||
ret = (SHIM_ARG_TYPE)__ret; \
|
||||
END_SHIM(name)
|
||||
|
||||
#define SHIM_SYSCALL_4(name, func, r, t1, a1, t2, a2, t3, a3, t4, a4) \
|
||||
BEGIN_SHIM(name, SHIM_ARG_TYPE __arg1, SHIM_ARG_TYPE __arg2, \
|
||||
SHIM_ARG_TYPE __arg3, SHIM_ARG_TYPE __arg4) \
|
||||
t1 a1 = (t1) __arg1; \
|
||||
t2 a2 = (t2) __arg2; \
|
||||
t3 a3 = (t3) __arg3; \
|
||||
t4 a4 = (t4) __arg4; \
|
||||
PARSE_SYSCALL1(name, 4, #t1, a1, #t2, a2, #t3, a3, #t4, a4); \
|
||||
r __ret = (func)(a1, a2, a3, a4); \
|
||||
PARSE_SYSCALL2(name, 4, #r, __ret, #t1, a1, #t2, a2, #t3, a3, \
|
||||
#t4, a4); \
|
||||
ret = (SHIM_ARG_TYPE) __ret; \
|
||||
#define SHIM_SYSCALL_4(name, func, r, t1, a1, t2, a2, t3, a3, t4, a4) \
|
||||
BEGIN_SHIM(name, SHIM_ARG_TYPE __arg1, SHIM_ARG_TYPE __arg2, SHIM_ARG_TYPE __arg3, \
|
||||
SHIM_ARG_TYPE __arg4) \
|
||||
t1 a1 = (t1)__arg1; \
|
||||
t2 a2 = (t2)__arg2; \
|
||||
t3 a3 = (t3)__arg3; \
|
||||
t4 a4 = (t4)__arg4; \
|
||||
PARSE_SYSCALL1(name, 4, #t1, a1, #t2, a2, #t3, a3, #t4, a4); \
|
||||
r __ret = (func)(a1, a2, a3, a4); \
|
||||
PARSE_SYSCALL2(name, 4, #r, __ret, #t1, a1, #t2, a2, #t3, a3, #t4, a4); \
|
||||
ret = (SHIM_ARG_TYPE)__ret; \
|
||||
END_SHIM(name)
|
||||
|
||||
#define SHIM_SYSCALL_5(name, func, r, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5) \
|
||||
BEGIN_SHIM(name, SHIM_ARG_TYPE __arg1, SHIM_ARG_TYPE __arg2, \
|
||||
SHIM_ARG_TYPE __arg3, SHIM_ARG_TYPE __arg4, \
|
||||
SHIM_ARG_TYPE __arg5) \
|
||||
t1 a1 = (t1) __arg1; \
|
||||
t2 a2 = (t2) __arg2; \
|
||||
t3 a3 = (t3) __arg3; \
|
||||
t4 a4 = (t4) __arg4; \
|
||||
t5 a5 = (t5) __arg5; \
|
||||
PARSE_SYSCALL1(name, 5, #t1, a1, #t2, a2, #t3, a3, #t4, a4, \
|
||||
#t5, a5); \
|
||||
r __ret = (func)(a1, a2, a3, a4, a5); \
|
||||
PARSE_SYSCALL2(name, 5, #r, __ret, #t1, a1, #t2, a2, #t3, a3, \
|
||||
#t4, a4, #t5, a5); \
|
||||
ret = (SHIM_ARG_TYPE) __ret; \
|
||||
#define SHIM_SYSCALL_5(name, func, r, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5) \
|
||||
BEGIN_SHIM(name, SHIM_ARG_TYPE __arg1, SHIM_ARG_TYPE __arg2, SHIM_ARG_TYPE __arg3, \
|
||||
SHIM_ARG_TYPE __arg4, SHIM_ARG_TYPE __arg5) \
|
||||
t1 a1 = (t1)__arg1; \
|
||||
t2 a2 = (t2)__arg2; \
|
||||
t3 a3 = (t3)__arg3; \
|
||||
t4 a4 = (t4)__arg4; \
|
||||
t5 a5 = (t5)__arg5; \
|
||||
PARSE_SYSCALL1(name, 5, #t1, a1, #t2, a2, #t3, a3, #t4, a4, #t5, a5); \
|
||||
r __ret = (func)(a1, a2, a3, a4, a5); \
|
||||
PARSE_SYSCALL2(name, 5, #r, __ret, #t1, a1, #t2, a2, #t3, a3, #t4, a4, #t5, a5); \
|
||||
ret = (SHIM_ARG_TYPE)__ret; \
|
||||
END_SHIM(name)
|
||||
|
||||
#define SHIM_SYSCALL_6(name, func, r, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6) \
|
||||
BEGIN_SHIM(name, SHIM_ARG_TYPE __arg1, SHIM_ARG_TYPE __arg2, \
|
||||
SHIM_ARG_TYPE __arg3, SHIM_ARG_TYPE __arg4, \
|
||||
SHIM_ARG_TYPE __arg5, SHIM_ARG_TYPE __arg6) \
|
||||
t1 a1 = (t1) __arg1; \
|
||||
t2 a2 = (t2) __arg2; \
|
||||
t3 a3 = (t3) __arg3; \
|
||||
t4 a4 = (t4) __arg4; \
|
||||
t5 a5 = (t5) __arg5; \
|
||||
t6 a6 = (t6) __arg6; \
|
||||
PARSE_SYSCALL1(name, 6, #t1, a1, #t2, a2, #t3, a3, #t4, a4, \
|
||||
#t5, a5, #t6, a6); \
|
||||
r __ret = (func)(a1, a2, a3, a4, a5, a6); \
|
||||
PARSE_SYSCALL2(name, 6, #r, __ret, #t1, a1, #t2, a2, #t3, a3, \
|
||||
#t4, a4, #t5, a5, #t6, a6); \
|
||||
ret = (SHIM_ARG_TYPE) __ret; \
|
||||
#define SHIM_SYSCALL_6(name, func, r, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6) \
|
||||
BEGIN_SHIM(name, SHIM_ARG_TYPE __arg1, SHIM_ARG_TYPE __arg2, SHIM_ARG_TYPE __arg3, \
|
||||
SHIM_ARG_TYPE __arg4, SHIM_ARG_TYPE __arg5, SHIM_ARG_TYPE __arg6) \
|
||||
t1 a1 = (t1)__arg1; \
|
||||
t2 a2 = (t2)__arg2; \
|
||||
t3 a3 = (t3)__arg3; \
|
||||
t4 a4 = (t4)__arg4; \
|
||||
t5 a5 = (t5)__arg5; \
|
||||
t6 a6 = (t6)__arg6; \
|
||||
PARSE_SYSCALL1(name, 6, #t1, a1, #t2, a2, #t3, a3, #t4, a4, #t5, a5, #t6, a6); \
|
||||
r __ret = (func)(a1, a2, a3, a4, a5, a6); \
|
||||
PARSE_SYSCALL2(name, 6, #r, __ret, #t1, a1, #t2, a2, #t3, a3, #t4, a4, #t5, a5, #t6, a6); \
|
||||
ret = (SHIM_ARG_TYPE)__ret; \
|
||||
END_SHIM(name)
|
||||
|
||||
#define SHIM_PROTO_ARGS_0 void
|
||||
@@ -331,30 +330,36 @@ void parse_syscall_after (int sysno, const char * name, int nr, ...);
|
||||
|
||||
#define SHIM_UNUSED_ARGS_0()
|
||||
|
||||
#define SHIM_UNUSED_ARGS_1() do { \
|
||||
__UNUSED(__arg1); \
|
||||
#define SHIM_UNUSED_ARGS_1() \
|
||||
do { \
|
||||
__UNUSED(__arg1); \
|
||||
} while (0)
|
||||
#define SHIM_UNUSED_ARGS_2() do { \
|
||||
SHIM_UNUSED_ARGS_1(); \
|
||||
__UNUSED(__arg2); \
|
||||
#define SHIM_UNUSED_ARGS_2() \
|
||||
do { \
|
||||
SHIM_UNUSED_ARGS_1(); \
|
||||
__UNUSED(__arg2); \
|
||||
} while (0)
|
||||
#define SHIM_UNUSED_ARGS_3() do { \
|
||||
SHIM_UNUSED_ARGS_2(); \
|
||||
__UNUSED(__arg3); \
|
||||
#define SHIM_UNUSED_ARGS_3() \
|
||||
do { \
|
||||
SHIM_UNUSED_ARGS_2(); \
|
||||
__UNUSED(__arg3); \
|
||||
} while (0)
|
||||
#define SHIM_UNUSED_ARGS_4() do { \
|
||||
SHIM_UNUSED_ARGS_3(); \
|
||||
__UNUSED(__arg4); \
|
||||
#define SHIM_UNUSED_ARGS_4() \
|
||||
do { \
|
||||
SHIM_UNUSED_ARGS_3(); \
|
||||
__UNUSED(__arg4); \
|
||||
} while (0)
|
||||
|
||||
#define SHIM_UNUSED_ARGS_5() do { \
|
||||
SHIM_UNUSED_ARGS_4(); \
|
||||
__UNUSED(__arg5); \
|
||||
#define SHIM_UNUSED_ARGS_5() \
|
||||
do { \
|
||||
SHIM_UNUSED_ARGS_4(); \
|
||||
__UNUSED(__arg5); \
|
||||
} while (0)
|
||||
|
||||
#define SHIM_UNUSED_ARGS_6() do { \
|
||||
SHIM_UNUSED_ARGS_5(); \
|
||||
__UNUSED(__arg6); \
|
||||
#define SHIM_UNUSED_ARGS_6() \
|
||||
do { \
|
||||
SHIM_UNUSED_ARGS_5(); \
|
||||
__UNUSED(__arg6); \
|
||||
} while (0)
|
||||
|
||||
#define SHIM_SYSCALL_PROTO_0(NAME, RTYPE) \
|
||||
@@ -387,67 +392,61 @@ void parse_syscall_after (int sysno, const char * name, int nr, ...);
|
||||
END_SHIM(name) \
|
||||
EXPORT_SHIM_SYSCALL(name, n, __VA_ARGS__)
|
||||
|
||||
#define CONCAT2(t1, t2) __CONCAT2(t1, t2)
|
||||
#define CONCAT2(t1, t2) __CONCAT2(t1, t2)
|
||||
#define __CONCAT2(t1, t2) t1##_##t2
|
||||
|
||||
#define CONCAT3(t1, t2, t3) __CONCAT3(t1, t2, t3)
|
||||
#define CONCAT3(t1, t2, t3) __CONCAT3(t1, t2, t3)
|
||||
#define __CONCAT3(t1, t2, t3) t1##_##t2##_##t3
|
||||
|
||||
/* Some SHIM internal errno */
|
||||
#define EISLINK 141 /* the path is a link */
|
||||
#define ECONTAINLINK 142 /* part of path contains a link */
|
||||
#define ENOTLINK 143 /* the path is not a link */
|
||||
#define ESKIPPED 144 /* skip looking up current path */
|
||||
#define EISLINK 141 /* the path is a link */
|
||||
#define ECONTAINLINK 142 /* part of path contains a link */
|
||||
#define ENOTLINK 143 /* the path is not a link */
|
||||
#define ESKIPPED 144 /* skip looking up current path */
|
||||
|
||||
#define PAL_CB(member) (pal_control.member)
|
||||
#define PAL_CB(member) (pal_control.member)
|
||||
|
||||
#define LOCK_FREE ((IDTYPE) -1)
|
||||
#define LOCK_FREE ((IDTYPE)-1)
|
||||
|
||||
extern bool lock_enabled;
|
||||
|
||||
static inline void enable_locking (void)
|
||||
{
|
||||
static inline void enable_locking(void) {
|
||||
if (!lock_enabled)
|
||||
lock_enabled = true;
|
||||
}
|
||||
|
||||
static inline PAL_HANDLE thread_create (void * func, void * arg)
|
||||
{
|
||||
static inline PAL_HANDLE thread_create(void* func, void* arg) {
|
||||
assert(lock_enabled);
|
||||
return DkThreadCreate(func, arg);
|
||||
}
|
||||
|
||||
static inline int64_t __disable_preempt (shim_tcb_t * tcb)
|
||||
{
|
||||
//tcb->context.syscall_nr += SYSCALL_NR_PREEMPT_INC;
|
||||
static inline int64_t __disable_preempt(shim_tcb_t* tcb) {
|
||||
// tcb->context.syscall_nr += SYSCALL_NR_PREEMPT_INC;
|
||||
int64_t preempt = __atomic_add_fetch(&tcb->context.preempt.counter, 1, __ATOMIC_SEQ_CST);
|
||||
/* Assert if this counter overflows */
|
||||
assert(preempt != 0);
|
||||
//debug("disable preempt: %d\n", preempt);
|
||||
// debug("disable preempt: %d\n", preempt);
|
||||
return preempt;
|
||||
}
|
||||
|
||||
static inline void disable_preempt (shim_tcb_t * tcb)
|
||||
{
|
||||
static inline void disable_preempt(shim_tcb_t* tcb) {
|
||||
if (!tcb && !(tcb = shim_get_tcb()))
|
||||
return;
|
||||
|
||||
__disable_preempt(tcb);
|
||||
}
|
||||
|
||||
static inline void __enable_preempt (shim_tcb_t * tcb)
|
||||
{
|
||||
static inline void __enable_preempt(shim_tcb_t* tcb) {
|
||||
int64_t preempt = __atomic_sub_fetch(&tcb->context.preempt.counter, 1, __ATOMIC_SEQ_CST);
|
||||
/* Assert if this counter underflows */
|
||||
__UNUSED(preempt);
|
||||
assert(preempt >= 0);
|
||||
//debug("enable preempt: %d\n", preempt);
|
||||
// debug("enable preempt: %d\n", preempt);
|
||||
}
|
||||
|
||||
void __handle_signals(shim_tcb_t* tcb);
|
||||
|
||||
static inline void enable_preempt (shim_tcb_t * tcb)
|
||||
{
|
||||
static inline void enable_preempt(shim_tcb_t* tcb) {
|
||||
if (!tcb && !(tcb = shim_get_tcb()))
|
||||
return;
|
||||
|
||||
@@ -461,26 +460,24 @@ static inline void enable_preempt (shim_tcb_t * tcb)
|
||||
__enable_preempt(tcb);
|
||||
}
|
||||
|
||||
static inline bool lock_created(struct shim_lock* l)
|
||||
{
|
||||
static inline bool lock_created(struct shim_lock* l) {
|
||||
return l->lock != NULL;
|
||||
}
|
||||
|
||||
static inline void clear_lock(struct shim_lock* l)
|
||||
{
|
||||
l->lock = NULL;
|
||||
static inline void clear_lock(struct shim_lock* l) {
|
||||
l->lock = NULL;
|
||||
l->owner = 0;
|
||||
}
|
||||
|
||||
static inline bool create_lock(struct shim_lock* l) {
|
||||
l->owner = 0;
|
||||
l->lock = DkMutexCreate(0);
|
||||
l->lock = DkMutexCreate(0);
|
||||
return l->lock != NULL;
|
||||
}
|
||||
|
||||
static inline void destroy_lock(struct shim_lock* l) {
|
||||
DkObjectClose(l->lock);
|
||||
l->lock = NULL;
|
||||
l->lock = NULL;
|
||||
l->owner = 0;
|
||||
}
|
||||
|
||||
@@ -502,7 +499,7 @@ static void lock(struct shim_lock* l) {
|
||||
__abort();
|
||||
}
|
||||
|
||||
shim_tcb_t * tcb = shim_get_tcb();
|
||||
shim_tcb_t* tcb = shim_get_tcb();
|
||||
disable_preempt(tcb);
|
||||
|
||||
while (!DkSynchronizationObjectWait(l->lock, NO_TIMEOUT))
|
||||
@@ -549,19 +546,25 @@ static inline bool locked(struct shim_lock* l) {
|
||||
extern struct shim_lock __master_lock;
|
||||
|
||||
#if DEBUG_MASTER_LOCK == 1
|
||||
# define MASTER_LOCK() \
|
||||
do { \
|
||||
lock(&__master_lock); \
|
||||
pal_printf("master lock " __FILE__ ":%d\n", __LINE__); \
|
||||
#define MASTER_LOCK() \
|
||||
do { \
|
||||
lock(&__master_lock); \
|
||||
pal_printf("master lock " __FILE__ ":%d\n", __LINE__); \
|
||||
} while (0)
|
||||
# define MASTER_UNLOCK() \
|
||||
do { \
|
||||
pal_printf("master unlock " __FILE__ ":%d\n", __LINE__); \
|
||||
unlock(&__master_lock); \
|
||||
#define MASTER_UNLOCK() \
|
||||
do { \
|
||||
pal_printf("master unlock " __FILE__ ":%d\n", __LINE__); \
|
||||
unlock(&__master_lock); \
|
||||
} while (0)
|
||||
#else
|
||||
# define MASTER_LOCK() do { lock(&__master_lock); } while (0)
|
||||
# define MASTER_UNLOCK() do { unlock(&__master_lock); } while (0)
|
||||
#define MASTER_LOCK() \
|
||||
do { \
|
||||
lock(&__master_lock); \
|
||||
} while (0)
|
||||
#define MASTER_UNLOCK() \
|
||||
do { \
|
||||
unlock(&__master_lock); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
static inline bool create_lock_runtime(struct shim_lock* l) {
|
||||
@@ -577,41 +580,34 @@ static inline bool create_lock_runtime(struct shim_lock* l) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void create_event (AEVENTTYPE * e)
|
||||
{
|
||||
static inline void create_event(AEVENTTYPE* e) {
|
||||
if (!e->event)
|
||||
e->event = DkStreamOpen(URI_PREFIX_PIPE, PAL_ACCESS_RDWR, 0, 0,
|
||||
PAL_OPTION_NONBLOCK);
|
||||
e->event = DkStreamOpen(URI_PREFIX_PIPE, PAL_ACCESS_RDWR, 0, 0, PAL_OPTION_NONBLOCK);
|
||||
}
|
||||
|
||||
static inline bool event_created (AEVENTTYPE * e)
|
||||
{
|
||||
static inline bool event_created(AEVENTTYPE* e) {
|
||||
return e->event != NULL;
|
||||
}
|
||||
|
||||
static inline PAL_HANDLE event_handle (AEVENTTYPE * e)
|
||||
{
|
||||
static inline PAL_HANDLE event_handle(AEVENTTYPE* e) {
|
||||
return e->event;
|
||||
}
|
||||
|
||||
static inline void destroy_event (AEVENTTYPE * e)
|
||||
{
|
||||
static inline void destroy_event(AEVENTTYPE* e) {
|
||||
if (e->event) {
|
||||
DkObjectClose(e->event);
|
||||
e->event = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void set_event (AEVENTTYPE * e, int n)
|
||||
{
|
||||
static inline void set_event(AEVENTTYPE* e, int n) {
|
||||
if (e->event) {
|
||||
char bytes[n];
|
||||
DkStreamWrite(e->event, 0, n, bytes, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void wait_event (AEVENTTYPE * e)
|
||||
{
|
||||
static inline void wait_event(AEVENTTYPE* e) {
|
||||
if (e->event) {
|
||||
char byte;
|
||||
int n = 0;
|
||||
@@ -621,8 +617,7 @@ static inline void wait_event (AEVENTTYPE * e)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void clear_event (AEVENTTYPE * e)
|
||||
{
|
||||
static inline void clear_event(AEVENTTYPE* e) {
|
||||
if (e->event) {
|
||||
char bytes[100];
|
||||
int n;
|
||||
@@ -633,11 +628,10 @@ static inline void clear_event (AEVENTTYPE * e)
|
||||
}
|
||||
|
||||
/* reference counter APIs */
|
||||
#define REF_GET(ref) __atomic_load_n(&(ref).counter, __ATOMIC_SEQ_CST)
|
||||
#define REF_SET(ref, count) __atomic_store_n(&(ref).counter, count, __ATOMIC_SEQ_CST);
|
||||
#define REF_GET(ref) __atomic_load_n(&(ref).counter, __ATOMIC_SEQ_CST)
|
||||
#define REF_SET(ref, count) __atomic_store_n(&(ref).counter, count, __ATOMIC_SEQ_CST);
|
||||
|
||||
static inline int __ref_inc (REFTYPE * ref)
|
||||
{
|
||||
static inline int __ref_inc(REFTYPE* ref) {
|
||||
int64_t _c;
|
||||
do {
|
||||
_c = __atomic_load_n(&ref->counter, __ATOMIC_SEQ_CST);
|
||||
@@ -647,10 +641,9 @@ static inline int __ref_inc (REFTYPE * ref)
|
||||
return _c + 1;
|
||||
}
|
||||
|
||||
#define REF_INC(ref) __ref_inc(&(ref))
|
||||
#define REF_INC(ref) __ref_inc(&(ref))
|
||||
|
||||
static inline int __ref_dec (REFTYPE * ref)
|
||||
{
|
||||
static inline int __ref_dec(REFTYPE* ref) {
|
||||
int64_t _c;
|
||||
do {
|
||||
_c = __atomic_load_n(&ref->counter, __ATOMIC_SEQ_CST);
|
||||
@@ -667,7 +660,7 @@ static inline int __ref_dec (REFTYPE * ref)
|
||||
#define REF_DEC(ref) __ref_dec(&(ref))
|
||||
|
||||
#ifndef __alloca
|
||||
# define __alloca __builtin_alloca
|
||||
#define __alloca __builtin_alloca
|
||||
#endif
|
||||
|
||||
extern size_t g_pal_alloc_align;
|
||||
@@ -679,40 +672,40 @@ extern size_t g_pal_alloc_align;
|
||||
#define ALLOC_ALIGN_DOWN_PTR(x) ALIGN_DOWN_PTR_POW2(x, g_pal_alloc_align)
|
||||
#define ALLOC_ALIGN_UP_PTR(x) ALIGN_UP_PTR_POW2(x, g_pal_alloc_align)
|
||||
|
||||
void * __system_malloc (size_t size);
|
||||
void __system_free (void * addr, size_t size);
|
||||
void* __system_malloc(size_t size);
|
||||
void __system_free(void* addr, size_t size);
|
||||
|
||||
#define system_malloc __system_malloc
|
||||
#define system_free __system_free
|
||||
#define system_free __system_free
|
||||
|
||||
extern void * migrated_memory_start;
|
||||
extern void * migrated_memory_end;
|
||||
extern void* migrated_memory_start;
|
||||
extern void* migrated_memory_end;
|
||||
|
||||
static inline bool memory_migrated(void * mem)
|
||||
{
|
||||
static inline bool memory_migrated(void* mem) {
|
||||
return mem >= migrated_memory_start && mem < migrated_memory_end;
|
||||
}
|
||||
|
||||
extern void* __load_address;
|
||||
extern void* __load_address_end;
|
||||
extern void* __code_address;
|
||||
extern void* __code_address_end;
|
||||
|
||||
extern void * __load_address, * __load_address_end;
|
||||
extern void * __code_address, * __code_address_end;
|
||||
|
||||
unsigned long parse_int (const char * str);
|
||||
unsigned long parse_int(const char* str);
|
||||
|
||||
extern const char** migrated_argv;
|
||||
extern const char** migrated_envp;
|
||||
|
||||
struct shim_handle;
|
||||
int init_brk_from_executable (struct shim_handle * exec);
|
||||
int init_brk_from_executable(struct shim_handle* exec);
|
||||
int init_brk_region(void* brk_region, size_t data_segment_size);
|
||||
void reset_brk(void);
|
||||
int init_internal_map (void);
|
||||
int init_loader (void);
|
||||
int init_manifest (PAL_HANDLE manifest_handle);
|
||||
int init_internal_map(void);
|
||||
int init_loader(void);
|
||||
int init_manifest(PAL_HANDLE manifest_handle);
|
||||
int init_rlimit(void);
|
||||
|
||||
bool test_user_memory (void * addr, size_t size, bool write);
|
||||
bool test_user_string (const char * addr);
|
||||
bool test_user_memory(void* addr, size_t size, bool write);
|
||||
bool test_user_string(const char* addr);
|
||||
|
||||
uint64_t get_rlimit_cur(int resource);
|
||||
void set_rlimit_cur(int resource, uint64_t rlim);
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
#ifndef _SHIM_IPC_H_
|
||||
#define _SHIM_IPC_H_
|
||||
|
||||
#include <list.h>
|
||||
#include <pal.h>
|
||||
#include <shim_defs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_sysv.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_types.h>
|
||||
#include "list.h"
|
||||
#include "pal.h"
|
||||
#include "shim_defs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_sysv.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_types.h"
|
||||
|
||||
/* if callback func returns RESPONSE_CALLBACK, send response msg even if callback succeeded */
|
||||
#define RESPONSE_CALLBACK 1
|
||||
@@ -26,7 +26,7 @@
|
||||
#define LEASE_TIME 1000
|
||||
|
||||
#define IPC_MSG_MINIMAL_SIZE 48
|
||||
#define IPC_SEM_NOTIMEOUT ((unsigned long)-1)
|
||||
#define IPC_SEM_NOTIMEOUT ((unsigned long)-1)
|
||||
#define MAX_IPC_PORT_FINI_CB 3
|
||||
|
||||
enum {
|
||||
@@ -48,10 +48,10 @@ enum {
|
||||
IPC_PORT_DIRECTCHILD = 1 << IPC_DIRECTCHILD,
|
||||
IPC_PORT_DIRECTPARENT = 1 << IPC_DIRECTPARENT,
|
||||
|
||||
IPC_PORT_CLIENT = 1 << IPC_CLIENT,
|
||||
IPC_PORT_LEADER = 1 << IPC_LEADER,
|
||||
IPC_PORT_OWNER = 1 << IPC_OWNER,
|
||||
IPC_PORT_CONNECTION = 1 << IPC_CONNECTION,
|
||||
IPC_PORT_CLIENT = 1 << IPC_CLIENT,
|
||||
IPC_PORT_LEADER = 1 << IPC_LEADER,
|
||||
IPC_PORT_OWNER = 1 << IPC_OWNER,
|
||||
IPC_PORT_CONNECTION = 1 << IPC_CONNECTION,
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -470,7 +470,7 @@ struct shim_ipc_msg_with_ack* pop_ipc_msg_with_ack(struct shim_ipc_port* port, u
|
||||
int broadcast_ipc(struct shim_ipc_msg* msg, int target_type, struct shim_ipc_port* exclude_port);
|
||||
int send_ipc_message(struct shim_ipc_msg* msg, struct shim_ipc_port* port);
|
||||
int send_ipc_message_with_ack(struct shim_ipc_msg_with_ack* msg, struct shim_ipc_port* port,
|
||||
unsigned long* seq, void* private_data);
|
||||
unsigned long* seq, void* private_data);
|
||||
int send_response_ipc_message(struct shim_ipc_port* port, IDTYPE dest, int ret, unsigned long seq);
|
||||
|
||||
void ipc_port_with_child_fini(struct shim_ipc_port* port, IDTYPE vmid, unsigned int exitcode);
|
||||
|
||||
@@ -1,89 +1,98 @@
|
||||
#ifndef _SHIM_SIGNAL_H_
|
||||
#define _SHIM_SIGNAL_H_
|
||||
|
||||
#include <shim_types.h>
|
||||
#include <shim_defs.h>
|
||||
#include <ucontext.h>
|
||||
#include "shim_defs.h"
|
||||
#include "shim_types.h"
|
||||
#include "ucontext.h"
|
||||
|
||||
void sigaction_make_defaults(struct __kernel_sigaction* sig_action);
|
||||
void thread_sigaction_reset_on_execve(struct shim_thread* thread);
|
||||
|
||||
# define BITS_PER_WORD (8 * sizeof(unsigned long))
|
||||
#define BITS_PER_WORD (8 * sizeof(unsigned long))
|
||||
/* The standard def of this macro is dumb */
|
||||
#undef _SIGSET_NWORDS
|
||||
# define _SIGSET_NWORDS (NUM_SIGS / BITS_PER_WORD)
|
||||
#define _SIGSET_NWORDS (NUM_SIGS / BITS_PER_WORD)
|
||||
|
||||
/* Return a mask that includes the bit for SIG only. */
|
||||
# define __sigmask(sig) \
|
||||
(((unsigned long int) 1) << (((sig) - 1) % (8 * sizeof (unsigned long int))))
|
||||
#define __sigmask(sig) \
|
||||
(((unsigned long int)1) << (((sig) - 1) % (8 * sizeof(unsigned long int))))
|
||||
|
||||
/* Return the word index for SIG. */
|
||||
# define __sigword(sig) (((sig) - 1) / (8 * sizeof (unsigned long int)))
|
||||
#define __sigword(sig) (((sig) - 1) / (8 * sizeof(unsigned long int)))
|
||||
|
||||
/* Clear all signals from SET. */
|
||||
# define __sigemptyset(set) \
|
||||
(__extension__ ({ int __cnt = _SIGSET_NWORDS; \
|
||||
__sigset_t *__set = (set); \
|
||||
while (--__cnt >= 0) __set->__val[__cnt] = 0; \
|
||||
0; }))
|
||||
#define __sigemptyset(set) \
|
||||
(__extension__({ \
|
||||
int __cnt = _SIGSET_NWORDS; \
|
||||
__sigset_t* __set = (set); \
|
||||
while (--__cnt >= 0) \
|
||||
__set->__val[__cnt] = 0; \
|
||||
0; \
|
||||
}))
|
||||
|
||||
/* Set all signals in SET. */
|
||||
# define __sigfillset(set) \
|
||||
(__extension__ ({ int __cnt = _SIGSET_NWORDS; \
|
||||
__sigset_t *__set = (set); \
|
||||
while (--__cnt >= 0) __set->__val[__cnt] = ~0UL; \
|
||||
0; }))
|
||||
#define __sigfillset(set) \
|
||||
(__extension__({ \
|
||||
int __cnt = _SIGSET_NWORDS; \
|
||||
__sigset_t* __set = (set); \
|
||||
while (--__cnt >= 0) \
|
||||
__set->__val[__cnt] = ~0UL; \
|
||||
0; \
|
||||
}))
|
||||
|
||||
# define __sigisemptyset(set) \
|
||||
(__extension__ ({ int __cnt = _SIGSET_NWORDS; \
|
||||
const __sigset_t *__set = (set); \
|
||||
int __ret = __set->__val[--__cnt]; \
|
||||
while (!__ret && --__cnt >= 0) \
|
||||
__ret = __set->__val[__cnt]; \
|
||||
__ret == 0; }))
|
||||
#define __sigisemptyset(set) \
|
||||
(__extension__({ \
|
||||
int __cnt = _SIGSET_NWORDS; \
|
||||
const __sigset_t* __set = (set); \
|
||||
int __ret = __set->__val[--__cnt]; \
|
||||
while (!__ret && --__cnt >= 0) \
|
||||
__ret = __set->__val[__cnt]; \
|
||||
__ret == 0; \
|
||||
}))
|
||||
|
||||
# define __sigandset(dest, left, right) \
|
||||
(__extension__ ({ int __cnt = _SIGSET_NWORDS; \
|
||||
__sigset_t *__dest = (dest); \
|
||||
const __sigset_t *__left = (left); \
|
||||
const __sigset_t *__right = (right); \
|
||||
while (--__cnt >= 0) \
|
||||
__dest->__val[__cnt] = (__left->__val[__cnt] \
|
||||
& __right->__val[__cnt]); \
|
||||
0; }))
|
||||
#define __sigandset(dest, left, right) \
|
||||
(__extension__({ \
|
||||
int __cnt = _SIGSET_NWORDS; \
|
||||
__sigset_t* __dest = (dest); \
|
||||
const __sigset_t* __left = (left); \
|
||||
const __sigset_t* __right = (right); \
|
||||
while (--__cnt >= 0) \
|
||||
__dest->__val[__cnt] = (__left->__val[__cnt] & __right->__val[__cnt]); \
|
||||
0; \
|
||||
}))
|
||||
|
||||
# define __sigorset(dest, left, right) \
|
||||
(__extension__ ({ int __cnt = _SIGSET_NWORDS; \
|
||||
__sigset_t *__dest = (dest); \
|
||||
const __sigset_t *__left = (left); \
|
||||
const __sigset_t *__right = (right); \
|
||||
while (--__cnt >= 0) \
|
||||
__dest->__val[__cnt] = (__left->__val[__cnt] \
|
||||
| __right->__val[__cnt]); \
|
||||
0; }))
|
||||
#define __sigorset(dest, left, right) \
|
||||
(__extension__({ \
|
||||
int __cnt = _SIGSET_NWORDS; \
|
||||
__sigset_t* __dest = (dest); \
|
||||
const __sigset_t* __left = (left); \
|
||||
const __sigset_t* __right = (right); \
|
||||
while (--__cnt >= 0) \
|
||||
__dest->__val[__cnt] = (__left->__val[__cnt] | __right->__val[__cnt]); \
|
||||
0; \
|
||||
}))
|
||||
|
||||
# define __signotset(dest, left, right) \
|
||||
(__extension__ ({ int __cnt = _SIGSET_NWORDS; \
|
||||
__sigset_t *__dest = (dest); \
|
||||
const __sigset_t *__left = (left); \
|
||||
const __sigset_t *__right = (right); \
|
||||
while (--__cnt >= 0) \
|
||||
__dest->__val[__cnt] = (__left->__val[__cnt] \
|
||||
& ~__right->__val[__cnt]); \
|
||||
0; }))
|
||||
#define __signotset(dest, left, right) \
|
||||
(__extension__({ \
|
||||
int __cnt = _SIGSET_NWORDS; \
|
||||
__sigset_t* __dest = (dest); \
|
||||
const __sigset_t* __left = (left); \
|
||||
const __sigset_t* __right = (right); \
|
||||
while (--__cnt >= 0) \
|
||||
__dest->__val[__cnt] = (__left->__val[__cnt] & ~__right->__val[__cnt]); \
|
||||
0; \
|
||||
}))
|
||||
|
||||
# define __SIGSETFN(NAME, BODY, CONST) \
|
||||
static inline int \
|
||||
NAME (CONST __sigset_t *__set, int __sig) \
|
||||
{ \
|
||||
unsigned long int __mask = __sigmask (__sig); \
|
||||
unsigned long int __word = __sigword (__sig); \
|
||||
return BODY; \
|
||||
#define __SIGSETFN(NAME, BODY, CONST) \
|
||||
static inline int NAME(CONST __sigset_t* __set, int __sig) { \
|
||||
unsigned long int __mask = __sigmask(__sig); \
|
||||
unsigned long int __word = __sigword(__sig); \
|
||||
return BODY; \
|
||||
}
|
||||
|
||||
__SIGSETFN (shim_sigismember, (__set->__val[__word] & __mask) ? 1 : 0, __const)
|
||||
__SIGSETFN (shim_sigaddset, ((__set->__val[__word] |= __mask), 0), )
|
||||
__SIGSETFN (shim_sigdelset, ((__set->__val[__word] &= ~__mask), 0), )
|
||||
__SIGSETFN(shim_sigismember, (__set->__val[__word] & __mask) ? 1 : 0, __const)
|
||||
__SIGSETFN(shim_sigaddset, ((__set->__val[__word] |= __mask), 0), )
|
||||
__SIGSETFN(shim_sigdelset, ((__set->__val[__word] &= ~__mask), 0), )
|
||||
|
||||
#define __sigismember shim_sigismember
|
||||
#define __sigaddset shim_sigaddset
|
||||
@@ -91,32 +100,29 @@ __SIGSETFN (shim_sigdelset, ((__set->__val[__word] &= ~__mask), 0), )
|
||||
|
||||
/* NB: Check shim_signal.c if this changes. Some memset(0) elision*/
|
||||
struct shim_signal {
|
||||
siginfo_t info;
|
||||
bool context_stored;
|
||||
ucontext_t context;
|
||||
PAL_CONTEXT * pal_context;
|
||||
siginfo_t info;
|
||||
bool context_stored;
|
||||
ucontext_t context;
|
||||
PAL_CONTEXT* pal_context;
|
||||
};
|
||||
|
||||
void get_pending_signals(struct shim_thread* thread, __sigset_t* set);
|
||||
|
||||
struct shim_thread;
|
||||
|
||||
int init_signal (void);
|
||||
int init_signal(void);
|
||||
|
||||
void __store_context (shim_tcb_t * tcb, PAL_CONTEXT * pal_context,
|
||||
struct shim_signal * signal);
|
||||
void __store_context(shim_tcb_t* tcb, PAL_CONTEXT* pal_context, struct shim_signal* signal);
|
||||
|
||||
int append_signal(struct shim_thread* thread, siginfo_t* info);
|
||||
|
||||
void deliver_signal(siginfo_t* info, PAL_CONTEXT* context);
|
||||
|
||||
__sigset_t * get_sig_mask (struct shim_thread * thread);
|
||||
__sigset_t * set_sig_mask (struct shim_thread * thread,
|
||||
const __sigset_t * new_set);
|
||||
__sigset_t* get_sig_mask(struct shim_thread* thread);
|
||||
__sigset_t* set_sig_mask(struct shim_thread* thread, const __sigset_t* new_set);
|
||||
|
||||
int do_kill_thread (IDTYPE sender, IDTYPE tgid, IDTYPE tid, int sig,
|
||||
bool use_ipc);
|
||||
int do_kill_proc (IDTYPE sender, IDTYPE tgid, int sig, bool use_ipc);
|
||||
int do_kill_pgroup (IDTYPE sender, IDTYPE pgid, int sig, bool use_ipc);
|
||||
int do_kill_thread(IDTYPE sender, IDTYPE tgid, IDTYPE tid, int sig, bool use_ipc);
|
||||
int do_kill_proc(IDTYPE sender, IDTYPE tgid, int sig, bool use_ipc);
|
||||
int do_kill_pgroup(IDTYPE sender, IDTYPE pgid, int sig, bool use_ipc);
|
||||
|
||||
#endif /* _SHIM_SIGNAL_H_ */
|
||||
|
||||
@@ -11,8 +11,9 @@
|
||||
#ifndef __SHIM_SYSV_H__
|
||||
#define __SHIM_SYSV_H__
|
||||
|
||||
#include <shim_handle.h>
|
||||
#include <shim_types.h>
|
||||
#include "list.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_types.h"
|
||||
|
||||
#define SYSV_TYPE_STR(type) \
|
||||
((type) == SYSV_MSGQ ? "MSGQ" \
|
||||
@@ -28,8 +29,6 @@ struct shim_handle;
|
||||
|
||||
#define MSG_NOERROR 010000
|
||||
|
||||
#include <list.h>
|
||||
|
||||
struct __kernel_msgbuf {
|
||||
long mtype; /* type of message */
|
||||
char mtext[]; /* message text */
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
#ifndef _SHIM_TABLE_H_
|
||||
#define _SHIM_TABLE_H_
|
||||
|
||||
#include <shim_types.h>
|
||||
#include <shim_unistd.h>
|
||||
#include <stdnoreturn.h>
|
||||
#if defined(__i386__) || defined (__x86_64__)
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#include <asm/ldt.h>
|
||||
#endif
|
||||
|
||||
#include "shim_types.h"
|
||||
#include "shim_unistd.h"
|
||||
|
||||
#ifdef IN_SHIM
|
||||
|
||||
void debug_unsupp(int num);
|
||||
@@ -493,8 +494,8 @@ int shim_do_accept4(int sockfd, struct sockaddr* addr, int* addrlen, int flags);
|
||||
int shim_do_dup3(unsigned int oldfd, unsigned int newfd, int flags);
|
||||
int shim_do_epoll_create1(int flags);
|
||||
int shim_do_pipe2(int* fildes, int flags);
|
||||
int shim_do_mknod(const char *pathname, mode_t mode, dev_t dev);
|
||||
int shim_do_mknodat(int dirfd, const char *pathname, mode_t mode, dev_t dev);
|
||||
int shim_do_mknod(const char* pathname, mode_t mode, dev_t dev);
|
||||
int shim_do_mknodat(int dirfd, const char* pathname, mode_t mode, dev_t dev);
|
||||
ssize_t shim_do_recvmmsg(int sockfd, struct mmsghdr* msg, unsigned int vlen, int flags,
|
||||
struct __kernel_timespec* timeout);
|
||||
int shim_do_prlimit64(pid_t pid, int resource, const struct __kernel_rlimit64* new_rlim,
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
#ifndef _SHIM_TCB_H_
|
||||
#define _SHIM_TCB_H_
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "api.h"
|
||||
#include "assert.h"
|
||||
#include "atomic.h"
|
||||
#include "pal.h"
|
||||
|
||||
#include "shim_tcb-arch.h"
|
||||
|
||||
#define SHIM_TCB_CANARY 0xdeadbeef
|
||||
|
||||
struct shim_context {
|
||||
struct shim_regs * regs;
|
||||
uint64_t fs_base;
|
||||
struct atomic_int preempt;
|
||||
struct shim_regs* regs;
|
||||
uint64_t fs_base;
|
||||
struct atomic_int preempt;
|
||||
};
|
||||
|
||||
static inline unsigned long shim_context_get_sp(struct shim_context* sc) {
|
||||
@@ -50,15 +48,16 @@ struct shim_tcb {
|
||||
* If a segfault occurs with the range [start, end],
|
||||
* the code addr is set to cont_addr to alert the caller. */
|
||||
struct {
|
||||
void * start, * end;
|
||||
void * cont_addr;
|
||||
void* start;
|
||||
void* end;
|
||||
void* cont_addr;
|
||||
bool has_fault;
|
||||
} test_range;
|
||||
};
|
||||
|
||||
static inline void __shim_tcb_init(shim_tcb_t* shim_tcb) {
|
||||
shim_tcb->canary = SHIM_TCB_CANARY;
|
||||
shim_tcb->self = shim_tcb;
|
||||
shim_tcb->canary = SHIM_TCB_CANARY;
|
||||
shim_tcb->self = shim_tcb;
|
||||
shim_tcb->vma_cache = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
#ifndef _SHIM_THREAD_H_
|
||||
#define _SHIM_THREAD_H_
|
||||
|
||||
#include <shim_defs.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_tcb.h>
|
||||
#include <shim_utils.h>
|
||||
#include <shim_signal.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_vma.h>
|
||||
|
||||
#include <api.h>
|
||||
#include <pal.h>
|
||||
#include <list.h>
|
||||
#include "api.h"
|
||||
#include "list.h"
|
||||
#include "pal.h"
|
||||
#include "shim_defs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_signal.h"
|
||||
#include "shim_tcb.h"
|
||||
#include "shim_utils.h"
|
||||
#include "shim_vma.h"
|
||||
|
||||
struct shim_handle;
|
||||
struct shim_fd_map;
|
||||
@@ -63,9 +62,9 @@ struct shim_thread {
|
||||
PAL_HANDLE pal_handle;
|
||||
|
||||
/* parent handle */
|
||||
struct shim_thread * parent;
|
||||
struct shim_thread* parent;
|
||||
/* thread leader */
|
||||
struct shim_thread * leader;
|
||||
struct shim_thread* leader;
|
||||
/* child handles; protected by thread->lock */
|
||||
LISTP_TYPE(shim_thread) children;
|
||||
/* nodes in child handles; protected by the parent's lock */
|
||||
@@ -73,12 +72,12 @@ struct shim_thread {
|
||||
/* nodes in global handles; protected by thread_list_lock */
|
||||
LIST_TYPE(shim_thread) list;
|
||||
|
||||
struct shim_handle_map * handle_map;
|
||||
struct shim_handle_map* handle_map;
|
||||
|
||||
/* child tid */
|
||||
int* set_child_tid;
|
||||
int* clear_child_tid; /* LibOS zeroes it to notify parent that thread exited */
|
||||
int clear_child_tid_pal; /* PAL zeroes it to notify LibOS that thread exited */
|
||||
int* clear_child_tid; /* LibOS zeroes it to notify parent that thread exited */
|
||||
int clear_child_tid_pal; /* PAL zeroes it to notify LibOS that thread exited */
|
||||
|
||||
/* signal handling */
|
||||
__sigset_t signal_mask;
|
||||
@@ -108,34 +107,36 @@ struct shim_thread {
|
||||
LISTP_TYPE(shim_thread) exited_children;
|
||||
|
||||
/* file system */
|
||||
struct shim_dentry * root, * cwd;
|
||||
struct shim_dentry* root;
|
||||
struct shim_dentry* cwd;
|
||||
mode_t umask;
|
||||
|
||||
/* executable */
|
||||
struct shim_handle * exec;
|
||||
struct shim_handle* exec;
|
||||
|
||||
void * stack, * stack_top, * stack_red;
|
||||
shim_tcb_t * shim_tcb;
|
||||
void * frameptr;
|
||||
void* stack;
|
||||
void* stack_top;
|
||||
void* stack_red;
|
||||
shim_tcb_t* shim_tcb;
|
||||
void* frameptr;
|
||||
|
||||
REFTYPE ref_count;
|
||||
struct shim_lock lock;
|
||||
};
|
||||
|
||||
int init_thread (void);
|
||||
int init_thread(void);
|
||||
|
||||
static inline bool is_internal(struct shim_thread *thread)
|
||||
{
|
||||
static inline bool is_internal(struct shim_thread* thread) {
|
||||
return thread->tid >= INTERNAL_TID_BASE;
|
||||
}
|
||||
|
||||
void get_signal_handles(struct shim_signal_handles* handles);
|
||||
void put_signal_handles(struct shim_signal_handles* handles);
|
||||
|
||||
void get_thread (struct shim_thread * thread);
|
||||
void put_thread (struct shim_thread * thread);
|
||||
void get_thread(struct shim_thread* thread);
|
||||
void put_thread(struct shim_thread* thread);
|
||||
|
||||
void debug_setprefix (shim_tcb_t * tcb);
|
||||
void debug_setprefix(shim_tcb_t* tcb);
|
||||
|
||||
static inline void debug_setbuf(shim_tcb_t* tcb,
|
||||
struct debug_buf* debug_buf) {
|
||||
@@ -179,9 +180,7 @@ static inline void set_cur_thread(struct shim_thread* thread) {
|
||||
}
|
||||
}
|
||||
|
||||
static inline void thread_setwait (struct shim_thread ** queue,
|
||||
struct shim_thread * thread)
|
||||
{
|
||||
static inline void thread_setwait(struct shim_thread** queue, struct shim_thread* thread) {
|
||||
if (!thread)
|
||||
thread = get_cur_thread();
|
||||
DkEventClear(thread->scheduler_event);
|
||||
@@ -191,9 +190,8 @@ static inline void thread_setwait (struct shim_thread ** queue,
|
||||
}
|
||||
}
|
||||
|
||||
static inline int thread_sleep (uint64_t timeout_us)
|
||||
{
|
||||
struct shim_thread * cur_thread = get_cur_thread();
|
||||
static inline int thread_sleep(uint64_t timeout_us) {
|
||||
struct shim_thread* cur_thread = get_cur_thread();
|
||||
|
||||
if (!cur_thread)
|
||||
return -EINVAL;
|
||||
@@ -208,8 +206,7 @@ static inline int thread_sleep (uint64_t timeout_us)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void thread_wakeup (struct shim_thread * thread)
|
||||
{
|
||||
static inline void thread_wakeup(struct shim_thread* thread) {
|
||||
DkEventSet(thread->scheduler_event);
|
||||
}
|
||||
|
||||
@@ -262,15 +259,15 @@ extern struct shim_lock thread_list_lock;
|
||||
*/
|
||||
struct shim_thread* lookup_thread(IDTYPE tid);
|
||||
|
||||
void set_as_child (struct shim_thread * parent, struct shim_thread * child);
|
||||
void set_as_child(struct shim_thread* parent, struct shim_thread* child);
|
||||
|
||||
/* creating and revoking thread objects */
|
||||
struct shim_thread * get_new_thread (IDTYPE new_tid);
|
||||
struct shim_thread * get_new_internal_thread (void);
|
||||
struct shim_thread* get_new_thread(IDTYPE new_tid);
|
||||
struct shim_thread* get_new_internal_thread(void);
|
||||
|
||||
/* thread list utilities */
|
||||
void add_thread (struct shim_thread * thread);
|
||||
void del_thread (struct shim_thread * thread);
|
||||
void add_thread(struct shim_thread* thread);
|
||||
void del_thread(struct shim_thread* thread);
|
||||
|
||||
void cleanup_thread(IDTYPE caller, void* thread);
|
||||
bool mark_self_dead(void);
|
||||
@@ -281,8 +278,8 @@ int walk_thread_list(int (*callback)(struct shim_thread*, void*), void* arg, boo
|
||||
void dump_threads(void);
|
||||
|
||||
/* reference counting of handle maps */
|
||||
void get_handle_map (struct shim_handle_map * map);
|
||||
void put_handle_map (struct shim_handle_map * map);
|
||||
void get_handle_map(struct shim_handle_map* map);
|
||||
void put_handle_map(struct shim_handle_map* map);
|
||||
|
||||
/* retriving handle mapping */
|
||||
static inline struct shim_handle_map* get_cur_handle_map(struct shim_thread* thread) {
|
||||
@@ -315,14 +312,14 @@ void release_robust_list(struct robust_list_head* head);
|
||||
struct shim_clone_args {
|
||||
PAL_HANDLE create_event;
|
||||
PAL_HANDLE initialize_event;
|
||||
struct shim_thread * parent, * thread;
|
||||
void * stack;
|
||||
struct shim_thread* parent;
|
||||
struct shim_thread* thread;
|
||||
void* stack;
|
||||
unsigned long fs_base;
|
||||
};
|
||||
|
||||
void * allocate_stack (size_t size, size_t protect_size, bool user);
|
||||
void* allocate_stack(size_t size, size_t protect_size, bool user);
|
||||
|
||||
int init_stack(const char** argv, const char** envp, const char*** out_argp,
|
||||
elf_auxv_t** out_auxv);
|
||||
int init_stack(const char** argv, const char** envp, const char*** out_argp, elf_auxv_t** out_auxv);
|
||||
|
||||
#endif /* _SHIM_THREAD_H_ */
|
||||
|
||||
@@ -1,78 +1,79 @@
|
||||
#ifndef _SHIM_TYPES_H_
|
||||
#define _SHIM_TYPES_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define __KERNEL__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/times.h>
|
||||
#include <linux/shm.h>
|
||||
#include <linux/msg.h>
|
||||
#include <linux/sem.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/utime.h>
|
||||
#include <linux/futex.h>
|
||||
#include <asm/poll.h>
|
||||
#include <asm/posix_types.h>
|
||||
#include <asm/siginfo.h>
|
||||
#include <asm/signal.h>
|
||||
#include <asm/stat.h>
|
||||
#include <asm/statfs.h>
|
||||
#include <linux/aio_abi.h>
|
||||
#include <linux/futex.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/msg.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <linux/sem.h>
|
||||
#include <linux/shm.h>
|
||||
#include <linux/times.h>
|
||||
#include <linux/timex.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/utime.h>
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#include <asm/posix_types.h>
|
||||
#include <asm/statfs.h>
|
||||
#include <asm/stat.h>
|
||||
#include <asm/signal.h>
|
||||
#include <asm/siginfo.h>
|
||||
#include <asm/poll.h>
|
||||
|
||||
#include "elf.h"
|
||||
#include "pal.h"
|
||||
#include "shim_types-arch.h"
|
||||
|
||||
typedef unsigned int __u32;
|
||||
typedef unsigned int __u32;
|
||||
|
||||
typedef unsigned long int nfds_t;
|
||||
typedef unsigned long int nlink_t;
|
||||
typedef unsigned long int nfds_t;
|
||||
typedef unsigned long int nlink_t;
|
||||
|
||||
typedef __kernel_uid_t uid_t;
|
||||
typedef __kernel_gid_t gid_t;
|
||||
typedef __kernel_pid_t pid_t;
|
||||
typedef __kernel_caddr_t caddr_t;
|
||||
typedef __kernel_mode_t mode_t;
|
||||
typedef __kernel_off_t off_t;
|
||||
typedef __kernel_loff_t loff_t;
|
||||
typedef __kernel_time_t time_t;
|
||||
typedef __kernel_old_dev_t dev_t;
|
||||
typedef __kernel_ino_t ino_t;
|
||||
typedef __kernel_clockid_t clockid_t;
|
||||
typedef __kernel_key_t key_t;
|
||||
typedef __kernel_timer_t timer_t;
|
||||
typedef __kernel_fd_set fd_set;
|
||||
typedef __kernel_uid_t uid_t;
|
||||
typedef __kernel_gid_t gid_t;
|
||||
typedef __kernel_pid_t pid_t;
|
||||
typedef __kernel_caddr_t caddr_t;
|
||||
typedef __kernel_mode_t mode_t;
|
||||
typedef __kernel_off_t off_t;
|
||||
typedef __kernel_loff_t loff_t;
|
||||
typedef __kernel_time_t time_t;
|
||||
typedef __kernel_old_dev_t dev_t;
|
||||
typedef __kernel_ino_t ino_t;
|
||||
typedef __kernel_clockid_t clockid_t;
|
||||
typedef __kernel_key_t key_t;
|
||||
typedef __kernel_timer_t timer_t;
|
||||
typedef __kernel_fd_set fd_set;
|
||||
|
||||
/* linux/time.h */
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 18, 0)
|
||||
struct __kernel_timespec {
|
||||
__kernel_time_t tv_sec; /* seconds */
|
||||
long tv_nsec; /* nanoseconds */
|
||||
__kernel_time_t tv_sec; /* seconds */
|
||||
long tv_nsec; /* nanoseconds */
|
||||
};
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)
|
||||
struct __kernel_itimerspec {
|
||||
struct __kernel_timespec it_interval; /* timer period */
|
||||
struct __kernel_timespec it_value; /* timer expiration */
|
||||
struct __kernel_timespec it_interval; /* timer period */
|
||||
struct __kernel_timespec it_value; /* timer expiration */
|
||||
};
|
||||
#endif
|
||||
|
||||
struct __kernel_timeval {
|
||||
__kernel_time_t tv_sec; /* seconds */
|
||||
__kernel_suseconds_t tv_usec; /* microsecond */
|
||||
__kernel_time_t tv_sec; /* seconds */
|
||||
__kernel_suseconds_t tv_usec; /* microsecond */
|
||||
};
|
||||
|
||||
struct __kernel_itimerval {
|
||||
struct __kernel_timeval it_interval; /* time interval */
|
||||
struct __kernel_timeval it_value; /* current value */
|
||||
struct __kernel_timeval it_interval; /* time interval */
|
||||
struct __kernel_timeval it_value; /* current value */
|
||||
};
|
||||
|
||||
struct __kernel_timezone {
|
||||
@@ -80,73 +81,75 @@ struct __kernel_timezone {
|
||||
int tz_dsttime; /* type of dst correction */
|
||||
};
|
||||
|
||||
|
||||
/* linux/time.h
|
||||
* syscall interface - used (mainly by NTP daemon)
|
||||
* to discipline kernel clock oscillator
|
||||
*/
|
||||
struct ____kernel_timex {
|
||||
unsigned int modes; /* mode selector */
|
||||
long offset; /* time offset (usec) */
|
||||
long freq; /* frequency offset (scaled ppm) */
|
||||
long maxerror; /* maximum error (usec) */
|
||||
long esterror; /* estimated error (usec) */
|
||||
int status; /* clock command/status */
|
||||
long constant; /* pll time constant */
|
||||
long precision; /* clock precision (usec) (read only) */
|
||||
long tolerance; /* clock frequency tolerance (ppm)
|
||||
* (read only) */
|
||||
struct __kernel_timeval time; /* (read only) */
|
||||
long tick; /* (modified) usecs between clock ticks */
|
||||
unsigned int modes; /* mode selector */
|
||||
long offset; /* time offset (usec) */
|
||||
long freq; /* frequency offset (scaled ppm) */
|
||||
long maxerror; /* maximum error (usec) */
|
||||
long esterror; /* estimated error (usec) */
|
||||
int status; /* clock command/status */
|
||||
long constant; /* pll time constant */
|
||||
long precision; /* clock precision (usec) (read only) */
|
||||
long tolerance; /* clock frequency tolerance (ppm) (read only) */
|
||||
struct __kernel_timeval time; /* (read only) */
|
||||
long tick; /* (modified) usecs between clock ticks */
|
||||
|
||||
long ppsfreq; /* pps frequency (scaled ppm) (ro) */
|
||||
long jitter; /* pps jitter (us) (ro) */
|
||||
int shift; /* interval duration (s) (shift) (ro) */
|
||||
long stabil; /* pps stability (scaled ppm) (ro) */
|
||||
long jitcnt; /* jitter limit exceeded (ro) */
|
||||
long calcnt; /* calibration intervals (ro) */
|
||||
long errcnt; /* calibration errors (ro) */
|
||||
long stbcnt; /* stability limit exceeded (ro) */
|
||||
long ppsfreq; /* pps frequency (scaled ppm) (ro) */
|
||||
long jitter; /* pps jitter (us) (ro) */
|
||||
int shift; /* interval duration (s) (shift) (ro) */
|
||||
long stabil; /* pps stability (scaled ppm) (ro) */
|
||||
long jitcnt; /* jitter limit exceeded (ro) */
|
||||
long calcnt; /* calibration intervals (ro) */
|
||||
long errcnt; /* calibration errors (ro) */
|
||||
long stbcnt; /* stability limit exceeded (ro) */
|
||||
|
||||
int tai; /* TAI offset (ro) */
|
||||
int tai; /* TAI offset (ro) */
|
||||
|
||||
int :32; int :32; int :32; int :32;
|
||||
int :32; int :32; int :32; int :32;
|
||||
int :32; int :32; int :32;
|
||||
int : 32;
|
||||
int : 32;
|
||||
int : 32;
|
||||
int : 32;
|
||||
int : 32;
|
||||
int : 32;
|
||||
int : 32;
|
||||
int : 32;
|
||||
int : 32;
|
||||
int : 32;
|
||||
int : 32;
|
||||
};
|
||||
|
||||
|
||||
/* /arch/x86/include/asm/posix_types_64.h */
|
||||
typedef unsigned int __kernel_uid_t;
|
||||
typedef unsigned int __kernel_uid_t;
|
||||
typedef __kernel_uid_t __kernel_uid32_t;
|
||||
|
||||
|
||||
/* quota.h */
|
||||
typedef __kernel_uid32_t qid_t; /* Type in which we store ids in memory */
|
||||
|
||||
|
||||
/* capability.h */
|
||||
typedef struct __user_cap_header_struct {
|
||||
__u32 version;
|
||||
int pid;
|
||||
} *cap_user_header_t;
|
||||
}* cap_user_header_t;
|
||||
|
||||
typedef struct __user_cap_data_struct {
|
||||
__u32 effective;
|
||||
__u32 permitted;
|
||||
__u32 inheritable;
|
||||
} *cap_user_data_t;
|
||||
|
||||
}* cap_user_data_t;
|
||||
|
||||
/* defined in function in sysdeps/unix/sysv/linux/sysctl.c */
|
||||
struct __kernel_sysctl_args {
|
||||
int *name; /* integer vector describing variable */
|
||||
int nlen; /* length of this vector */
|
||||
void *oldval; /* 0 or address where to store old value */
|
||||
size_t *oldlenp; /* available room for old value,
|
||||
int* name; /* integer vector describing variable */
|
||||
int nlen; /* length of this vector */
|
||||
void* oldval; /* 0 or address where to store old value */
|
||||
size_t* oldlenp; /* available room for old value,
|
||||
overwritten by actual size of old value */
|
||||
void *newval; /* 0 or address of new value */
|
||||
size_t newlen; /* size of new value */
|
||||
void* newval; /* 0 or address of new value */
|
||||
size_t newlen; /* size of new value */
|
||||
};
|
||||
|
||||
struct __kernel_sched_param {
|
||||
@@ -156,7 +159,7 @@ struct __kernel_sched_param {
|
||||
struct __kernel_sigaction {
|
||||
__sighandler_t k_sa_handler;
|
||||
unsigned long sa_flags;
|
||||
void (*sa_restorer) (void);
|
||||
void (*sa_restorer)(void);
|
||||
__sigset_t sa_mask;
|
||||
};
|
||||
|
||||
@@ -165,22 +168,22 @@ typedef unsigned long aio_context_t;
|
||||
|
||||
/* linux/rlimit.h */
|
||||
struct __kernel_rusage {
|
||||
struct __kernel_timeval ru_utime; /* user time used */
|
||||
struct __kernel_timeval ru_stime; /* system time used */
|
||||
long ru_maxrss; /* maximum resident set size */
|
||||
long ru_ixrss; /* integral shared memory size */
|
||||
long ru_idrss; /* integral unshared data size */
|
||||
long ru_isrss; /* integral unshared stack size */
|
||||
long ru_minflt; /* page reclaims */
|
||||
long ru_majflt; /* page faults */
|
||||
long ru_nswap; /* swaps */
|
||||
long ru_inblock; /* block input operations */
|
||||
long ru_oublock; /* block output operations */
|
||||
long ru_msgsnd; /* messages sent */
|
||||
long ru_msgrcv; /* messages received */
|
||||
long ru_nsignals; /* signals received */
|
||||
long ru_nvcsw; /* voluntary context switches */
|
||||
long ru_nivcsw; /* involuntary " */
|
||||
struct __kernel_timeval ru_utime; /* user time used */
|
||||
struct __kernel_timeval ru_stime; /* system time used */
|
||||
long ru_maxrss; /* maximum resident set size */
|
||||
long ru_ixrss; /* integral shared memory size */
|
||||
long ru_idrss; /* integral unshared data size */
|
||||
long ru_isrss; /* integral unshared stack size */
|
||||
long ru_minflt; /* page reclaims */
|
||||
long ru_majflt; /* page faults */
|
||||
long ru_nswap; /* swaps */
|
||||
long ru_inblock; /* block input operations */
|
||||
long ru_oublock; /* block output operations */
|
||||
long ru_msgsnd; /* messages sent */
|
||||
long ru_msgrcv; /* messages received */
|
||||
long ru_nsignals; /* signals received */
|
||||
long ru_nvcsw; /* voluntary context switches */
|
||||
long ru_nivcsw; /* involuntary " */
|
||||
};
|
||||
|
||||
struct __kernel_rlimit {
|
||||
@@ -208,44 +211,42 @@ __attribute__((packed));
|
||||
#endif
|
||||
|
||||
/* bits/ustat.h */
|
||||
struct __kernel_ustat
|
||||
{
|
||||
__daddr_t f_tfree; /* Number of free blocks. */
|
||||
__ino_t f_tinode; /* Number of free inodes. */
|
||||
struct __kernel_ustat {
|
||||
__daddr_t f_tfree; /* Number of free blocks. */
|
||||
__ino_t f_tinode; /* Number of free inodes. */
|
||||
char f_fname[6];
|
||||
char f_fpack[6];
|
||||
};
|
||||
};
|
||||
|
||||
/* bits/socket.h */
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
MSG_OOB = 0x01, /* Process out-of-band data. */
|
||||
MSG_PEEK = 0x02, /* Peek at incoming messages. */
|
||||
MSG_DONTWAIT = 0x40, /* Nonblocking IO. */
|
||||
MSG_NOSIGNAL = 0x4000, /* Do not generate SIGPIPE. */
|
||||
#define MSG_OOB MSG_OOB
|
||||
#define MSG_PEEK MSG_PEEK
|
||||
#define MSG_OOB MSG_OOB
|
||||
#define MSG_PEEK MSG_PEEK
|
||||
#define MSG_DONTWAIT MSG_DONTWAIT
|
||||
#define MSG_NOSIGNAL MSG_NOSIGNAL
|
||||
};
|
||||
|
||||
struct msghdr {
|
||||
void *msg_name; /* Address to send to/receive from. */
|
||||
int msg_namelen; /* Length of address data. */
|
||||
void* msg_name; /* Address to send to/receive from. */
|
||||
int msg_namelen; /* Length of address data. */
|
||||
|
||||
struct iovec *msg_iov; /* Vector of data to send/receive into. */
|
||||
size_t msg_iovlen; /* Number of elements in the vector. */
|
||||
struct iovec* msg_iov; /* Vector of data to send/receive into. */
|
||||
size_t msg_iovlen; /* Number of elements in the vector. */
|
||||
|
||||
void *msg_control; /* Ancillary data (eg BSD filedesc passing). */
|
||||
size_t msg_controllen; /* Ancillary data buffer length. */
|
||||
void* msg_control; /* Ancillary data (eg BSD filedesc passing). */
|
||||
size_t msg_controllen; /* Ancillary data buffer length. */
|
||||
|
||||
unsigned int msg_flags; /* Flags on received message. */
|
||||
};
|
||||
|
||||
/* For `recvmmsg'. */
|
||||
struct mmsghdr {
|
||||
struct msghdr msg_hdr; /* Actual message header. */
|
||||
unsigned int msg_len; /* Number of received bytes for the entry. */
|
||||
struct msghdr msg_hdr; /* Actual message header. */
|
||||
unsigned int msg_len; /* Number of received bytes for the entry. */
|
||||
};
|
||||
|
||||
/* POSIX.1g specifies this type name for the `sa_family' member. */
|
||||
@@ -255,38 +256,37 @@ typedef unsigned short int sa_family_t;
|
||||
of the data types used for socket addresses, `struct sockaddr',
|
||||
`struct sockaddr_in', `struct sockaddr_un', etc. */
|
||||
|
||||
#define __SOCKADDR_COMMON(sa_prefix) \
|
||||
sa_family_t sa_prefix##family
|
||||
|
||||
#define __SOCKADDR_COMMON(sa_prefix) \
|
||||
sa_family_t sa_prefix##family
|
||||
|
||||
/* Structure describing a generic socket address. */
|
||||
struct sockaddr {
|
||||
__SOCKADDR_COMMON (sa_); /* Common data: address family and length. */
|
||||
char sa_data[14]; /* Address data. */
|
||||
__SOCKADDR_COMMON(sa_); /* Common data: address family and length. */
|
||||
char sa_data[14]; /* Address data. */
|
||||
};
|
||||
|
||||
/* From bits/socket.h */
|
||||
/* Structure large enough to hold any socket address (with the historical
|
||||
exception of AF_UNIX). */
|
||||
struct sockaddr_storage {
|
||||
__SOCKADDR_COMMON(ss_); /* Address family, etc. */
|
||||
__SOCKADDR_COMMON(ss_); /* Address family, etc. */
|
||||
char __ss_padding[128 - sizeof(sa_family_t)];
|
||||
};
|
||||
|
||||
/* linux/mqueue.h */
|
||||
struct __kernel_mq_attr {
|
||||
long mq_flags; /* message queue flags */
|
||||
long mq_maxmsg; /* maximum number of messages */
|
||||
long mq_msgsize; /* maximum message size */
|
||||
long mq_curmsgs; /* number of messages currently queued */
|
||||
long __reserved[4]; /* ignored for input, zeroed for output */
|
||||
long mq_flags; /* message queue flags */
|
||||
long mq_maxmsg; /* maximum number of messages */
|
||||
long mq_msgsize; /* maximum message size */
|
||||
long mq_curmsgs; /* number of messages currently queued */
|
||||
long __reserved[4]; /* ignored for input, zeroed for output */
|
||||
};
|
||||
|
||||
/* bits/uio.h */
|
||||
/* Structure for scatter/gather I/O. */
|
||||
struct iovec {
|
||||
void * iov_base; /* Pointer to data. */
|
||||
size_t iov_len; /* Length of data. */
|
||||
void* iov_base; /* Pointer to data. */
|
||||
size_t iov_len; /* Length of data. */
|
||||
};
|
||||
|
||||
/* bits/sched.h */
|
||||
@@ -294,49 +294,49 @@ struct iovec {
|
||||
typedef unsigned long int __kernel_cpu_mask;
|
||||
|
||||
/* Size definition for CPU sets. */
|
||||
# define __CPU_SETSIZE 1024
|
||||
# define __NCPUBITS (8 * sizeof (__kernel_cpu_mask))
|
||||
#define __CPU_SETSIZE 1024
|
||||
#define __NCPUBITS (8 * sizeof(__kernel_cpu_mask))
|
||||
|
||||
/* Data structure to describe CPU mask. */
|
||||
typedef struct {
|
||||
__kernel_cpu_mask __bits[__CPU_SETSIZE / __NCPUBITS];
|
||||
__kernel_cpu_mask __bits[__CPU_SETSIZE / __NCPUBITS];
|
||||
} __kernel_cpu_set_t;
|
||||
|
||||
struct getcpu_cache {
|
||||
unsigned long blob[128 / sizeof(long)];
|
||||
};
|
||||
|
||||
# undef __CPU_SETSIZE
|
||||
# undef __NCPUBITS
|
||||
#undef __CPU_SETSIZE
|
||||
#undef __NCPUBITS
|
||||
|
||||
#define LINUX_DT_UNKNOWN 0
|
||||
#define LINUX_DT_FIFO 1
|
||||
#define LINUX_DT_CHR 2
|
||||
#define LINUX_DT_DIR 4
|
||||
#define LINUX_DT_BLK 6
|
||||
#define LINUX_DT_REG 8
|
||||
#define LINUX_DT_LNK 10
|
||||
#define LINUX_DT_SOCK 12
|
||||
#define LINUX_DT_WHT 14
|
||||
#define LINUX_DT_UNKNOWN 0
|
||||
#define LINUX_DT_FIFO 1
|
||||
#define LINUX_DT_CHR 2
|
||||
#define LINUX_DT_DIR 4
|
||||
#define LINUX_DT_BLK 6
|
||||
#define LINUX_DT_REG 8
|
||||
#define LINUX_DT_LNK 10
|
||||
#define LINUX_DT_SOCK 12
|
||||
#define LINUX_DT_WHT 14
|
||||
|
||||
struct linux_dirent64 {
|
||||
uint64_t d_ino; /* Inode number */
|
||||
uint64_t d_off; /* Offset to next linux_dirent */
|
||||
unsigned short int d_reclen; /* Length of this linux_dirent */
|
||||
unsigned char d_type;
|
||||
char d_name[]; /* File name (null-terminated) */
|
||||
uint64_t d_ino; /* Inode number */
|
||||
uint64_t d_off; /* Offset to next linux_dirent */
|
||||
unsigned short int d_reclen; /* Length of this linux_dirent */
|
||||
unsigned char d_type;
|
||||
char d_name[]; /* File name (null-terminated) */
|
||||
};
|
||||
|
||||
struct linux_dirent {
|
||||
unsigned long d_ino; /* Inode number */
|
||||
unsigned long d_off; /* Offset to next linux_dirent */
|
||||
unsigned short int d_reclen; /* Length of this linux_dirent */
|
||||
char d_name[]; /* File name (null-terminated) */
|
||||
unsigned long d_ino; /* Inode number */
|
||||
unsigned long d_off; /* Offset to next linux_dirent */
|
||||
unsigned short int d_reclen; /* Length of this linux_dirent */
|
||||
char d_name[]; /* File name (null-terminated) */
|
||||
};
|
||||
|
||||
struct linux_dirent_tail {
|
||||
char pad;
|
||||
unsigned char d_type;
|
||||
char pad;
|
||||
unsigned char d_type;
|
||||
};
|
||||
|
||||
struct linux_file_handle {
|
||||
@@ -345,8 +345,6 @@ struct linux_file_handle {
|
||||
unsigned char f_handle[0];
|
||||
};
|
||||
|
||||
#include "elf.h"
|
||||
|
||||
#ifdef __x86_64__
|
||||
typedef Elf64_auxv_t elf_auxv_t;
|
||||
#else
|
||||
@@ -361,8 +359,6 @@ typedef uint64_t HASHTYPE;
|
||||
|
||||
typedef struct atomic_int REFTYPE;
|
||||
|
||||
#include <pal.h>
|
||||
|
||||
struct shim_lock {
|
||||
PAL_HANDLE lock;
|
||||
IDTYPE owner;
|
||||
@@ -372,21 +368,21 @@ typedef struct shim_aevent {
|
||||
PAL_HANDLE event;
|
||||
} AEVENTTYPE;
|
||||
|
||||
#define STR_SIZE 4096
|
||||
#define STR_SIZE 4096
|
||||
|
||||
struct shim_str {
|
||||
char str[STR_SIZE];
|
||||
};
|
||||
|
||||
#define QSTR_SIZE 32
|
||||
#define QSTR_SIZE 32
|
||||
|
||||
/* Use qstr for names. This has fixed size string + string object
|
||||
* if len > SHIM_QSTR_SIZE then use overflow string */
|
||||
struct shim_qstr {
|
||||
HASHTYPE hash;
|
||||
size_t len;
|
||||
char name[QSTR_SIZE];
|
||||
struct shim_str * oflow;
|
||||
HASHTYPE hash;
|
||||
size_t len;
|
||||
char name[QSTR_SIZE];
|
||||
struct shim_str* oflow;
|
||||
};
|
||||
|
||||
/* maximum length of pipe/FIFO name (should be less than Linux sockaddr_un.sun_path = 108) */
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
#ifndef _SHIM_UTILS_H_
|
||||
#define _SHIM_UTILS_H_
|
||||
|
||||
#include <api.h>
|
||||
#include <list.h>
|
||||
#include <pal.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include "api.h"
|
||||
#include "list.h"
|
||||
#include "pal.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
|
||||
struct shim_handle;
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
struct shim_vma_info {
|
||||
void* addr;
|
||||
size_t length;
|
||||
int prot; // memory protection flags: PROT_*
|
||||
int prot; // memory protection flags: PROT_*
|
||||
int flags; // MAP_* and VMA_*
|
||||
struct shim_handle* file;
|
||||
off_t file_offset;
|
||||
@@ -40,7 +40,6 @@ struct shim_vma_info {
|
||||
#define MAP_SHARED_VALIDATE 0x03
|
||||
#endif // MAP_SHARED_VALIDATE
|
||||
|
||||
|
||||
/* vma is kept for bookkeeping, but the memory is not actually allocated */
|
||||
#define VMA_UNMAPPED 0x10000000
|
||||
/* vma is used internally */
|
||||
|
||||
@@ -2,18 +2,16 @@
|
||||
/* Copyright (C) 2014 Stony Brook University */
|
||||
|
||||
/*
|
||||
* shim_handle.c
|
||||
*
|
||||
* This file contains codes to maintain bookkeeping for handles in library OS.
|
||||
* This file contains code to maintain bookkeeping for handles in library OS.
|
||||
*/
|
||||
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_checkpoint.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_thread.h>
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_checkpoint.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_thread.h"
|
||||
|
||||
static struct shim_lock handle_mgr_lock;
|
||||
|
||||
@@ -24,7 +22,7 @@ static struct shim_lock handle_mgr_lock;
|
||||
#define SYSTEM_LOCKED() locked(&handle_mgr_lock)
|
||||
|
||||
#define OBJ_TYPE struct shim_handle
|
||||
#include <memmgr.h>
|
||||
#include "memmgr.h"
|
||||
|
||||
static MEM_MGR handle_mgr = NULL;
|
||||
|
||||
@@ -44,9 +42,9 @@ static inline int init_tty_handle(struct shim_handle* hdl, bool write) {
|
||||
if ((ret = path_lookupat(NULL, "/dev/tty", LOOKUP_OPEN, &dent, NULL)) < 0)
|
||||
return ret;
|
||||
|
||||
int flags = (write ? O_WRONLY : O_RDONLY) | O_APPEND;
|
||||
int flags = (write ? O_WRONLY : O_RDONLY) | O_APPEND;
|
||||
struct shim_mount* fs = dent->fs;
|
||||
ret = fs->d_ops->open(hdl, dent, flags);
|
||||
ret = fs->d_ops->open(hdl, dent, flags);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -800,7 +798,8 @@ BEGIN_RS_FUNC(handle) {
|
||||
switch (hdl->type) {
|
||||
case TYPE_DEV:
|
||||
/* for device handles, info.dev.dev_ops contains function pointers into LibOS; they may
|
||||
have become invalid due to relocation of LibOS text section in the child, update them */
|
||||
* have become invalid due to relocation of LibOS text section in the child, update them
|
||||
*/
|
||||
if (dev_update_dev_ops(hdl) < 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -2,28 +2,28 @@
|
||||
/* Copyright (C) 2014 Stony Brook University */
|
||||
|
||||
/*
|
||||
* shim_signal.c
|
||||
*
|
||||
* This file contains codes to handle signals and exceptions passed from PAL.
|
||||
* This file contains code for handling signals and exceptions passed from PAL.
|
||||
*/
|
||||
|
||||
#include <stdnoreturn.h>
|
||||
|
||||
#include <shim_internal.h>
|
||||
#include <shim_utils.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_vma.h>
|
||||
#include <shim_checkpoint.h>
|
||||
#include <shim_signal.h>
|
||||
#include <shim_ucontext-arch.h>
|
||||
#include <shim_unistd.h>
|
||||
|
||||
#include <cpu.h>
|
||||
#include <pal.h>
|
||||
#include <stddef.h> /* linux/signal.h misses this dependency (for size_t), at least on Ubuntu 16.04.
|
||||
* We must include it ourselves before including linux/signal.h.
|
||||
*/
|
||||
|
||||
#include <asm/signal.h>
|
||||
#include <stdnoreturn.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "pal.h"
|
||||
#include "shim_checkpoint.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_signal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_ucontext-arch.h"
|
||||
#include "shim_unistd.h"
|
||||
#include "shim_utils.h"
|
||||
#include "shim_vma.h"
|
||||
|
||||
// __rt_sighandler_t is different from __sighandler_t in <asm-generic/signal-defs.h>:
|
||||
// typedef void __signalfn_t(int);
|
||||
@@ -33,8 +33,8 @@ typedef void (*__rt_sighandler_t)(int, siginfo_t*, void*);
|
||||
|
||||
void sigaction_make_defaults(struct __kernel_sigaction* sig_action) {
|
||||
sig_action->k_sa_handler = (void*)SIG_DFL;
|
||||
sig_action->sa_flags = 0;
|
||||
sig_action->sa_restorer = NULL;
|
||||
sig_action->sa_flags = 0;
|
||||
sig_action->sa_restorer = NULL;
|
||||
__sigemptyset(&sig_action->sa_mask);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ void thread_sigaction_reset_on_execve(struct shim_thread* thread) {
|
||||
|
||||
static __rt_sighandler_t default_sighandler[NUM_SIGS];
|
||||
|
||||
static struct shim_signal_queue process_signal_queue = { 0 };
|
||||
static struct shim_signal_queue process_signal_queue = {0};
|
||||
/* This is just an optimization, not to have to check the queue for pending signals. A thread will
|
||||
* be woken up after signal is appended to its queue and will handle all unblocked pending signals
|
||||
* no matter what is the relative ordering of increasing this variable vs. appending signal to
|
||||
@@ -77,7 +77,7 @@ static uint64_t process_pending_signals_cnt = 0;
|
||||
*/
|
||||
static bool is_rt_sq_empty(struct shim_rt_signal_queue* queue) {
|
||||
return __atomic_load_n(&queue->get_idx, __ATOMIC_ACQUIRE)
|
||||
== __atomic_load_n(&queue->put_idx, __ATOMIC_ACQUIRE);
|
||||
== __atomic_load_n(&queue->put_idx, __ATOMIC_ACQUIRE);
|
||||
}
|
||||
|
||||
static bool has_standard_signal(struct shim_signal** queue) {
|
||||
@@ -109,15 +109,14 @@ void get_pending_signals(struct shim_thread* thread, __sigset_t* set) {
|
||||
|
||||
static bool append_standard_signal(struct shim_signal** signal_slot, struct shim_signal* signal) {
|
||||
struct shim_signal* old = NULL;
|
||||
return __atomic_compare_exchange_n(signal_slot, &old, signal, /*weak=*/false,
|
||||
__ATOMIC_RELEASE, __ATOMIC_ACQUIRE);
|
||||
return __atomic_compare_exchange_n(signal_slot, &old, signal, /*weak=*/false, __ATOMIC_RELEASE,
|
||||
__ATOMIC_ACQUIRE);
|
||||
}
|
||||
|
||||
/* In theory `get_idx` and `put_idx` could overflow, but adding signals with 1GHz (10**9 signals
|
||||
* per second) gives a 544 years running time before overflow, which we consider a "safe margin"
|
||||
* for now. */
|
||||
static bool append_rt_signal(struct shim_rt_signal_queue* queue,
|
||||
struct shim_signal* signal) {
|
||||
static bool append_rt_signal(struct shim_rt_signal_queue* queue, struct shim_signal* signal) {
|
||||
uint64_t get_idx;
|
||||
uint64_t put_idx = __atomic_load_n(&queue->put_idx, __ATOMIC_ACQUIRE);
|
||||
do {
|
||||
@@ -213,15 +212,12 @@ static struct shim_signal* process_pop_signal(int sig) {
|
||||
|
||||
static void __handle_one_signal(shim_tcb_t* tcb, struct shim_signal* signal);
|
||||
|
||||
static void __store_info (siginfo_t * info, struct shim_signal * signal)
|
||||
{
|
||||
static void __store_info(siginfo_t* info, struct shim_signal* signal) {
|
||||
if (info)
|
||||
memcpy(&signal->info, info, sizeof(siginfo_t));
|
||||
}
|
||||
|
||||
void __store_context (shim_tcb_t * tcb, PAL_CONTEXT * pal_context,
|
||||
struct shim_signal * signal)
|
||||
{
|
||||
void __store_context(shim_tcb_t* tcb, PAL_CONTEXT* pal_context, struct shim_signal* signal) {
|
||||
ucontext_t* context = &signal->context;
|
||||
|
||||
if (tcb && tcb->context.regs && shim_context_get_syscallnr(&tcb->context)) {
|
||||
@@ -240,9 +236,8 @@ void __store_context (shim_tcb_t * tcb, PAL_CONTEXT * pal_context,
|
||||
}
|
||||
}
|
||||
|
||||
void deliver_signal (siginfo_t * info, PAL_CONTEXT * context)
|
||||
{
|
||||
shim_tcb_t * tcb = shim_get_tcb();
|
||||
void deliver_signal(siginfo_t* info, PAL_CONTEXT* context) {
|
||||
shim_tcb_t* tcb = shim_get_tcb();
|
||||
assert(tcb);
|
||||
|
||||
struct shim_thread* cur_thread = (struct shim_thread*)tcb->tp;
|
||||
@@ -255,7 +250,7 @@ void deliver_signal (siginfo_t * info, PAL_CONTEXT * context)
|
||||
|
||||
int64_t preempt = __disable_preempt(tcb);
|
||||
|
||||
struct shim_signal * signal = __alloca(sizeof(struct shim_signal));
|
||||
struct shim_signal* signal = __alloca(sizeof(struct shim_signal));
|
||||
/* save in signal */
|
||||
memset(signal, 0, sizeof(struct shim_signal));
|
||||
__store_info(info, signal);
|
||||
@@ -263,11 +258,11 @@ void deliver_signal (siginfo_t * info, PAL_CONTEXT * context)
|
||||
signal->pal_context = context;
|
||||
|
||||
if (preempt > 1 || __sigismember(&cur_thread->signal_mask, sig)) {
|
||||
signal = malloc_copy(signal,sizeof(struct shim_signal));
|
||||
signal = malloc_copy(signal, sizeof(struct shim_signal));
|
||||
if (signal) {
|
||||
if (!append_thread_signal(cur_thread, signal)) {
|
||||
debug("Signal %d queue of thread %u is full, dropping the incoming signal\n",
|
||||
sig, tcb->tid);
|
||||
debug("Signal %d queue of thread %u is full, dropping the incoming signal\n", sig,
|
||||
tcb->tid);
|
||||
free(signal);
|
||||
}
|
||||
}
|
||||
@@ -279,25 +274,23 @@ void deliver_signal (siginfo_t * info, PAL_CONTEXT * context)
|
||||
__enable_preempt(tcb);
|
||||
}
|
||||
|
||||
#define ALLOC_SIGINFO(signo, code, member, value) \
|
||||
({ \
|
||||
siginfo_t * _info = __alloca(sizeof(siginfo_t)); \
|
||||
memset(_info, 0, sizeof(siginfo_t)); \
|
||||
_info->si_signo = (signo); \
|
||||
_info->si_code = (code); \
|
||||
_info->member = (value); \
|
||||
_info; \
|
||||
#define ALLOC_SIGINFO(signo, code, member, value) \
|
||||
({ \
|
||||
siginfo_t* _info = __alloca(sizeof(siginfo_t)); \
|
||||
memset(_info, 0, sizeof(siginfo_t)); \
|
||||
_info->si_signo = (signo); \
|
||||
_info->si_code = (code); \
|
||||
_info->member = (value); \
|
||||
_info; \
|
||||
})
|
||||
|
||||
static inline bool context_is_internal(PAL_CONTEXT * context)
|
||||
{
|
||||
static inline bool context_is_internal(PAL_CONTEXT* context) {
|
||||
if (!context)
|
||||
return false;
|
||||
|
||||
void* ip = (void*)pal_context_get_ip(context);
|
||||
|
||||
return ip >= (void*)&__code_address &&
|
||||
ip < (void*)&__code_address_end;
|
||||
return (void*)&__code_address <= ip && ip < (void*)&__code_address_end;
|
||||
}
|
||||
|
||||
static noreturn void internal_fault(const char* errstr, PAL_NUM addr, PAL_CONTEXT* context) {
|
||||
@@ -305,40 +298,35 @@ static noreturn void internal_fault(const char* errstr, PAL_NUM addr, PAL_CONTEX
|
||||
PAL_NUM ip = pal_context_get_ip(context);
|
||||
|
||||
if (context_is_internal(context))
|
||||
SYS_PRINTF("%s at 0x%08lx (IP = +0x%lx, VMID = %u, TID = %u)\n", errstr,
|
||||
addr, (void*)ip - (void*)&__load_address,
|
||||
cur_process.vmid, is_internal_tid(tid) ? 0 : tid);
|
||||
SYS_PRINTF("%s at 0x%08lx (IP = +0x%lx, VMID = %u, TID = %u)\n", errstr, addr,
|
||||
(void*)ip - (void*)&__load_address, cur_process.vmid,
|
||||
is_internal_tid(tid) ? 0 : tid);
|
||||
else
|
||||
SYS_PRINTF("%s at 0x%08lx (IP = 0x%08lx, VMID = %u, TID = %u)\n", errstr,
|
||||
addr, context ? ip : 0,
|
||||
cur_process.vmid, is_internal_tid(tid) ? 0 : tid);
|
||||
SYS_PRINTF("%s at 0x%08lx (IP = 0x%08lx, VMID = %u, TID = %u)\n", errstr, addr,
|
||||
context ? ip : 0, cur_process.vmid, is_internal_tid(tid) ? 0 : tid);
|
||||
|
||||
DEBUG_BREAK_ON_FAILURE();
|
||||
DkProcessExit(1);
|
||||
}
|
||||
|
||||
static void arithmetic_error_upcall (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
|
||||
{
|
||||
static void arithmetic_error_upcall(PAL_PTR event, PAL_NUM arg, PAL_CONTEXT* context) {
|
||||
if (is_internal_tid(get_cur_tid()) || context_is_internal(context)) {
|
||||
internal_fault("Internal arithmetic fault", arg, context);
|
||||
} else {
|
||||
if (context)
|
||||
debug("arithmetic fault at 0x%08lx\n", pal_context_get_ip(context));
|
||||
|
||||
deliver_signal(ALLOC_SIGINFO(SIGFPE, FPE_INTDIV,
|
||||
si_addr, (void *) arg), context);
|
||||
deliver_signal(ALLOC_SIGINFO(SIGFPE, FPE_INTDIV, si_addr, (void*)arg), context);
|
||||
}
|
||||
DkExceptionReturn(event);
|
||||
}
|
||||
|
||||
static void memfault_upcall (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
|
||||
{
|
||||
shim_tcb_t * tcb = shim_get_tcb();
|
||||
static void memfault_upcall(PAL_PTR event, PAL_NUM arg, PAL_CONTEXT* context) {
|
||||
shim_tcb_t* tcb = shim_get_tcb();
|
||||
assert(tcb);
|
||||
|
||||
if (tcb->test_range.cont_addr
|
||||
&& (void *) arg >= tcb->test_range.start
|
||||
&& (void *) arg <= tcb->test_range.end) {
|
||||
if (tcb->test_range.cont_addr && (void*)arg >= tcb->test_range.start &&
|
||||
(void*)arg <= tcb->test_range.end) {
|
||||
assert(context);
|
||||
tcb->test_range.has_fault = true;
|
||||
pal_context_set_ip(context, (PAL_NUM)tcb->test_range.cont_addr);
|
||||
@@ -357,7 +345,7 @@ static void memfault_upcall (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
|
||||
int code;
|
||||
if (!arg) {
|
||||
code = SEGV_MAPERR;
|
||||
} else if (!lookup_vma((void *) arg, &vma_info)) {
|
||||
} else if (!lookup_vma((void*)arg, &vma_info)) {
|
||||
if (vma_info.flags & VMA_INTERNAL) {
|
||||
internal_fault("Internal memory fault with VMA", arg, context);
|
||||
}
|
||||
@@ -366,7 +354,7 @@ static void memfault_upcall (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
|
||||
/* DEP 3/3/17: If the mapping exceeds end of a file (but is in the VMA)
|
||||
* then return a SIGBUS. */
|
||||
uintptr_t eof_in_vma = (uintptr_t)vma_info.addr + vma_info.file_offset
|
||||
+ file->info.file.size;
|
||||
+ file->info.file.size;
|
||||
if (arg > eof_in_vma) {
|
||||
signo = SIGBUS;
|
||||
code = BUS_ADRERR;
|
||||
@@ -391,7 +379,7 @@ static void memfault_upcall (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
|
||||
code = SEGV_MAPERR;
|
||||
}
|
||||
|
||||
deliver_signal(ALLOC_SIGINFO(signo, code, si_addr, (void *) arg), context);
|
||||
deliver_signal(ALLOC_SIGINFO(signo, code, si_addr, (void*)arg), context);
|
||||
|
||||
ret_exception:
|
||||
DkExceptionReturn(event);
|
||||
@@ -415,13 +403,12 @@ ret_exception:
|
||||
* The second option is faster in fault-free case but cannot be used under
|
||||
* SGX PAL. We use the best option for each PAL for now. */
|
||||
static bool is_sgx_pal(void) {
|
||||
static struct atomic_int sgx_pal = { .counter = 0 };
|
||||
static struct atomic_int inited = { .counter = 0 };
|
||||
static struct atomic_int sgx_pal = {.counter = 0};
|
||||
static struct atomic_int inited = {.counter = 0};
|
||||
|
||||
if (!__atomic_load_n(&inited.counter, __ATOMIC_SEQ_CST)) {
|
||||
/* Ensure that is_sgx_pal is updated before initialized */
|
||||
__atomic_store_n(&sgx_pal.counter,
|
||||
!strcmp_static(PAL_CB(host_type), "Linux-SGX"),
|
||||
__atomic_store_n(&sgx_pal.counter, !strcmp_static(PAL_CB(host_type), "Linux-SGX"),
|
||||
__ATOMIC_SEQ_CST);
|
||||
__atomic_store_n(&inited.counter, 1, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
@@ -438,8 +425,7 @@ static bool is_sgx_pal(void) {
|
||||
* with a concurrent system call. The purpose of these functions is simply for
|
||||
* the compatibility with programs that rely on the error numbers, such as the
|
||||
* LTP test suite. */
|
||||
bool test_user_memory (void * addr, size_t size, bool write)
|
||||
{
|
||||
bool test_user_memory(void* addr, size_t size, bool write) {
|
||||
if (!size)
|
||||
return false;
|
||||
|
||||
@@ -452,7 +438,7 @@ bool test_user_memory (void * addr, size_t size, bool write)
|
||||
|
||||
/* Non-SGX path: check if [addr, addr+size) is addressable by touching
|
||||
* a byte of each page; invalid access will be caught in memfault_upcall */
|
||||
shim_tcb_t * tcb = shim_get_tcb();
|
||||
shim_tcb_t* tcb = shim_get_tcb();
|
||||
assert(tcb && tcb->tp);
|
||||
__disable_preempt(tcb);
|
||||
|
||||
@@ -461,25 +447,25 @@ bool test_user_memory (void * addr, size_t size, bool write)
|
||||
assert(!tcb->test_range.cont_addr);
|
||||
tcb->test_range.has_fault = false;
|
||||
tcb->test_range.cont_addr = &&ret_fault;
|
||||
tcb->test_range.start = addr;
|
||||
tcb->test_range.end = addr + size - 1;
|
||||
tcb->test_range.start = addr;
|
||||
tcb->test_range.end = addr + size - 1;
|
||||
/* enforce compiler to store tcb->test_range into memory */
|
||||
__asm__ volatile(""::: "memory");
|
||||
__asm__ volatile("" ::: "memory");
|
||||
|
||||
/* Try to read or write into one byte inside each page */
|
||||
void * tmp = addr;
|
||||
void* tmp = addr;
|
||||
while (tmp <= addr + size - 1) {
|
||||
if (write) {
|
||||
*(volatile char *) tmp = *(volatile char *) tmp;
|
||||
*(volatile char*)tmp = *(volatile char*)tmp;
|
||||
} else {
|
||||
*(volatile char *) tmp;
|
||||
*(volatile char*)tmp;
|
||||
}
|
||||
tmp = ALLOC_ALIGN_UP_PTR(tmp + 1);
|
||||
}
|
||||
|
||||
ret_fault:
|
||||
/* enforce compiler to load tcb->test_range.has_fault below */
|
||||
__asm__ volatile("": "=m"(tcb->test_range.has_fault));
|
||||
__asm__ volatile("" : "=m"(tcb->test_range.has_fault));
|
||||
|
||||
/* If any read or write into the target region causes an exception,
|
||||
* the control flow will immediately jump to here. */
|
||||
@@ -495,8 +481,7 @@ ret_fault:
|
||||
* This function tests a user string with unknown length. It only tests
|
||||
* whether the memory is readable.
|
||||
*/
|
||||
bool test_user_string (const char * addr)
|
||||
{
|
||||
bool test_user_string(const char* addr) {
|
||||
if (!access_ok(addr, 1))
|
||||
return true;
|
||||
|
||||
@@ -510,7 +495,7 @@ bool test_user_string (const char * addr)
|
||||
do {
|
||||
maxlen = next - addr;
|
||||
|
||||
if (!access_ok(addr, maxlen) || !is_in_adjacent_user_vmas((void*) addr, maxlen))
|
||||
if (!access_ok(addr, maxlen) || !is_in_adjacent_user_vmas((void*)addr, maxlen))
|
||||
return true;
|
||||
|
||||
size = strnlen(addr, maxlen);
|
||||
@@ -523,7 +508,7 @@ bool test_user_string (const char * addr)
|
||||
|
||||
/* Non-SGX path: check if [addr, addr+size) is addressable by touching
|
||||
* a byte of each page; invalid access will be caught in memfault_upcall. */
|
||||
shim_tcb_t * tcb = shim_get_tcb();
|
||||
shim_tcb_t* tcb = shim_get_tcb();
|
||||
assert(tcb && tcb->tp);
|
||||
__disable_preempt(tcb);
|
||||
|
||||
@@ -531,19 +516,19 @@ bool test_user_string (const char * addr)
|
||||
tcb->test_range.has_fault = false;
|
||||
tcb->test_range.cont_addr = &&ret_fault;
|
||||
/* enforce compiler to store tcb->test_range into memory */
|
||||
__asm__ volatile(""::: "memory");
|
||||
__asm__ volatile("" ::: "memory");
|
||||
|
||||
do {
|
||||
/* Add the memory region to the watch list. This is not racy because
|
||||
* each thread has its own record. */
|
||||
tcb->test_range.start = (void *) addr;
|
||||
tcb->test_range.end = (void *) (next - 1);
|
||||
tcb->test_range.start = (void*)addr;
|
||||
tcb->test_range.end = (void*)(next - 1);
|
||||
|
||||
maxlen = next - addr;
|
||||
|
||||
if (!access_ok(addr, maxlen))
|
||||
return true;
|
||||
*(volatile char *) addr; /* try to read one byte from the page */
|
||||
*(volatile char*)addr; /* try to read one byte from the page */
|
||||
|
||||
size = strnlen(addr, maxlen);
|
||||
addr = next;
|
||||
@@ -552,7 +537,7 @@ bool test_user_string (const char * addr)
|
||||
|
||||
ret_fault:
|
||||
/* enforce compiler to load tcb->test_range.has_fault below */
|
||||
__asm__ volatile("": "=m"(tcb->test_range.has_fault));
|
||||
__asm__ volatile("" : "=m"(tcb->test_range.has_fault));
|
||||
|
||||
/* If any read or write into the target region causes an exception,
|
||||
* the control flow will immediately jump to here. */
|
||||
@@ -564,8 +549,7 @@ ret_fault:
|
||||
return has_fault;
|
||||
}
|
||||
|
||||
void __attribute__((weak)) syscall_wrapper(void)
|
||||
{
|
||||
void __attribute__((weak)) syscall_wrapper(void) {
|
||||
/*
|
||||
* work around for link.
|
||||
* syscalldb.S is excluded for libsysdb_debug.so so it fails to link
|
||||
@@ -573,15 +557,11 @@ void __attribute__((weak)) syscall_wrapper(void)
|
||||
*/
|
||||
}
|
||||
|
||||
static void illegal_upcall (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
|
||||
{
|
||||
struct shim_vma_info vma_info = { .file = NULL };
|
||||
|
||||
if (!is_internal_tid(get_cur_tid()) &&
|
||||
!context_is_internal(context) &&
|
||||
!(lookup_vma((void *)arg, &vma_info)) &&
|
||||
!(vma_info.flags & VMA_INTERNAL)) {
|
||||
static void illegal_upcall(PAL_PTR event, PAL_NUM arg, PAL_CONTEXT* context) {
|
||||
struct shim_vma_info vma_info = {.file = NULL};
|
||||
|
||||
if (!is_internal_tid(get_cur_tid()) && !context_is_internal(context) &&
|
||||
!(lookup_vma((void*)arg, &vma_info)) && !(vma_info.flags & VMA_INTERNAL)) {
|
||||
assert(context);
|
||||
|
||||
uint8_t* rip = (uint8_t*)pal_context_get_ip(context);
|
||||
@@ -623,8 +603,7 @@ static void illegal_upcall (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
|
||||
} else {
|
||||
debug("Illegal instruction during app execution at 0x%08lx; delivering to app\n",
|
||||
(unsigned long)rip);
|
||||
deliver_signal(ALLOC_SIGINFO(SIGILL, ILL_ILLOPC,
|
||||
si_addr, (void *) arg), context);
|
||||
deliver_signal(ALLOC_SIGINFO(SIGILL, ILL_ILLOPC, si_addr, (void*)arg), context);
|
||||
}
|
||||
} else {
|
||||
internal_fault("Illegal instruction during Graphene internal execution", arg, context);
|
||||
@@ -636,8 +615,7 @@ static void illegal_upcall (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
|
||||
DkExceptionReturn(event);
|
||||
}
|
||||
|
||||
static void quit_upcall (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
|
||||
{
|
||||
static void quit_upcall(PAL_PTR event, PAL_NUM arg, PAL_CONTEXT* context) {
|
||||
__UNUSED(arg);
|
||||
__UNUSED(context);
|
||||
if (!is_internal_tid(get_cur_tid())) {
|
||||
@@ -646,8 +624,7 @@ static void quit_upcall (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
|
||||
DkExceptionReturn(event);
|
||||
}
|
||||
|
||||
static void suspend_upcall (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
|
||||
{
|
||||
static void suspend_upcall(PAL_PTR event, PAL_NUM arg, PAL_CONTEXT* context) {
|
||||
__UNUSED(arg);
|
||||
__UNUSED(context);
|
||||
if (!is_internal_tid(get_cur_tid())) {
|
||||
@@ -656,11 +633,10 @@ static void suspend_upcall (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
|
||||
DkExceptionReturn(event);
|
||||
}
|
||||
|
||||
static void resume_upcall (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
|
||||
{
|
||||
static void resume_upcall(PAL_PTR event, PAL_NUM arg, PAL_CONTEXT* context) {
|
||||
__UNUSED(arg);
|
||||
__UNUSED(context);
|
||||
shim_tcb_t * tcb = shim_get_tcb();
|
||||
shim_tcb_t* tcb = shim_get_tcb();
|
||||
if (!tcb || !tcb->tp)
|
||||
return;
|
||||
|
||||
@@ -673,19 +649,17 @@ static void resume_upcall (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
|
||||
DkExceptionReturn(event);
|
||||
}
|
||||
|
||||
int init_signal (void)
|
||||
{
|
||||
DkSetExceptionHandler(&arithmetic_error_upcall, PAL_EVENT_ARITHMETIC_ERROR);
|
||||
DkSetExceptionHandler(&memfault_upcall, PAL_EVENT_MEMFAULT);
|
||||
DkSetExceptionHandler(&illegal_upcall, PAL_EVENT_ILLEGAL);
|
||||
DkSetExceptionHandler(&quit_upcall, PAL_EVENT_QUIT);
|
||||
DkSetExceptionHandler(&suspend_upcall, PAL_EVENT_SUSPEND);
|
||||
DkSetExceptionHandler(&resume_upcall, PAL_EVENT_RESUME);
|
||||
int init_signal(void) {
|
||||
DkSetExceptionHandler(&arithmetic_error_upcall, PAL_EVENT_ARITHMETIC_ERROR);
|
||||
DkSetExceptionHandler(&memfault_upcall, PAL_EVENT_MEMFAULT);
|
||||
DkSetExceptionHandler(&illegal_upcall, PAL_EVENT_ILLEGAL);
|
||||
DkSetExceptionHandler(&quit_upcall, PAL_EVENT_QUIT);
|
||||
DkSetExceptionHandler(&suspend_upcall, PAL_EVENT_SUSPEND);
|
||||
DkSetExceptionHandler(&resume_upcall, PAL_EVENT_RESUME);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__sigset_t * get_sig_mask (struct shim_thread * thread)
|
||||
{
|
||||
__sigset_t* get_sig_mask(struct shim_thread* thread) {
|
||||
if (!thread)
|
||||
thread = get_cur_thread();
|
||||
|
||||
@@ -694,9 +668,7 @@ __sigset_t * get_sig_mask (struct shim_thread * thread)
|
||||
return &(thread->signal_mask);
|
||||
}
|
||||
|
||||
__sigset_t * set_sig_mask (struct shim_thread * thread,
|
||||
const __sigset_t * set)
|
||||
{
|
||||
__sigset_t* set_sig_mask(struct shim_thread* thread, const __sigset_t* set) {
|
||||
if (!thread)
|
||||
thread = get_cur_thread();
|
||||
|
||||
@@ -723,7 +695,7 @@ static __rt_sighandler_t get_sighandler(struct shim_thread* thread, int sig, boo
|
||||
* sa_handler simply ignores 2nd and 3rd argument.
|
||||
*/
|
||||
#ifndef __x86_64__
|
||||
# error "get_sighandler: see the comment above"
|
||||
#error "get_sighandler: see the comment above"
|
||||
#endif
|
||||
|
||||
__rt_sighandler_t handler = (void*)sig_action->k_sa_handler;
|
||||
@@ -741,8 +713,7 @@ static __rt_sighandler_t get_sighandler(struct shim_thread* thread, int sig, boo
|
||||
return handler;
|
||||
}
|
||||
|
||||
static void
|
||||
__handle_one_signal(shim_tcb_t* tcb, struct shim_signal* signal) {
|
||||
static void __handle_one_signal(shim_tcb_t* tcb, struct shim_signal* signal) {
|
||||
struct shim_thread* thread = (struct shim_thread*)tcb->tp;
|
||||
__rt_sighandler_t handler = NULL;
|
||||
|
||||
@@ -768,10 +739,9 @@ __handle_one_signal(shim_tcb_t* tcb, struct shim_signal* signal) {
|
||||
shim_context_set_syscallnr(&tcb->context, 0);
|
||||
}
|
||||
|
||||
debug("run signal handler %p (%d, %p, %p)\n", handler, sig, &signal->info,
|
||||
&signal->context);
|
||||
debug("run signal handler %p (%d, %p, %p)\n", handler, sig, &signal->info, &signal->context);
|
||||
|
||||
(*handler) (sig, &signal->info, &signal->context);
|
||||
(*handler)(sig, &signal->info, &signal->context);
|
||||
|
||||
__atomic_store_n(&thread->signal_handled, true, __ATOMIC_RELEASE);
|
||||
|
||||
@@ -823,7 +793,7 @@ void __handle_signals(shim_tcb_t* tcb) {
|
||||
}
|
||||
|
||||
void handle_signals(void) {
|
||||
shim_tcb_t * tcb = shim_get_tcb();
|
||||
shim_tcb_t* tcb = shim_get_tcb();
|
||||
assert(tcb);
|
||||
|
||||
int64_t preempt = __disable_preempt(tcb);
|
||||
@@ -849,7 +819,7 @@ int append_signal(struct shim_thread* thread, siginfo_t* info) {
|
||||
/* save in signal */
|
||||
__store_info(info, signal);
|
||||
signal->context_stored = false;
|
||||
signal->pal_context = NULL;
|
||||
signal->pal_context = NULL;
|
||||
|
||||
if (thread) {
|
||||
if (append_thread_signal(thread, signal)) {
|
||||
@@ -884,8 +854,7 @@ static void sighandler_kill(int sig, siginfo_t* info, void* ucontext) {
|
||||
process_exit(0, sig);
|
||||
}
|
||||
|
||||
static void sighandler_core (int sig, siginfo_t * info, void * ucontext)
|
||||
{
|
||||
static void sighandler_core(int sig, siginfo_t* info, void* ucontext) {
|
||||
/* NOTE: This implementation only indicates the core dump for wait4()
|
||||
* and friends. No actual core-dump file is created. */
|
||||
sig = __WCOREDUMP_BIT | sig;
|
||||
@@ -893,41 +862,40 @@ static void sighandler_core (int sig, siginfo_t * info, void * ucontext)
|
||||
}
|
||||
|
||||
static __rt_sighandler_t default_sighandler[NUM_SIGS] = {
|
||||
/* SIGHUP */ &sighandler_kill,
|
||||
/* SIGINT */ &sighandler_kill,
|
||||
/* SIGQUIT */ &sighandler_core,
|
||||
/* SIGILL */ &sighandler_core,
|
||||
/* SIGTRAP */ &sighandler_core,
|
||||
/* SIGABRT */ &sighandler_core,
|
||||
/* SIGBUS */ &sighandler_core,
|
||||
/* SIGFPE */ &sighandler_core,
|
||||
/* SIGKILL */ &sighandler_kill,
|
||||
/* SIGUSR1 */ &sighandler_kill,
|
||||
/* SIGSEGV */ &sighandler_core,
|
||||
/* SIGUSR2 */ &sighandler_kill,
|
||||
/* SIGPIPE */ &sighandler_kill,
|
||||
/* SIGALRM */ &sighandler_kill,
|
||||
/* SIGTERM */ &sighandler_kill,
|
||||
/* SIGSTKFLT */ &sighandler_kill,
|
||||
/* SIGCHLD */ NULL,
|
||||
/* SIGCONT */ NULL,
|
||||
/* SIGSTOP */ NULL,
|
||||
/* SIGTSTP */ NULL,
|
||||
/* SIGTTIN */ NULL,
|
||||
/* SIGTTOU */ NULL,
|
||||
/* SIGURG */ NULL,
|
||||
/* SIGXCPU */ &sighandler_core,
|
||||
/* SIGXFSZ */ &sighandler_core,
|
||||
/* SIGVTALRM */ &sighandler_kill,
|
||||
/* SIGPROF */ &sighandler_kill,
|
||||
/* SIGWINCH */ NULL,
|
||||
/* SIGIO */ &sighandler_kill,
|
||||
/* SIGPWR */ &sighandler_kill,
|
||||
/* SIGSYS */ &sighandler_core
|
||||
[SIGHUP - 1] = &sighandler_kill,
|
||||
[SIGINT - 1] = &sighandler_kill,
|
||||
[SIGQUIT - 1] = &sighandler_core,
|
||||
[SIGILL - 1] = &sighandler_core,
|
||||
[SIGTRAP - 1] = &sighandler_core,
|
||||
[SIGABRT - 1] = &sighandler_core,
|
||||
[SIGBUS - 1] = &sighandler_core,
|
||||
[SIGFPE - 1] = &sighandler_core,
|
||||
[SIGKILL - 1] = &sighandler_kill,
|
||||
[SIGUSR1 - 1] = &sighandler_kill,
|
||||
[SIGSEGV - 1] = &sighandler_core,
|
||||
[SIGUSR2 - 1] = &sighandler_kill,
|
||||
[SIGPIPE - 1] = &sighandler_kill,
|
||||
[SIGALRM - 1] = &sighandler_kill,
|
||||
[SIGTERM - 1] = &sighandler_kill,
|
||||
[SIGSTKFLT - 1] = &sighandler_kill,
|
||||
[SIGCHLD - 1] = NULL,
|
||||
[SIGCONT - 1] = NULL,
|
||||
[SIGSTOP - 1] = NULL,
|
||||
[SIGTSTP - 1] = NULL,
|
||||
[SIGTTIN - 1] = NULL,
|
||||
[SIGTTOU - 1] = NULL,
|
||||
[SIGURG - 1] = NULL,
|
||||
[SIGXCPU - 1] = &sighandler_core,
|
||||
[SIGXFSZ - 1] = &sighandler_core,
|
||||
[SIGVTALRM - 1] = &sighandler_kill,
|
||||
[SIGPROF - 1] = &sighandler_kill,
|
||||
[SIGWINCH - 1] = NULL,
|
||||
[SIGIO - 1] = &sighandler_kill,
|
||||
[SIGPWR - 1] = &sighandler_kill,
|
||||
[SIGSYS - 1] = &sighandler_core,
|
||||
};
|
||||
|
||||
BEGIN_CP_FUNC(pending_signals)
|
||||
{
|
||||
BEGIN_CP_FUNC(pending_signals) {
|
||||
__UNUSED(obj);
|
||||
__UNUSED(size);
|
||||
__UNUSED(objp);
|
||||
@@ -937,7 +905,7 @@ BEGIN_CP_FUNC(pending_signals)
|
||||
* safe margin slots. */
|
||||
const size_t SAFE_MARGIN_SLOTS = 10;
|
||||
uint64_t n = __atomic_load_n(&process_pending_signals_cnt, __ATOMIC_ACQUIRE)
|
||||
+ SAFE_MARGIN_SLOTS;
|
||||
+ SAFE_MARGIN_SLOTS;
|
||||
uint64_t i = 0;
|
||||
assert(n <= SIGRTMIN - 1 + (NUM_SIGS - SIGRTMIN + 1) * MAX_SIGNAL_LOG + SAFE_MARGIN_SLOTS);
|
||||
siginfo_t infos[n];
|
||||
@@ -972,8 +940,7 @@ BEGIN_CP_FUNC(pending_signals)
|
||||
}
|
||||
END_CP_FUNC(pending_signals)
|
||||
|
||||
BEGIN_RS_FUNC(pending_signals)
|
||||
{
|
||||
BEGIN_RS_FUNC(pending_signals) {
|
||||
__UNUSED(offset);
|
||||
__UNUSED(rebase);
|
||||
|
||||
@@ -990,7 +957,7 @@ BEGIN_RS_FUNC(pending_signals)
|
||||
|
||||
memcpy(&signal->info, &infos[i], sizeof(signal->info));
|
||||
signal->context_stored = false;
|
||||
signal->pal_context = NULL;
|
||||
signal->pal_context = NULL;
|
||||
if (!append_process_signal(signal)) {
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
@@ -2,27 +2,28 @@
|
||||
/* Copyright (C) 2014 Stony Brook University */
|
||||
|
||||
/*
|
||||
* shim_thread.c
|
||||
*
|
||||
* This file contains codes to maintain bookkeeping of threads in library OS.
|
||||
* This file contains code for maintaining bookkeeping of threads in library OS.
|
||||
*/
|
||||
|
||||
#include <shim_defs.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_vma.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_context.h>
|
||||
#include <shim_checkpoint.h>
|
||||
#include <shim_utils.h>
|
||||
|
||||
#include <cpu.h>
|
||||
#include <list.h>
|
||||
#include <pal.h>
|
||||
#include <stddef.h> /* linux/signal.h misses this dependency (for size_t), at least on Ubuntu 16.04.
|
||||
* We must include it ourselves before including linux/signal.h.
|
||||
*/
|
||||
|
||||
#include <linux/signal.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "list.h"
|
||||
#include "pal.h"
|
||||
#include "shim_checkpoint.h"
|
||||
#include "shim_context.h"
|
||||
#include "shim_defs.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_utils.h"
|
||||
#include "shim_vma.h"
|
||||
|
||||
static IDTYPE tid_alloc_idx __attribute_migratable = 0;
|
||||
|
||||
static LISTP_TYPE(shim_thread) thread_list = LISTP_INIT;
|
||||
@@ -40,13 +41,12 @@ PAL_HANDLE thread_start_event = NULL;
|
||||
#define DEBUG_PRINT_REF_COUNT(rc) __UNUSED(rc)
|
||||
#endif
|
||||
|
||||
int init_thread (void)
|
||||
{
|
||||
int init_thread(void) {
|
||||
if (!create_lock(&thread_list_lock)) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
struct shim_thread * cur_thread = get_cur_thread();
|
||||
struct shim_thread* cur_thread = get_cur_thread();
|
||||
if (cur_thread)
|
||||
return 0;
|
||||
|
||||
@@ -60,14 +60,13 @@ int init_thread (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dump_threads (void)
|
||||
{
|
||||
struct shim_thread * tmp;
|
||||
void dump_threads(void) {
|
||||
struct shim_thread* tmp;
|
||||
|
||||
lock(&thread_list_lock);
|
||||
LISTP_FOR_EACH_ENTRY(tmp, &thread_list, list) {
|
||||
debug("thread %d, vmid = %d, pgid = %d, ppid = %d, tgid = %d, in_vm = %d\n",
|
||||
tmp->tid, tmp->vmid, tmp->pgid, tmp->ppid, tmp->tgid, tmp->in_vm);
|
||||
debug("thread %d, vmid = %d, pgid = %d, ppid = %d, tgid = %d, in_vm = %d\n", tmp->tid,
|
||||
tmp->vmid, tmp->pgid, tmp->ppid, tmp->tgid, tmp->in_vm);
|
||||
}
|
||||
unlock(&thread_list_lock);
|
||||
}
|
||||
@@ -123,8 +122,7 @@ static IDTYPE get_pid(void) {
|
||||
return idx;
|
||||
}
|
||||
|
||||
static IDTYPE get_internal_pid (void)
|
||||
{
|
||||
static IDTYPE get_internal_pid(void) {
|
||||
lock(&thread_list_lock);
|
||||
internal_tid_alloc_idx++;
|
||||
IDTYPE idx = internal_tid_alloc_idx;
|
||||
@@ -133,9 +131,8 @@ static IDTYPE get_internal_pid (void)
|
||||
return idx;
|
||||
}
|
||||
|
||||
static struct shim_thread * alloc_new_thread (void)
|
||||
{
|
||||
struct shim_thread * thread = calloc(1, sizeof(struct shim_thread));
|
||||
static struct shim_thread* alloc_new_thread(void) {
|
||||
struct shim_thread* thread = calloc(1, sizeof(struct shim_thread));
|
||||
if (!thread)
|
||||
return NULL;
|
||||
|
||||
@@ -150,25 +147,24 @@ static struct shim_thread * alloc_new_thread (void)
|
||||
}
|
||||
|
||||
static struct shim_signal_handles* alloc_default_signal_handles(void) {
|
||||
struct shim_signal_handles* handles = malloc(sizeof(*handles));
|
||||
if (!handles) {
|
||||
return NULL;
|
||||
}
|
||||
struct shim_signal_handles* handles = malloc(sizeof(*handles));
|
||||
if (!handles) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!create_lock(&handles->lock)) {
|
||||
free(handles);
|
||||
return NULL;
|
||||
}
|
||||
REF_SET(handles->ref_count, 1);
|
||||
for (size_t i = 0; i < ARRAY_SIZE(handles->actions); i++) {
|
||||
sigaction_make_defaults(&handles->actions[i]);
|
||||
}
|
||||
if (!create_lock(&handles->lock)) {
|
||||
free(handles);
|
||||
return NULL;
|
||||
}
|
||||
REF_SET(handles->ref_count, 1);
|
||||
for (size_t i = 0; i < ARRAY_SIZE(handles->actions); i++) {
|
||||
sigaction_make_defaults(&handles->actions[i]);
|
||||
}
|
||||
|
||||
return handles;
|
||||
return handles;
|
||||
}
|
||||
|
||||
struct shim_thread * get_new_thread (IDTYPE new_tid)
|
||||
{
|
||||
struct shim_thread* get_new_thread(IDTYPE new_tid) {
|
||||
if (!new_tid) {
|
||||
new_tid = get_pid();
|
||||
if (!new_tid) {
|
||||
@@ -177,45 +173,44 @@ struct shim_thread * get_new_thread (IDTYPE new_tid)
|
||||
}
|
||||
}
|
||||
|
||||
struct shim_thread * thread = alloc_new_thread();
|
||||
struct shim_thread* thread = alloc_new_thread();
|
||||
if (!thread) {
|
||||
release_ipc_id(new_tid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct shim_thread * cur_thread = get_cur_thread();
|
||||
struct shim_thread* cur_thread = get_cur_thread();
|
||||
thread->tid = new_tid;
|
||||
|
||||
if (cur_thread) {
|
||||
/* The newly created thread will be in the same thread group
|
||||
(process group as well) with its parent */
|
||||
thread->pgid = cur_thread->pgid;
|
||||
thread->ppid = cur_thread->tgid;
|
||||
thread->tgid = cur_thread->tgid;
|
||||
thread->uid = cur_thread->uid;
|
||||
thread->gid = cur_thread->gid;
|
||||
thread->euid = cur_thread->euid;
|
||||
thread->egid = cur_thread->egid;
|
||||
thread->parent = cur_thread;
|
||||
thread->stack = cur_thread->stack;
|
||||
thread->stack_top = cur_thread->stack_top;
|
||||
thread->stack_red = cur_thread->stack_red;
|
||||
thread->cwd = cur_thread->cwd;
|
||||
thread->root = cur_thread->root;
|
||||
thread->umask = cur_thread->umask;
|
||||
thread->exec = cur_thread->exec;
|
||||
thread->pgid = cur_thread->pgid;
|
||||
thread->ppid = cur_thread->tgid;
|
||||
thread->tgid = cur_thread->tgid;
|
||||
thread->uid = cur_thread->uid;
|
||||
thread->gid = cur_thread->gid;
|
||||
thread->euid = cur_thread->euid;
|
||||
thread->egid = cur_thread->egid;
|
||||
thread->parent = cur_thread;
|
||||
thread->stack = cur_thread->stack;
|
||||
thread->stack_top = cur_thread->stack_top;
|
||||
thread->stack_red = cur_thread->stack_red;
|
||||
thread->cwd = cur_thread->cwd;
|
||||
thread->root = cur_thread->root;
|
||||
thread->umask = cur_thread->umask;
|
||||
thread->exec = cur_thread->exec;
|
||||
get_handle(cur_thread->exec);
|
||||
|
||||
thread->signal_handles = cur_thread->signal_handles;
|
||||
get_signal_handles(thread->signal_handles);
|
||||
|
||||
memcpy(&thread->signal_mask, &cur_thread->signal_mask,
|
||||
sizeof(sigset_t));
|
||||
memcpy(&thread->signal_mask, &cur_thread->signal_mask, sizeof(sigset_t));
|
||||
|
||||
get_dentry(cur_thread->cwd);
|
||||
get_dentry(cur_thread->root);
|
||||
|
||||
struct shim_handle_map * map = get_cur_handle_map(cur_thread);
|
||||
struct shim_handle_map* map = get_cur_handle_map(cur_thread);
|
||||
assert(map);
|
||||
set_handle_map(thread, map);
|
||||
} else {
|
||||
@@ -226,8 +221,7 @@ struct shim_thread * get_new_thread (IDTYPE new_tid)
|
||||
*/
|
||||
path_lookupat(NULL, "/", 0, &thread->root, NULL);
|
||||
char dir_cfg[CONFIG_MAX];
|
||||
if (root_config &&
|
||||
get_config(root_config, "fs.start_dir", dir_cfg, sizeof(dir_cfg)) > 0) {
|
||||
if (root_config && get_config(root_config, "fs.start_dir", dir_cfg, sizeof(dir_cfg)) > 0) {
|
||||
path_lookupat(NULL, dir_cfg, 0, &thread->cwd, NULL);
|
||||
} else if (thread->root) {
|
||||
get_dentry(thread->root);
|
||||
@@ -244,9 +238,9 @@ struct shim_thread * get_new_thread (IDTYPE new_tid)
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
thread->vmid = cur_process.vmid;
|
||||
thread->scheduler_event = DkNotificationEventCreate(PAL_TRUE);
|
||||
thread->exit_event = DkNotificationEventCreate(PAL_FALSE);
|
||||
thread->vmid = cur_process.vmid;
|
||||
thread->scheduler_event = DkNotificationEventCreate(PAL_TRUE);
|
||||
thread->exit_event = DkNotificationEventCreate(PAL_FALSE);
|
||||
thread->child_exit_event = DkNotificationEventCreate(PAL_FALSE);
|
||||
return thread;
|
||||
|
||||
@@ -271,14 +265,13 @@ out_error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct shim_thread * get_new_internal_thread (void)
|
||||
{
|
||||
struct shim_thread* get_new_internal_thread(void) {
|
||||
IDTYPE new_tid = get_internal_pid();
|
||||
if (!new_tid) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct shim_thread * thread = alloc_new_thread();
|
||||
struct shim_thread* thread = alloc_new_thread();
|
||||
if (!thread)
|
||||
return NULL;
|
||||
|
||||
@@ -320,8 +313,7 @@ void put_thread(struct shim_thread* thread) {
|
||||
DEBUG_PRINT_REF_COUNT(ref_count);
|
||||
|
||||
if (!ref_count) {
|
||||
if (thread->pal_handle &&
|
||||
thread->pal_handle != PAL_CB(first_thread))
|
||||
if (thread->pal_handle && thread->pal_handle != PAL_CB(first_thread))
|
||||
DkObjectClose(thread->pal_handle);
|
||||
|
||||
if (thread->scheduler_event)
|
||||
@@ -359,9 +351,7 @@ void put_thread(struct shim_thread* thread) {
|
||||
}
|
||||
}
|
||||
|
||||
void set_as_child (struct shim_thread * parent,
|
||||
struct shim_thread * child)
|
||||
{
|
||||
void set_as_child(struct shim_thread* parent, struct shim_thread* child) {
|
||||
if (!parent)
|
||||
parent = get_cur_thread();
|
||||
|
||||
@@ -369,7 +359,7 @@ void set_as_child (struct shim_thread * parent,
|
||||
get_thread(child);
|
||||
|
||||
lock(&child->lock);
|
||||
child->ppid = parent->tid;
|
||||
child->ppid = parent->tid;
|
||||
child->parent = parent;
|
||||
|
||||
lock(&parent->lock);
|
||||
@@ -379,12 +369,12 @@ void set_as_child (struct shim_thread * parent,
|
||||
unlock(&child->lock);
|
||||
}
|
||||
|
||||
void add_thread (struct shim_thread * thread)
|
||||
{
|
||||
void add_thread(struct shim_thread* thread) {
|
||||
if (is_internal(thread) || !LIST_EMPTY(thread, list))
|
||||
return;
|
||||
|
||||
struct shim_thread * tmp, * prev = NULL;
|
||||
struct shim_thread* tmp;
|
||||
struct shim_thread* prev = NULL;
|
||||
lock(&thread_list_lock);
|
||||
|
||||
/* keep it sorted */
|
||||
@@ -404,9 +394,8 @@ void add_thread (struct shim_thread * thread)
|
||||
unlock(&thread_list_lock);
|
||||
}
|
||||
|
||||
void del_thread (struct shim_thread * thread)
|
||||
{
|
||||
debug("del_thread(%p, %d, %ld)\n", thread, thread ? (int) thread->tid : -1,
|
||||
void del_thread(struct shim_thread* thread) {
|
||||
debug("del_thread(%p, %d, %ld)\n", thread, thread ? (int)thread->tid : -1,
|
||||
__atomic_load_n(&thread->ref_count.counter, __ATOMIC_SEQ_CST));
|
||||
|
||||
if (is_internal(thread)) {
|
||||
@@ -521,8 +510,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
BEGIN_CP_FUNC(signal_handles)
|
||||
{
|
||||
BEGIN_CP_FUNC(signal_handles) {
|
||||
__UNUSED(size);
|
||||
assert(size == sizeof(struct shim_signal_handles));
|
||||
|
||||
@@ -552,12 +540,10 @@ BEGIN_CP_FUNC(signal_handles)
|
||||
if (objp) {
|
||||
*objp = (void*)new_handles;
|
||||
}
|
||||
|
||||
}
|
||||
END_CP_FUNC(signal_handles)
|
||||
|
||||
BEGIN_RS_FUNC(signal_handles)
|
||||
{
|
||||
BEGIN_RS_FUNC(signal_handles) {
|
||||
__UNUSED(offset);
|
||||
__UNUSED(rebase);
|
||||
struct shim_signal_handles* handles = (void*)(base + GET_CP_FUNC_ENTRY());
|
||||
@@ -568,20 +554,19 @@ BEGIN_RS_FUNC(signal_handles)
|
||||
}
|
||||
END_RS_FUNC(signal_handles)
|
||||
|
||||
BEGIN_CP_FUNC(thread)
|
||||
{
|
||||
BEGIN_CP_FUNC(thread) {
|
||||
__UNUSED(size);
|
||||
assert(size == sizeof(struct shim_thread));
|
||||
|
||||
struct shim_thread * thread = (struct shim_thread *) obj;
|
||||
struct shim_thread * new_thread = NULL;
|
||||
struct shim_thread* thread = (struct shim_thread*)obj;
|
||||
struct shim_thread* new_thread = NULL;
|
||||
|
||||
size_t off = GET_FROM_CP_MAP(obj);
|
||||
|
||||
if (!off) {
|
||||
off = ADD_CP_OFFSET(sizeof(struct shim_thread));
|
||||
ADD_TO_CP_MAP(obj, off);
|
||||
new_thread = (struct shim_thread *) (base + off);
|
||||
new_thread = (struct shim_thread*)(base + off);
|
||||
memcpy(new_thread, thread, sizeof(struct shim_thread));
|
||||
|
||||
INIT_LISTP(&new_thread->children);
|
||||
@@ -589,11 +574,11 @@ BEGIN_CP_FUNC(thread)
|
||||
INIT_LISTP(&new_thread->exited_children);
|
||||
INIT_LIST_HEAD(new_thread, list);
|
||||
|
||||
new_thread->in_vm = false;
|
||||
new_thread->parent = NULL;
|
||||
new_thread->in_vm = false;
|
||||
new_thread->parent = NULL;
|
||||
new_thread->handle_map = NULL;
|
||||
new_thread->root = NULL;
|
||||
new_thread->cwd = NULL;
|
||||
new_thread->root = NULL;
|
||||
new_thread->cwd = NULL;
|
||||
memset(&new_thread->signal_queue, 0, sizeof(new_thread->signal_queue));
|
||||
new_thread->robust_list = NULL;
|
||||
REF_SET(new_thread->ref_count, 0);
|
||||
@@ -606,17 +591,16 @@ BEGIN_CP_FUNC(thread)
|
||||
DO_CP_MEMBER(dentry, thread, new_thread, cwd);
|
||||
ADD_CP_FUNC_ENTRY(off);
|
||||
} else {
|
||||
new_thread = (struct shim_thread *) (base + off);
|
||||
new_thread = (struct shim_thread*)(base + off);
|
||||
}
|
||||
|
||||
if (objp)
|
||||
*objp = (void *) new_thread;
|
||||
*objp = (void*)new_thread;
|
||||
}
|
||||
END_CP_FUNC(thread)
|
||||
|
||||
BEGIN_RS_FUNC(thread)
|
||||
{
|
||||
struct shim_thread * thread = (void *) (base + GET_CP_FUNC_ENTRY());
|
||||
BEGIN_RS_FUNC(thread) {
|
||||
struct shim_thread* thread = (void*)(base + GET_CP_FUNC_ENTRY());
|
||||
__UNUSED(offset);
|
||||
|
||||
CP_REBASE(thread->children);
|
||||
@@ -632,8 +616,8 @@ BEGIN_RS_FUNC(thread)
|
||||
if (!create_lock(&thread->lock)) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
thread->scheduler_event = DkNotificationEventCreate(PAL_TRUE);
|
||||
thread->exit_event = DkNotificationEventCreate(PAL_FALSE);
|
||||
thread->scheduler_event = DkNotificationEventCreate(PAL_TRUE);
|
||||
thread->exit_event = DkNotificationEventCreate(PAL_FALSE);
|
||||
thread->child_exit_event = DkNotificationEventCreate(PAL_FALSE);
|
||||
|
||||
add_thread(thread);
|
||||
@@ -654,41 +638,38 @@ BEGIN_RS_FUNC(thread)
|
||||
get_signal_handles(thread->signal_handles);
|
||||
}
|
||||
|
||||
DEBUG_RS("tid=%d,tgid=%d,parent=%d,stack=%p,frameptr=%p,tcb=%p,shim_tcb=%p",
|
||||
thread->tid, thread->tgid,
|
||||
thread->parent ? thread->parent->tid : thread->tid,
|
||||
thread->stack, thread->frameptr, thread->tcb, thread->shim_tcb);
|
||||
DEBUG_RS("tid=%d,tgid=%d,parent=%d,stack=%p,frameptr=%p,tcb=%p,shim_tcb=%p", thread->tid,
|
||||
thread->tgid, thread->parent ? thread->parent->tid : thread->tid, thread->stack,
|
||||
thread->frameptr, thread->tcb, thread->shim_tcb);
|
||||
}
|
||||
END_RS_FUNC(thread)
|
||||
|
||||
BEGIN_CP_FUNC(running_thread)
|
||||
{
|
||||
BEGIN_CP_FUNC(running_thread) {
|
||||
__UNUSED(size);
|
||||
__UNUSED(objp);
|
||||
assert(size == sizeof(struct shim_thread));
|
||||
|
||||
struct shim_thread * thread = (struct shim_thread *) obj;
|
||||
struct shim_thread * new_thread = NULL;
|
||||
struct shim_thread* thread = (struct shim_thread*)obj;
|
||||
struct shim_thread* new_thread = NULL;
|
||||
|
||||
DO_CP(thread, thread, &new_thread);
|
||||
ADD_CP_FUNC_ENTRY((uintptr_t)new_thread - base);
|
||||
|
||||
if (thread->shim_tcb) {
|
||||
size_t toff = ADD_CP_OFFSET(sizeof(shim_tcb_t));
|
||||
new_thread->shim_tcb = (void *)(base + toff);
|
||||
new_thread->shim_tcb = (void*)(base + toff);
|
||||
struct shim_tcb* new_tcb = new_thread->shim_tcb;
|
||||
memcpy(new_tcb, thread->shim_tcb, sizeof(*new_tcb));
|
||||
/* don't export stale pointers */
|
||||
new_tcb->self = NULL;
|
||||
new_tcb->tp = NULL;
|
||||
new_tcb->self = NULL;
|
||||
new_tcb->tp = NULL;
|
||||
new_tcb->debug_buf = NULL;
|
||||
}
|
||||
}
|
||||
END_CP_FUNC(running_thread)
|
||||
|
||||
static int resume_wrapper (void * param)
|
||||
{
|
||||
struct shim_thread * thread = (struct shim_thread *) param;
|
||||
static int resume_wrapper(void* param) {
|
||||
struct shim_thread* thread = (struct shim_thread*)param;
|
||||
assert(thread);
|
||||
|
||||
/* initialize the current shim_tcb_t (= shim_get_tcb())
|
||||
@@ -704,7 +685,7 @@ static int resume_wrapper (void * param)
|
||||
thread->in_vm = thread->is_alive = true;
|
||||
|
||||
shim_tcb_t* tcb = shim_get_tcb();
|
||||
tcb->context.regs = saved_tcb->context.regs;
|
||||
tcb->context.regs = saved_tcb->context.regs;
|
||||
tcb->context.preempt = saved_tcb->context.preempt;
|
||||
debug_setbuf(tcb, NULL);
|
||||
debug("set fs_base to 0x%lx\n", fs_base);
|
||||
@@ -715,11 +696,10 @@ static int resume_wrapper (void * param)
|
||||
return 0;
|
||||
}
|
||||
|
||||
BEGIN_RS_FUNC(running_thread)
|
||||
{
|
||||
BEGIN_RS_FUNC(running_thread) {
|
||||
__UNUSED(offset);
|
||||
struct shim_thread * thread = (void *) (base + GET_CP_FUNC_ENTRY());
|
||||
struct shim_thread * cur_thread = get_cur_thread();
|
||||
struct shim_thread* thread = (void*)(base + GET_CP_FUNC_ENTRY());
|
||||
struct shim_thread* cur_thread = get_cur_thread();
|
||||
thread->in_vm = true;
|
||||
|
||||
thread->vmid = cur_process.vmid;
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
* Copyright (C) 2020 Invisible Things Lab
|
||||
*/
|
||||
|
||||
#include <stddef.h> /* linux/signal.h misses this dependency (for size_t), at least on Ubuntu 16.04.
|
||||
* We must include it ourselves before including linux/signal.h.
|
||||
*/
|
||||
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/mman.h>
|
||||
#include <stdalign.h>
|
||||
@@ -60,10 +64,10 @@ static void copy_comment(struct shim_vma* vma, const char* comment) {
|
||||
|
||||
static void copy_vma(struct shim_vma* old_vma, struct shim_vma* new_vma) {
|
||||
new_vma->begin = old_vma->begin;
|
||||
new_vma->end = old_vma->end;
|
||||
new_vma->prot = old_vma->prot;
|
||||
new_vma->end = old_vma->end;
|
||||
new_vma->prot = old_vma->prot;
|
||||
new_vma->flags = old_vma->flags;
|
||||
new_vma->file = old_vma->file;
|
||||
new_vma->file = old_vma->file;
|
||||
if (new_vma->file) {
|
||||
get_handle(new_vma->file);
|
||||
}
|
||||
@@ -94,7 +98,7 @@ static bool cmp_addr_to_vma(void* addr, struct avl_tree_node* node) {
|
||||
* Currently we do not merge similar adjacent vmas - if we ever start doing it, this code needs
|
||||
* to be revisited as there might be some optimizations that would break due to it.
|
||||
*/
|
||||
static struct avl_tree vma_tree = { .cmp = vma_tree_cmp };
|
||||
static struct avl_tree vma_tree = {.cmp = vma_tree_cmp};
|
||||
static spinlock_t vma_tree_lock = INIT_SPINLOCK_UNLOCKED;
|
||||
|
||||
static struct shim_vma* node2vma(struct avl_tree_node* node) {
|
||||
@@ -157,8 +161,7 @@ static void split_vma(struct shim_vma* old_vma, struct shim_vma* new_vma, uintpt
|
||||
* either internal or non-internal.
|
||||
*/
|
||||
static int _vma_bkeep_remove(uintptr_t begin, uintptr_t end, bool is_internal,
|
||||
struct shim_vma** new_vma_ptr,
|
||||
struct shim_vma** vmas_to_free) {
|
||||
struct shim_vma** new_vma_ptr, struct shim_vma** vmas_to_free) {
|
||||
assert(spinlock_is_locked(&vma_tree_lock));
|
||||
assert(!new_vma_ptr || *new_vma_ptr);
|
||||
assert(IS_ALLOC_ALIGNED_PTR(begin) && IS_ALLOC_ALIGNED_PTR(end));
|
||||
@@ -183,7 +186,6 @@ static int _vma_bkeep_remove(uintptr_t begin, uintptr_t end, bool is_internal,
|
||||
vma = _get_next_vma(vma);
|
||||
}
|
||||
|
||||
|
||||
vma = first_vma;
|
||||
|
||||
if (vma->begin < begin) {
|
||||
@@ -278,9 +280,9 @@ static void _vma_free(void* ptr, size_t size) {
|
||||
#undef system_malloc
|
||||
#undef system_free
|
||||
#define system_malloc _vma_malloc
|
||||
#define system_free _vma_free
|
||||
#define OBJ_TYPE struct shim_vma
|
||||
#include <memmgr.h>
|
||||
#define system_free _vma_free
|
||||
#define OBJ_TYPE struct shim_vma
|
||||
#include "memmgr.h"
|
||||
|
||||
static struct shim_lock vma_mgr_lock;
|
||||
static MEM_MGR vma_mgr = NULL;
|
||||
@@ -306,9 +308,9 @@ static_assert((VMA_CACHE_SIZE & (VMA_CACHE_SIZE + 1)) == 0,
|
||||
"VMA_CACHE_SIZE must be a power of 2 minus 1!");
|
||||
|
||||
static struct shim_vma* cache2ptr(void* vma) {
|
||||
static_assert(alignof(struct shim_vma) >= VMA_CACHE_SIZE + 1,
|
||||
"We need some lower bits of pointers to `struct shim_vma` for this optimization!"
|
||||
);
|
||||
static_assert(
|
||||
alignof(struct shim_vma) >= VMA_CACHE_SIZE + 1,
|
||||
"We need some lower bits of pointers to `struct shim_vma` for this optimization!");
|
||||
return (struct shim_vma*)((uintptr_t)vma & ~VMA_CACHE_SIZE);
|
||||
}
|
||||
|
||||
@@ -392,7 +394,7 @@ static struct shim_vma* alloc_vma(void) {
|
||||
if (!vma) {
|
||||
/* `enlarge_mem_mgr` below will call _vma_malloc, which uses at most 1 vma - so we
|
||||
* temporarily provide it. */
|
||||
struct shim_vma tmp_vma = { 0 };
|
||||
struct shim_vma tmp_vma = {0};
|
||||
/* vma cache is empty, as we checked it before. */
|
||||
if (!add_to_thread_vma_cache(&tmp_vma)) {
|
||||
debug("Failed to add tmp vma to cache!\n");
|
||||
@@ -479,32 +481,32 @@ static void* g_aslr_addr_top = NULL;
|
||||
|
||||
int init_vma(void) {
|
||||
struct shim_vma init_vmas[] = {
|
||||
{ .begin = 0 }, // vma for creation of memory manager
|
||||
{.begin = 0}, // vma for creation of memory manager
|
||||
{
|
||||
.begin = (uintptr_t)&__load_address,
|
||||
.end = (uintptr_t)ALLOC_ALIGN_UP_PTR(&__load_address_end),
|
||||
.prot = PROT_NONE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS | VMA_INTERNAL,
|
||||
.file = NULL,
|
||||
.offset = 0,
|
||||
.begin = (uintptr_t)&__load_address,
|
||||
.end = (uintptr_t)ALLOC_ALIGN_UP_PTR(&__load_address_end),
|
||||
.prot = PROT_NONE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS | VMA_INTERNAL,
|
||||
.file = NULL,
|
||||
.offset = 0,
|
||||
.comment = "LibOS",
|
||||
},
|
||||
{
|
||||
.begin = (uintptr_t)ALLOC_ALIGN_DOWN_PTR(PAL_CB(manifest_preload.start)),
|
||||
.end = (uintptr_t)ALLOC_ALIGN_UP_PTR(PAL_CB(manifest_preload.end)),
|
||||
.prot = PROT_NONE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS | VMA_INTERNAL,
|
||||
.file = NULL,
|
||||
.offset = 0,
|
||||
.begin = (uintptr_t)ALLOC_ALIGN_DOWN_PTR(PAL_CB(manifest_preload.start)),
|
||||
.end = (uintptr_t)ALLOC_ALIGN_UP_PTR(PAL_CB(manifest_preload.end)),
|
||||
.prot = PROT_NONE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS | VMA_INTERNAL,
|
||||
.file = NULL,
|
||||
.offset = 0,
|
||||
.comment = "manifest",
|
||||
},
|
||||
{
|
||||
.begin = (uintptr_t)PAL_CB(executable_range.start),
|
||||
.end = (uintptr_t)PAL_CB(executable_range.end),
|
||||
.prot = PROT_NONE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS | VMA_UNMAPPED,
|
||||
.file = NULL,
|
||||
.offset = 0,
|
||||
.begin = (uintptr_t)PAL_CB(executable_range.start),
|
||||
.end = (uintptr_t)PAL_CB(executable_range.end),
|
||||
.prot = PROT_NONE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS | VMA_UNMAPPED,
|
||||
.file = NULL,
|
||||
.offset = 0,
|
||||
.comment = "exec",
|
||||
},
|
||||
};
|
||||
@@ -522,20 +524,18 @@ int init_vma(void) {
|
||||
}
|
||||
if (!IS_ALLOC_ALIGNED(init_vmas[i].begin) || !IS_ALLOC_ALIGNED(init_vmas[i].end)) {
|
||||
debug("Unaligned VMA region: 0x%lx-0x%lx (%s)\n", init_vmas[i].begin, init_vmas[i].end,
|
||||
init_vmas[i].comment);
|
||||
init_vmas[i].comment);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
ret = _bkeep_initial_vma(&init_vmas[i]);
|
||||
if (ret < 0) {
|
||||
debug("Failed to bookkeep initial VMA region 0x%lx-0x%lx (%s)\n", init_vmas[i].begin,
|
||||
init_vmas[i].end,
|
||||
init_vmas[i].comment);
|
||||
init_vmas[i].end, init_vmas[i].comment);
|
||||
break;
|
||||
}
|
||||
debug("Initial VMA region 0x%lx-0x%lx (%s) bookkeeped\n", init_vmas[i].begin,
|
||||
init_vmas[i].end,
|
||||
init_vmas[i].comment);
|
||||
init_vmas[i].end, init_vmas[i].comment);
|
||||
}
|
||||
spinlock_unlock_signal_on(&vma_tree_lock);
|
||||
/* From now on if we return with an error we might leave a structure local to this function in
|
||||
@@ -618,11 +618,11 @@ int init_vma(void) {
|
||||
static void _add_unmapped_vma(uintptr_t begin, uintptr_t end, struct shim_vma* vma) {
|
||||
assert(spinlock_is_locked(&vma_tree_lock));
|
||||
|
||||
vma->begin = begin;
|
||||
vma->end = end;
|
||||
vma->prot = PROT_NONE;
|
||||
vma->flags = VMA_INTERNAL | VMA_UNMAPPED;
|
||||
vma->file = NULL;
|
||||
vma->begin = begin;
|
||||
vma->end = end;
|
||||
vma->prot = PROT_NONE;
|
||||
vma->flags = VMA_INTERNAL | VMA_UNMAPPED;
|
||||
vma->file = NULL;
|
||||
vma->offset = 0;
|
||||
copy_comment(vma, "");
|
||||
|
||||
@@ -684,8 +684,8 @@ static bool is_file_prot_matching(struct shim_handle* file_hdl, int prot) {
|
||||
return !(prot & PROT_WRITE) || (file_hdl->flags & O_RDWR);
|
||||
}
|
||||
|
||||
int bkeep_mmap_fixed(void* addr, size_t length, int prot, int flags,
|
||||
struct shim_handle* file, off_t offset, const char* comment) {
|
||||
int bkeep_mmap_fixed(void* addr, size_t length, int prot, int flags, struct shim_handle* file,
|
||||
off_t offset, const char* comment) {
|
||||
assert(flags & (MAP_FIXED | MAP_FIXED_NOREPLACE));
|
||||
|
||||
if (!length || !IS_ALLOC_ALIGNED(length) || !IS_ALLOC_ALIGNED_PTR(addr)) {
|
||||
@@ -700,10 +700,10 @@ int bkeep_mmap_fixed(void* addr, size_t length, int prot, int flags,
|
||||
struct shim_vma* vma1 = alloc_vma();
|
||||
|
||||
new_vma->begin = (uintptr_t)addr;
|
||||
new_vma->end = new_vma->begin + length;
|
||||
new_vma->prot = prot;
|
||||
new_vma->end = new_vma->begin + length;
|
||||
new_vma->prot = prot;
|
||||
new_vma->flags = filter_saved_flags(flags) | ((file && (prot & PROT_WRITE)) ? VMA_TAINTED : 0);
|
||||
new_vma->file = file;
|
||||
new_vma->file = file;
|
||||
if (new_vma->file) {
|
||||
get_handle(new_vma->file);
|
||||
}
|
||||
@@ -747,8 +747,7 @@ static void vma_update_prot(struct shim_vma* vma, int prot) {
|
||||
}
|
||||
|
||||
static int _vma_bkeep_change(uintptr_t begin, uintptr_t end, int prot, bool is_internal,
|
||||
struct shim_vma** new_vma_ptr1,
|
||||
struct shim_vma** new_vma_ptr2) {
|
||||
struct shim_vma** new_vma_ptr1, struct shim_vma** new_vma_ptr2) {
|
||||
assert(spinlock_is_locked(&vma_tree_lock));
|
||||
assert(IS_ALLOC_ALIGNED_PTR(begin) && IS_ALLOC_ALIGNED_PTR(end));
|
||||
assert(begin < end);
|
||||
@@ -878,8 +877,8 @@ int bkeep_mprotect(void* addr, size_t length, int prot, bool is_internal) {
|
||||
}
|
||||
|
||||
spinlock_lock_signal_off(&vma_tree_lock);
|
||||
int ret = _vma_bkeep_change((uintptr_t)addr, (uintptr_t)addr + length, prot, is_internal,
|
||||
&vma1, &vma2);
|
||||
int ret = _vma_bkeep_change((uintptr_t)addr, (uintptr_t)addr + length, prot, is_internal, &vma1,
|
||||
&vma2);
|
||||
spinlock_unlock_signal_on(&vma_tree_lock);
|
||||
|
||||
if (vma1) {
|
||||
@@ -912,7 +911,7 @@ int bkeep_mmap_any_in_range(void* _bottom_addr, void* _top_addr, size_t length,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
uintptr_t top_addr = (uintptr_t)_top_addr;
|
||||
uintptr_t top_addr = (uintptr_t)_top_addr;
|
||||
uintptr_t bottom_addr = (uintptr_t)_bottom_addr;
|
||||
int ret = 0;
|
||||
uintptr_t ret_val = 0;
|
||||
@@ -931,9 +930,9 @@ int bkeep_mmap_any_in_range(void* _bottom_addr, void* _top_addr, size_t length,
|
||||
if (!new_vma) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
new_vma->prot = prot;
|
||||
new_vma->prot = prot;
|
||||
new_vma->flags = filter_saved_flags(flags) | ((file && (prot & PROT_WRITE)) ? VMA_TAINTED : 0);
|
||||
new_vma->file = file;
|
||||
new_vma->file = file;
|
||||
if (new_vma->file) {
|
||||
get_handle(new_vma->file);
|
||||
}
|
||||
@@ -969,7 +968,7 @@ int bkeep_mmap_any_in_range(void* _bottom_addr, void* _top_addr, size_t length,
|
||||
}
|
||||
|
||||
out_found:
|
||||
new_vma->end = max_addr;
|
||||
new_vma->end = max_addr;
|
||||
new_vma->begin = new_vma->end - length;
|
||||
|
||||
avl_tree_insert(&vma_tree, &new_vma->tree_node);
|
||||
@@ -1007,12 +1006,12 @@ int bkeep_mmap_any_aslr(size_t length, int prot, int flags, struct shim_handle*
|
||||
}
|
||||
|
||||
static void dump_vma(struct shim_vma_info* vma_info, struct shim_vma* vma) {
|
||||
vma_info->addr = (void*)vma->begin;
|
||||
vma_info->length = vma->end - vma->begin;
|
||||
vma_info->prot = vma->prot;
|
||||
vma_info->flags = vma->flags;
|
||||
vma_info->addr = (void*)vma->begin;
|
||||
vma_info->length = vma->end - vma->begin;
|
||||
vma_info->prot = vma->prot;
|
||||
vma_info->flags = vma->flags;
|
||||
vma_info->file_offset = vma->offset;
|
||||
vma_info->file = vma->file;
|
||||
vma_info->file = vma->file;
|
||||
if (vma_info->file) {
|
||||
get_handle(vma_info->file);
|
||||
}
|
||||
@@ -1118,12 +1117,11 @@ void free_vma_info_array(struct shim_vma_info* vma_infos, size_t count) {
|
||||
free(vma_infos);
|
||||
}
|
||||
|
||||
BEGIN_CP_FUNC(vma)
|
||||
{
|
||||
BEGIN_CP_FUNC(vma) {
|
||||
__UNUSED(size);
|
||||
assert(size == sizeof(struct shim_vma_info));
|
||||
|
||||
struct shim_vma_info* vma = (struct shim_vma_info*) obj;
|
||||
struct shim_vma_info* vma = (struct shim_vma_info*)obj;
|
||||
struct shim_vma_info* new_vma = NULL;
|
||||
|
||||
size_t off = GET_FROM_CP_MAP(obj);
|
||||
@@ -1132,13 +1130,13 @@ BEGIN_CP_FUNC(vma)
|
||||
off = ADD_CP_OFFSET(sizeof(*vma));
|
||||
ADD_TO_CP_MAP(obj, off);
|
||||
|
||||
new_vma = (struct shim_vma_info*) (base + off);
|
||||
new_vma = (struct shim_vma_info*)(base + off);
|
||||
memcpy(new_vma, vma, sizeof(*vma));
|
||||
|
||||
if (vma->file)
|
||||
DO_CP(handle, vma->file, &new_vma->file);
|
||||
|
||||
void * need_mapped = vma->addr;
|
||||
void* need_mapped = vma->addr;
|
||||
|
||||
/* Check whether we need to checkpoint memory this vma bookkeeps. */
|
||||
if ((vma->flags & VMA_TAINTED || !vma->file) && !(vma->flags & VMA_UNMAPPED)) {
|
||||
@@ -1161,15 +1159,13 @@ BEGIN_CP_FUNC(vma)
|
||||
* forking. Has to be included in process migration.
|
||||
*/
|
||||
off_t file_len = get_file_size(vma->file);
|
||||
if (file_len >= 0 &&
|
||||
(off_t)(vma->file_offset + vma->length) > file_len) {
|
||||
send_size = file_len > vma->file_offset ?
|
||||
file_len - vma->file_offset : 0;
|
||||
if (file_len >= 0 && (off_t)(vma->file_offset + vma->length) > file_len) {
|
||||
send_size = file_len > vma->file_offset ? file_len - vma->file_offset : 0;
|
||||
send_size = ALLOC_ALIGN_UP(send_size);
|
||||
}
|
||||
}
|
||||
if (send_size > 0) {
|
||||
struct shim_mem_entry * mem;
|
||||
struct shim_mem_entry* mem;
|
||||
DO_CP_SIZE(memory, send_addr, send_size, &mem);
|
||||
mem->prot = LINUX_PROT_TO_PAL(vma->prot, /*map_flags=*/0);
|
||||
|
||||
@@ -1179,31 +1175,30 @@ BEGIN_CP_FUNC(vma)
|
||||
ADD_CP_FUNC_ENTRY(off);
|
||||
ADD_CP_ENTRY(ADDR, need_mapped);
|
||||
} else {
|
||||
new_vma = (struct shim_vma_info*) (base + off);
|
||||
new_vma = (struct shim_vma_info*)(base + off);
|
||||
}
|
||||
|
||||
if (objp)
|
||||
*objp = (void *) new_vma;
|
||||
*objp = (void*)new_vma;
|
||||
}
|
||||
END_CP_FUNC(vma)
|
||||
|
||||
BEGIN_RS_FUNC(vma)
|
||||
{
|
||||
struct shim_vma_info* vma = (void *) (base + GET_CP_FUNC_ENTRY());
|
||||
void * need_mapped = (void *) GET_CP_ENTRY(ADDR);
|
||||
BEGIN_RS_FUNC(vma) {
|
||||
struct shim_vma_info* vma = (void*)(base + GET_CP_FUNC_ENTRY());
|
||||
void* need_mapped = (void*)GET_CP_ENTRY(ADDR);
|
||||
CP_REBASE(vma->file);
|
||||
|
||||
DEBUG_RS("vma: %p-%p flags 0x%x prot 0x%08x comment \"%s\"\n",
|
||||
vma->addr, vma->addr + vma->length, vma->flags, vma->prot, vma->comment);
|
||||
DEBUG_RS("vma: %p-%p flags 0x%x prot 0x%08x comment \"%s\"\n", vma->addr,
|
||||
vma->addr + vma->length, vma->flags, vma->prot, vma->comment);
|
||||
|
||||
int ret = bkeep_mmap_fixed(vma->addr, vma->length, vma->prot, vma->flags | MAP_FIXED,
|
||||
vma->file, vma->file_offset, vma->comment);
|
||||
int ret = bkeep_mmap_fixed(vma->addr, vma->length, vma->prot, vma->flags | MAP_FIXED, vma->file,
|
||||
vma->file_offset, vma->comment);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!(vma->flags & VMA_UNMAPPED)) {
|
||||
if (vma->file) {
|
||||
struct shim_mount * fs = vma->file->fs;
|
||||
struct shim_mount* fs = vma->file->fs;
|
||||
get_handle(vma->file);
|
||||
|
||||
if (need_mapped < vma->addr + vma->length) {
|
||||
@@ -1212,14 +1207,10 @@ BEGIN_RS_FUNC(vma)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
void * addr = need_mapped;
|
||||
int ret = fs->fs_ops->mmap(vma->file, &addr,
|
||||
vma->addr + vma->length -
|
||||
need_mapped,
|
||||
vma->prot,
|
||||
vma->flags | MAP_FIXED,
|
||||
vma->file_offset +
|
||||
(need_mapped - vma->addr));
|
||||
void* addr = need_mapped;
|
||||
int ret = fs->fs_ops->mmap(vma->file, &addr, vma->addr + vma->length - need_mapped,
|
||||
vma->prot, vma->flags | MAP_FIXED,
|
||||
vma->file_offset + (need_mapped - vma->addr));
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -1241,24 +1232,20 @@ BEGIN_RS_FUNC(vma)
|
||||
}
|
||||
|
||||
if (need_mapped < vma->addr + vma->length)
|
||||
SYS_PRINTF("vma %p-%p cannot be allocated!\n", need_mapped,
|
||||
vma->addr + vma->length);
|
||||
SYS_PRINTF("vma %p-%p cannot be allocated!\n", need_mapped, vma->addr + vma->length);
|
||||
}
|
||||
|
||||
if (vma->file)
|
||||
DEBUG_RS("%p-%p,size=%ld,prot=%08x,flags=%08x,off=%ld,path=%s,uri=%s",
|
||||
vma->addr, vma->addr + vma->length, vma->length,
|
||||
vma->prot, vma->flags, vma->file_offset,
|
||||
DEBUG_RS("%p-%p,size=%ld,prot=%08x,flags=%08x,off=%ld,path=%s,uri=%s", vma->addr,
|
||||
vma->addr + vma->length, vma->length, vma->prot, vma->flags, vma->file_offset,
|
||||
qstrgetstr(&vma->file->path), qstrgetstr(&vma->file->uri));
|
||||
else
|
||||
DEBUG_RS("%p-%p,size=%ld,prot=%08x,flags=%08x,off=%ld",
|
||||
vma->addr, vma->addr + vma->length, vma->length,
|
||||
vma->prot, vma->flags, vma->file_offset);
|
||||
DEBUG_RS("%p-%p,size=%ld,prot=%08x,flags=%08x,off=%ld", vma->addr, vma->addr + vma->length,
|
||||
vma->length, vma->prot, vma->flags, vma->file_offset);
|
||||
}
|
||||
END_RS_FUNC(vma)
|
||||
|
||||
BEGIN_CP_FUNC(all_vmas)
|
||||
{
|
||||
BEGIN_CP_FUNC(all_vmas) {
|
||||
__UNUSED(obj);
|
||||
__UNUSED(size);
|
||||
__UNUSED(objp);
|
||||
|
||||
@@ -2,11 +2,8 @@
|
||||
/* Copyright (C) 2014 Stony Brook University */
|
||||
|
||||
/*
|
||||
* do-rel.c
|
||||
*
|
||||
* This file contains architecture-independent codes for relocating ELF
|
||||
* binaries.
|
||||
* Most of the source codes are imported from GNU C library.
|
||||
* This file contains architecture-independent code for relocating ELF binaries. Most of the source
|
||||
* code was imported from GNU C library.
|
||||
*/
|
||||
|
||||
#include "shim_dl-machine.h"
|
||||
|
||||
@@ -2,15 +2,14 @@
|
||||
/* Copyright (C) 2014 Stony Brook University */
|
||||
|
||||
/*
|
||||
* shim_rtld.c
|
||||
*
|
||||
* This file contains codes for dynamic loading of ELF binaries in library OS.
|
||||
* This file contains code for dynamic loading of ELF binaries in library OS.
|
||||
* It's espeically used for loading interpreter (ld.so, in general) and
|
||||
* optimization of execve.
|
||||
* Most of the source codes are imported from GNU C library.
|
||||
* Most of the source code was imported from GNU C library.
|
||||
*/
|
||||
|
||||
#include <asm/mman.h>
|
||||
#include <endian.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "elf.h"
|
||||
@@ -259,7 +258,6 @@ static struct link_map* new_elf_object(const char* realname, int type) {
|
||||
return new;
|
||||
}
|
||||
|
||||
#include <endian.h>
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define byteorder ELFDATA2MSB
|
||||
#elif __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
@@ -1057,18 +1055,19 @@ static unsigned long int elf_hash(const char* name_arg) {
|
||||
}
|
||||
|
||||
/* Check whether the symbol matches. */
|
||||
static ElfW(Sym)* check_match(ElfW(Sym)* sym, ElfW(Sym)* ref, const char* strtab, const char *undef_name, int len) {
|
||||
static ElfW(Sym)* check_match(ElfW(Sym)* sym, ElfW(Sym)* ref, const char* strtab,
|
||||
const char* undef_name, int len) {
|
||||
unsigned int stt = ELFW(ST_TYPE)(sym->st_info);
|
||||
|
||||
if ((sym->st_value == 0 /* No value */ && stt != STT_TLS) || sym->st_shndx == SHN_UNDEF)
|
||||
return NULL;
|
||||
|
||||
/* Ignore all but STT_NOTYPE, STT_OBJECT, STT_FUNC,
|
||||
STT_COMMON, STT_TLS, and STT_GNU_IFUNC since these are no
|
||||
code/data definitions. */
|
||||
#define ALLOWED_STT \
|
||||
((1 << STT_NOTYPE) | (1 << STT_OBJECT) | (1 << STT_FUNC) | (1 << STT_COMMON) | \
|
||||
(1 << STT_TLS) | (1 << STT_GNU_IFUNC))
|
||||
/* Ignore all but STT_NOTYPE, STT_OBJECT, STT_FUNC,
|
||||
STT_COMMON, STT_TLS, and STT_GNU_IFUNC since these are no
|
||||
code/data definitions. */
|
||||
#define ALLOWED_STT \
|
||||
((1 << STT_NOTYPE) | (1 << STT_OBJECT) | (1 << STT_FUNC) | (1 << STT_COMMON) | \
|
||||
(1 << STT_TLS) | (1 << STT_GNU_IFUNC))
|
||||
|
||||
if (((1 << stt) & ALLOWED_STT) == 0)
|
||||
return NULL;
|
||||
@@ -1272,7 +1271,7 @@ static int __load_interp_object(struct link_map* exec_map) {
|
||||
debug("search interpreter: %s\n", interp_path);
|
||||
|
||||
struct shim_dentry* dent = NULL;
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
if ((ret = path_lookupat(NULL, interp_path, LOOKUP_OPEN, &dent, NULL)) < 0 ||
|
||||
dent->state & DENTRY_NEGATIVE)
|
||||
@@ -1450,7 +1449,7 @@ int init_internal_map(void) {
|
||||
|
||||
int init_loader(void) {
|
||||
struct shim_thread* cur_thread = get_cur_thread();
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
lock(&cur_thread->lock);
|
||||
struct shim_handle* exec = cur_thread->exec;
|
||||
@@ -1577,7 +1576,7 @@ noreturn void execute_elf_object(struct shim_handle* exec, void* argp, ElfW(auxv
|
||||
ElfW(Addr) auxp_extra = (ElfW(Addr))&auxp[8];
|
||||
|
||||
ElfW(Addr) random = auxp_extra; /* random 16B for AT_RANDOM */
|
||||
ret = DkRandomBitsRead((PAL_PTR)random, 16);
|
||||
ret = DkRandomBitsRead((PAL_PTR)random, 16);
|
||||
if (ret < 0) {
|
||||
debug("execute_elf_object: DkRandomBitsRead failed.\n");
|
||||
DkThreadExit(/*clear_child_tid=*/NULL);
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
/* Copyright (C) 2014 Stony Brook University */
|
||||
|
||||
/*
|
||||
* fs.c
|
||||
*
|
||||
* This file contains codes for implementation of 'chroot' filesystem.
|
||||
* This file contains code for implementation of 'chroot' filesystem.
|
||||
*/
|
||||
|
||||
// FIXME: Sorting these includes causes a bunch of "error: ‘S_IFREG’ undeclared" errors.
|
||||
@@ -25,31 +23,32 @@
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/stat.h>
|
||||
|
||||
#define URI_MAX_SIZE STR_SIZE
|
||||
#define URI_MAX_SIZE STR_SIZE
|
||||
|
||||
#define FILE_BUFMAP_SIZE (PAL_CB(alloc_align) * 4)
|
||||
#define FILE_BUF_SIZE (PAL_CB(alloc_align))
|
||||
#define FILE_BUF_SIZE (PAL_CB(alloc_align))
|
||||
|
||||
struct mount_data {
|
||||
size_t data_size;
|
||||
size_t data_size;
|
||||
enum shim_file_type base_type;
|
||||
unsigned long ino_base;
|
||||
size_t root_uri_len;
|
||||
char root_uri[];
|
||||
unsigned long ino_base;
|
||||
size_t root_uri_len;
|
||||
char root_uri[];
|
||||
};
|
||||
|
||||
#define HANDLE_MOUNT_DATA(h) ((struct mount_data*)(h)->fs->data)
|
||||
#define DENTRY_MOUNT_DATA(d) ((struct mount_data*)(d)->fs->data)
|
||||
|
||||
static int chroot_mount (const char * uri, void ** mount_data)
|
||||
{
|
||||
static int chroot_mount(const char* uri, void** mount_data) {
|
||||
enum shim_file_type type;
|
||||
|
||||
if (strstartswith_static(uri, URI_PREFIX_FILE)) {
|
||||
type = FILE_UNKNOWN;
|
||||
uri += 5;
|
||||
} else if (strstartswith_static(uri, URI_PREFIX_DEV)) {
|
||||
type = strstartswith_static(uri + static_strlen(URI_PREFIX_DEV), "tty") ? FILE_TTY : FILE_DEV;
|
||||
type = strstartswith_static(uri + static_strlen(URI_PREFIX_DEV), "tty")
|
||||
? FILE_TTY
|
||||
: FILE_DEV;
|
||||
uri += 4;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
@@ -61,11 +60,11 @@ static int chroot_mount (const char * uri, void ** mount_data)
|
||||
int uri_len = strlen(uri);
|
||||
int data_size = uri_len + 1 + sizeof(struct mount_data);
|
||||
|
||||
struct mount_data * mdata = (struct mount_data *) malloc(data_size);
|
||||
struct mount_data* mdata = (struct mount_data*)malloc(data_size);
|
||||
|
||||
mdata->data_size = data_size;
|
||||
mdata->base_type = type;
|
||||
mdata->ino_base = hash_path(uri, uri_len);
|
||||
mdata->data_size = data_size;
|
||||
mdata->base_type = type;
|
||||
mdata->ino_base = hash_path(uri, uri_len);
|
||||
mdata->root_uri_len = uri_len;
|
||||
memcpy(mdata->root_uri, uri, uri_len + 1);
|
||||
|
||||
@@ -73,17 +72,14 @@ static int chroot_mount (const char * uri, void ** mount_data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int chroot_unmount (void * mount_data)
|
||||
{
|
||||
static int chroot_unmount(void* mount_data) {
|
||||
free(mount_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline ssize_t concat_uri (char * buffer, size_t size, int type,
|
||||
const char * root, size_t root_len,
|
||||
const char * trim, size_t trim_len)
|
||||
{
|
||||
char * tmp = NULL;
|
||||
static inline ssize_t concat_uri(char* buffer, size_t size, int type, const char* root,
|
||||
size_t root_len, const char* trim, size_t trim_len) {
|
||||
char* tmp = NULL;
|
||||
|
||||
switch (type) {
|
||||
case FILE_UNKNOWN:
|
||||
@@ -135,25 +131,20 @@ static struct shim_file_data* __create_data(void) {
|
||||
return data;
|
||||
}
|
||||
|
||||
static void __destroy_data (struct shim_file_data * data)
|
||||
{
|
||||
static void __destroy_data(struct shim_file_data* data) {
|
||||
qstrfree(&data->host_uri);
|
||||
destroy_lock(&data->lock);
|
||||
free(data);
|
||||
}
|
||||
|
||||
static ssize_t make_uri (struct shim_dentry * dent)
|
||||
{
|
||||
struct mount_data * mdata = DENTRY_MOUNT_DATA(dent);
|
||||
static ssize_t make_uri(struct shim_dentry* dent) {
|
||||
struct mount_data* mdata = DENTRY_MOUNT_DATA(dent);
|
||||
assert(mdata);
|
||||
|
||||
struct shim_file_data * data = FILE_DENTRY_DATA(dent);
|
||||
struct shim_file_data* data = FILE_DENTRY_DATA(dent);
|
||||
char uri[URI_MAX_SIZE];
|
||||
ssize_t len = concat_uri(uri, URI_MAX_SIZE, data->type,
|
||||
mdata->root_uri,
|
||||
mdata->root_uri_len,
|
||||
qstrgetstr(&dent->rel_path),
|
||||
dent->rel_path.len);
|
||||
ssize_t len = concat_uri(uri, URI_MAX_SIZE, data->type, mdata->root_uri, mdata->root_uri_len,
|
||||
qstrgetstr(&dent->rel_path), dent->rel_path.len);
|
||||
if (len >= 0)
|
||||
qstrsetstr(&data->host_uri, uri, len);
|
||||
|
||||
@@ -162,23 +153,21 @@ static ssize_t make_uri (struct shim_dentry * dent)
|
||||
|
||||
/* create a data in the dentry and compose it's uri. dent->lock needs to
|
||||
be held */
|
||||
static int create_data (struct shim_dentry * dent, const char * uri, size_t len)
|
||||
{
|
||||
static int create_data(struct shim_dentry* dent, const char* uri, size_t len) {
|
||||
assert(locked(&dent->lock));
|
||||
|
||||
if (dent->data)
|
||||
return 0;
|
||||
|
||||
struct shim_file_data * data = __create_data();
|
||||
struct shim_file_data* data = __create_data();
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
dent->data = data;
|
||||
|
||||
struct mount_data * mdata = DENTRY_MOUNT_DATA(dent);
|
||||
struct mount_data* mdata = DENTRY_MOUNT_DATA(dent);
|
||||
assert(mdata);
|
||||
data->type = (dent->state & DENTRY_ISDIRECTORY) ?
|
||||
FILE_DIR : mdata->base_type;
|
||||
data->type = (dent->state & DENTRY_ISDIRECTORY) ? FILE_DIR : mdata->base_type;
|
||||
data->mode = NO_MODE;
|
||||
|
||||
if (uri) {
|
||||
@@ -193,26 +182,35 @@ static int create_data (struct shim_dentry * dent, const char * uri, size_t len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int chroot_readdir (struct shim_dentry * dent,
|
||||
struct shim_dirent ** dirent);
|
||||
static int chroot_readdir(struct shim_dentry* dent, struct shim_dirent** dirent);
|
||||
|
||||
static int __query_attr (struct shim_dentry * dent,
|
||||
struct shim_file_data * data, PAL_HANDLE pal_handle)
|
||||
{
|
||||
static int __query_attr(struct shim_dentry* dent, struct shim_file_data* data,
|
||||
PAL_HANDLE pal_handle) {
|
||||
PAL_STREAM_ATTR pal_attr;
|
||||
enum shim_file_type old_type = data->type;
|
||||
|
||||
if (pal_handle ?
|
||||
!DkStreamAttributesQueryByHandle(pal_handle, &pal_attr) :
|
||||
!DkStreamAttributesQuery(qstrgetstr(&data->host_uri), &pal_attr))
|
||||
if (pal_handle ? !DkStreamAttributesQueryByHandle(pal_handle, &pal_attr)
|
||||
: !DkStreamAttributesQuery(qstrgetstr(&data->host_uri), &pal_attr))
|
||||
return -PAL_ERRNO();
|
||||
|
||||
/* need to correct the data type */
|
||||
if (data->type == FILE_UNKNOWN)
|
||||
switch (pal_attr.handle_type) {
|
||||
case pal_type_file: data->type = FILE_REGULAR; if (dent) dent->type = S_IFREG; break;
|
||||
case pal_type_dir: data->type = FILE_DIR; if (dent) dent->type = S_IFDIR; break;
|
||||
case pal_type_dev: data->type = FILE_DEV; if (dent) dent->type = S_IFCHR; break;
|
||||
case pal_type_file:
|
||||
data->type = FILE_REGULAR;
|
||||
if (dent)
|
||||
dent->type = S_IFREG;
|
||||
break;
|
||||
case pal_type_dir:
|
||||
data->type = FILE_DIR;
|
||||
if (dent)
|
||||
dent->type = S_IFDIR;
|
||||
break;
|
||||
case pal_type_dev:
|
||||
data->type = FILE_DEV;
|
||||
if (dent)
|
||||
dent->type = S_IFCHR;
|
||||
break;
|
||||
}
|
||||
|
||||
data->mode = (pal_attr.readable ? S_IRUSR : 0) |
|
||||
@@ -262,27 +260,23 @@ static int __query_attr (struct shim_dentry * dent,
|
||||
}
|
||||
|
||||
/* do not need any lock */
|
||||
static void chroot_update_ino (struct shim_dentry * dent)
|
||||
{
|
||||
static void chroot_update_ino(struct shim_dentry* dent) {
|
||||
if (dent->state & DENTRY_INO_UPDATED)
|
||||
return;
|
||||
|
||||
struct mount_data * mdata = DENTRY_MOUNT_DATA(dent);
|
||||
struct mount_data* mdata = DENTRY_MOUNT_DATA(dent);
|
||||
unsigned long ino = mdata->ino_base;
|
||||
|
||||
if (!qstrempty(&dent->rel_path))
|
||||
ino = rehash_path(mdata->ino_base, qstrgetstr(&dent->rel_path),
|
||||
dent->rel_path.len);
|
||||
ino = rehash_path(mdata->ino_base, qstrgetstr(&dent->rel_path), dent->rel_path.len);
|
||||
|
||||
dent->ino = ino;
|
||||
dent->state |= DENTRY_INO_UPDATED;
|
||||
}
|
||||
|
||||
static inline int try_create_data (struct shim_dentry * dent,
|
||||
const char * uri, size_t len,
|
||||
struct shim_file_data ** dataptr)
|
||||
{
|
||||
struct shim_file_data * data = FILE_DENTRY_DATA(dent);
|
||||
static inline int try_create_data(struct shim_dentry* dent, const char* uri, size_t len,
|
||||
struct shim_file_data** dataptr) {
|
||||
struct shim_file_data* data = FILE_DENTRY_DATA(dent);
|
||||
|
||||
if (!data) {
|
||||
lock(&dent->lock);
|
||||
@@ -298,12 +292,11 @@ static inline int try_create_data (struct shim_dentry * dent,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int query_dentry (struct shim_dentry * dent, PAL_HANDLE pal_handle,
|
||||
mode_t * mode, struct stat * stat)
|
||||
{
|
||||
static int query_dentry(struct shim_dentry* dent, PAL_HANDLE pal_handle, mode_t* mode,
|
||||
struct stat* stat) {
|
||||
int ret = 0;
|
||||
|
||||
struct shim_file_data * data;
|
||||
struct shim_file_data* data;
|
||||
if ((ret = try_create_data(dent, NULL, 0, &data)) < 0)
|
||||
return ret;
|
||||
|
||||
@@ -318,19 +311,19 @@ static int query_dentry (struct shim_dentry * dent, PAL_HANDLE pal_handle,
|
||||
*mode = data->mode;
|
||||
|
||||
if (stat) {
|
||||
struct mount_data * mdata = DENTRY_MOUNT_DATA(dent);
|
||||
struct mount_data* mdata = DENTRY_MOUNT_DATA(dent);
|
||||
chroot_update_ino(dent);
|
||||
|
||||
memset(stat, 0, sizeof(struct stat));
|
||||
|
||||
stat->st_mode = (mode_t) data->mode;
|
||||
stat->st_dev = (dev_t) mdata->ino_base;
|
||||
stat->st_ino = (ino_t) dent->ino;
|
||||
stat->st_size = (off_t) __atomic_load_n(&data->size.counter, __ATOMIC_SEQ_CST);
|
||||
stat->st_atime = (time_t) data->atime;
|
||||
stat->st_mtime = (time_t) data->mtime;
|
||||
stat->st_ctime = (time_t) data->ctime;
|
||||
stat->st_nlink = data->nlink;
|
||||
stat->st_mode = (mode_t)data->mode;
|
||||
stat->st_dev = (dev_t)mdata->ino_base;
|
||||
stat->st_ino = (ino_t)dent->ino;
|
||||
stat->st_size = (off_t)__atomic_load_n(&data->size.counter, __ATOMIC_SEQ_CST);
|
||||
stat->st_atime = (time_t)data->atime;
|
||||
stat->st_mtime = (time_t)data->mtime;
|
||||
stat->st_ctime = (time_t)data->ctime;
|
||||
stat->st_nlink = data->nlink;
|
||||
|
||||
switch (data->type) {
|
||||
case FILE_REGULAR:
|
||||
@@ -343,7 +336,8 @@ static int query_dentry (struct shim_dentry * dent, PAL_HANDLE pal_handle,
|
||||
case FILE_TTY:
|
||||
stat->st_mode |= S_IFCHR;
|
||||
break;
|
||||
default: break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,19 +345,15 @@ static int query_dentry (struct shim_dentry * dent, PAL_HANDLE pal_handle,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int chroot_mode (struct shim_dentry * dent, mode_t * mode)
|
||||
{
|
||||
static int chroot_mode(struct shim_dentry* dent, mode_t* mode) {
|
||||
return query_dentry(dent, NULL, mode, NULL);
|
||||
}
|
||||
|
||||
static int chroot_stat (struct shim_dentry * dent, struct stat * statbuf)
|
||||
{
|
||||
static int chroot_stat(struct shim_dentry* dent, struct stat* statbuf) {
|
||||
return query_dentry(dent, NULL, NULL, statbuf);
|
||||
}
|
||||
|
||||
static int chroot_lookup (struct shim_dentry * dent)
|
||||
{
|
||||
|
||||
static int chroot_lookup(struct shim_dentry* dent) {
|
||||
return query_dentry(dent, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -441,48 +431,46 @@ static int chroot_open(struct shim_handle* hdl, struct shim_dentry* dent, int fl
|
||||
if ((ret = __chroot_open(dent, NULL, flags, dent->mode, hdl, data)) < 0)
|
||||
return ret;
|
||||
|
||||
struct shim_file_handle * file = &hdl->info.file;
|
||||
struct shim_file_handle* file = &hdl->info.file;
|
||||
off_t size = __atomic_load_n(&data->size.counter, __ATOMIC_SEQ_CST);
|
||||
|
||||
/* initialize hdl, does not need a lock because no one is sharing */
|
||||
hdl->type = TYPE_FILE;
|
||||
file->marker = (flags & O_APPEND) ? size : 0;
|
||||
file->size = size;
|
||||
hdl->flags = flags;
|
||||
hdl->acc_mode = ACC_MODE(flags & O_ACCMODE);
|
||||
hdl->type = TYPE_FILE;
|
||||
hdl->flags = flags;
|
||||
hdl->acc_mode = ACC_MODE(flags & O_ACCMODE);
|
||||
file->marker = (flags & O_APPEND) ? size : 0;
|
||||
file->size = size;
|
||||
qstrcopy(&hdl->uri, &data->host_uri);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int chroot_creat (struct shim_handle * hdl, struct shim_dentry * dir,
|
||||
struct shim_dentry * dent, int flags, mode_t mode)
|
||||
{
|
||||
static int chroot_creat(struct shim_handle* hdl, struct shim_dentry* dir, struct shim_dentry* dent,
|
||||
int flags, mode_t mode) {
|
||||
int ret = 0;
|
||||
struct shim_file_data * data;
|
||||
struct shim_file_data* data;
|
||||
if ((ret = try_create_data(dent, NULL, 0, &data)) < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = __chroot_open(dent, NULL, flags|O_CREAT|O_EXCL, mode, hdl,
|
||||
data)) < 0)
|
||||
if ((ret = __chroot_open(dent, NULL, flags | O_CREAT | O_EXCL, mode, hdl, data)) < 0)
|
||||
return ret;
|
||||
|
||||
if (!hdl)
|
||||
return 0;
|
||||
|
||||
struct shim_file_handle * file = &hdl->info.file;
|
||||
struct shim_file_handle* file = &hdl->info.file;
|
||||
off_t size = __atomic_load_n(&data->size.counter, __ATOMIC_SEQ_CST);
|
||||
|
||||
/* initialize hdl, does not need a lock because no one is sharing */
|
||||
hdl->type = TYPE_FILE;
|
||||
file->marker = (flags & O_APPEND) ? size : 0;
|
||||
file->size = size;
|
||||
hdl->flags = flags;
|
||||
hdl->acc_mode = ACC_MODE(flags & O_ACCMODE);
|
||||
hdl->type = TYPE_FILE;
|
||||
hdl->flags = flags;
|
||||
hdl->acc_mode = ACC_MODE(flags & O_ACCMODE);
|
||||
file->marker = (flags & O_APPEND) ? size : 0;
|
||||
file->size = size;
|
||||
qstrcopy(&hdl->uri, &data->host_uri);
|
||||
|
||||
/* Increment the parent's link count */
|
||||
struct shim_file_data *parent_data = FILE_DENTRY_DATA(dir);
|
||||
struct shim_file_data* parent_data = FILE_DENTRY_DATA(dir);
|
||||
if (parent_data) {
|
||||
lock(&parent_data->lock);
|
||||
if (parent_data->queried)
|
||||
@@ -492,11 +480,9 @@ static int chroot_creat (struct shim_handle * hdl, struct shim_dentry * dir,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int chroot_mkdir (struct shim_dentry * dir, struct shim_dentry * dent,
|
||||
mode_t mode)
|
||||
{
|
||||
static int chroot_mkdir(struct shim_dentry* dir, struct shim_dentry* dent, mode_t mode) {
|
||||
int ret = 0;
|
||||
struct shim_file_data * data;
|
||||
struct shim_file_data* data;
|
||||
if ((ret = try_create_data(dent, NULL, 0, &data)) < 0)
|
||||
return ret;
|
||||
|
||||
@@ -510,7 +496,7 @@ static int chroot_mkdir (struct shim_dentry * dir, struct shim_dentry * dent,
|
||||
ret = __chroot_open(dent, NULL, O_CREAT | O_EXCL, mode, NULL, data);
|
||||
|
||||
/* Increment the parent's link count */
|
||||
struct shim_file_data *parent_data = FILE_DENTRY_DATA(dir);
|
||||
struct shim_file_data* parent_data = FILE_DENTRY_DATA(dir);
|
||||
if (parent_data) {
|
||||
lock(&parent_data->lock);
|
||||
if (parent_data->queried)
|
||||
@@ -520,18 +506,17 @@ static int chroot_mkdir (struct shim_dentry * dir, struct shim_dentry * dent,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define NEED_RECREATE(hdl) (!FILE_HANDLE_DATA(hdl))
|
||||
#define NEED_RECREATE(hdl) (!FILE_HANDLE_DATA(hdl))
|
||||
|
||||
static int chroot_recreate (struct shim_handle * hdl)
|
||||
{
|
||||
struct shim_file_data * data = FILE_HANDLE_DATA(hdl);
|
||||
static int chroot_recreate(struct shim_handle* hdl) {
|
||||
struct shim_file_data* data = FILE_HANDLE_DATA(hdl);
|
||||
int ret = 0;
|
||||
|
||||
/* quickly bail out if the data is created */
|
||||
if (data)
|
||||
return 0;
|
||||
|
||||
const char * uri = qstrgetstr(&hdl->uri);
|
||||
const char* uri = qstrgetstr(&hdl->uri);
|
||||
size_t len = hdl->uri.len;
|
||||
|
||||
if (hdl->dentry) {
|
||||
@@ -548,12 +533,10 @@ static int chroot_recreate (struct shim_handle * hdl)
|
||||
* when recreating a file handle after migration, the file should
|
||||
* not be created again.
|
||||
*/
|
||||
return __chroot_open(hdl->dentry, uri, hdl->flags & ~(O_CREAT|O_EXCL),
|
||||
0, hdl, data);
|
||||
return __chroot_open(hdl->dentry, uri, hdl->flags & ~(O_CREAT | O_EXCL), 0, hdl, data);
|
||||
}
|
||||
|
||||
static inline bool check_version (struct shim_handle * hdl)
|
||||
{
|
||||
static inline bool check_version(struct shim_handle* hdl) {
|
||||
return __atomic_load_n(&FILE_HANDLE_DATA(hdl)->version.counter, __ATOMIC_SEQ_CST)
|
||||
== hdl->info.file.version;
|
||||
}
|
||||
@@ -572,24 +555,23 @@ static void chroot_update_size(struct shim_handle* hdl, struct shim_file_handle*
|
||||
}
|
||||
}
|
||||
|
||||
static int chroot_hstat (struct shim_handle * hdl, struct stat * stat)
|
||||
{
|
||||
static int chroot_hstat(struct shim_handle* hdl, struct stat* stat) {
|
||||
int ret;
|
||||
if (NEED_RECREATE(hdl) && (ret = chroot_recreate(hdl)) < 0)
|
||||
return ret;
|
||||
|
||||
if (!check_version(hdl) || !hdl->dentry) {
|
||||
struct shim_file_handle * file = &hdl->info.file;
|
||||
struct shim_dentry * dent = hdl->dentry;
|
||||
struct mount_data * mdata = dent ? DENTRY_MOUNT_DATA(dent) : NULL;
|
||||
struct shim_file_handle* file = &hdl->info.file;
|
||||
struct shim_dentry* dent = hdl->dentry;
|
||||
struct mount_data* mdata = dent ? DENTRY_MOUNT_DATA(dent) : NULL;
|
||||
|
||||
if (dent)
|
||||
chroot_update_ino(dent);
|
||||
|
||||
if (stat) {
|
||||
memset(stat, 0, sizeof(struct stat));
|
||||
stat->st_dev = mdata ? (dev_t) mdata->ino_base : 0;
|
||||
stat->st_ino = dent ? (ino_t) dent->ino : 0;
|
||||
stat->st_dev = mdata ? (dev_t)mdata->ino_base : 0;
|
||||
stat->st_ino = dent ? (ino_t)dent->ino : 0;
|
||||
stat->st_size = file->size;
|
||||
stat->st_mode |= (file->type == FILE_REGULAR) ? S_IFREG : S_IFCHR;
|
||||
}
|
||||
@@ -612,8 +594,7 @@ static int chroot_close(struct shim_handle* hdl) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t chroot_read (struct shim_handle * hdl, void * buf, size_t count)
|
||||
{
|
||||
static ssize_t chroot_read(struct shim_handle* hdl, void* buf, size_t count) {
|
||||
ssize_t ret = 0;
|
||||
|
||||
if (count == 0)
|
||||
@@ -628,7 +609,7 @@ static ssize_t chroot_read (struct shim_handle * hdl, void * buf, size_t count)
|
||||
goto out;
|
||||
}
|
||||
|
||||
struct shim_file_handle * file = &hdl->info.file;
|
||||
struct shim_file_handle* file = &hdl->info.file;
|
||||
|
||||
off_t dummy_off_t;
|
||||
if (file->type != FILE_TTY && __builtin_add_overflow(file->marker, count, &dummy_off_t)) {
|
||||
@@ -645,7 +626,7 @@ static ssize_t chroot_read (struct shim_handle * hdl, void * buf, size_t count)
|
||||
if (file->type != FILE_TTY && __builtin_add_overflow(file->marker, pal_ret, &file->marker))
|
||||
BUG();
|
||||
} else {
|
||||
ret = PAL_NATIVE_ERRNO() == PAL_ERROR_ENDOFSTREAM ? 0 : -PAL_ERRNO();
|
||||
ret = PAL_NATIVE_ERRNO() == PAL_ERROR_ENDOFSTREAM ? 0 : -PAL_ERRNO();
|
||||
}
|
||||
|
||||
unlock(&hdl->lock);
|
||||
@@ -653,8 +634,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t chroot_write (struct shim_handle * hdl, const void * buf, size_t count)
|
||||
{
|
||||
static ssize_t chroot_write(struct shim_handle* hdl, const void* buf, size_t count) {
|
||||
ssize_t ret;
|
||||
|
||||
if (count == 0)
|
||||
@@ -669,7 +649,7 @@ static ssize_t chroot_write (struct shim_handle * hdl, const void * buf, size_t
|
||||
goto out;
|
||||
}
|
||||
|
||||
struct shim_file_handle * file = &hdl->info.file;
|
||||
struct shim_file_handle* file = &hdl->info.file;
|
||||
|
||||
off_t dummy_off_t;
|
||||
if (file->type != FILE_TTY && __builtin_add_overflow(file->marker, count, &dummy_off_t)) {
|
||||
@@ -679,7 +659,7 @@ static ssize_t chroot_write (struct shim_handle * hdl, const void * buf, size_t
|
||||
|
||||
lock(&hdl->lock);
|
||||
|
||||
PAL_NUM pal_ret = DkStreamWrite(hdl->pal_handle, file->marker, count, (void *) buf, NULL);
|
||||
PAL_NUM pal_ret = DkStreamWrite(hdl->pal_handle, file->marker, count, (void*)buf, NULL);
|
||||
if (pal_ret != PAL_STREAM_ERROR) {
|
||||
if (__builtin_add_overflow(pal_ret, 0, &ret))
|
||||
BUG();
|
||||
@@ -690,7 +670,7 @@ static ssize_t chroot_write (struct shim_handle * hdl, const void * buf, size_t
|
||||
chroot_update_size(hdl, file, FILE_HANDLE_DATA(hdl));
|
||||
}
|
||||
} else {
|
||||
ret = PAL_NATIVE_ERRNO() == PAL_ERROR_ENDOFSTREAM ? 0 : -PAL_ERRNO();
|
||||
ret = PAL_NATIVE_ERRNO() == PAL_ERROR_ENDOFSTREAM ? 0 : -PAL_ERRNO();
|
||||
}
|
||||
|
||||
unlock(&hdl->lock);
|
||||
@@ -698,9 +678,8 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int chroot_mmap (struct shim_handle * hdl, void ** addr, size_t size,
|
||||
int prot, int flags, off_t offset)
|
||||
{
|
||||
static int chroot_mmap(struct shim_handle* hdl, void** addr, size_t size, int prot, int flags,
|
||||
off_t offset) {
|
||||
int ret;
|
||||
if (NEED_RECREATE(hdl) && (ret = chroot_recreate(hdl)) < 0)
|
||||
return ret;
|
||||
@@ -714,8 +693,7 @@ static int chroot_mmap (struct shim_handle * hdl, void ** addr, size_t size,
|
||||
#endif
|
||||
return -EINVAL;
|
||||
|
||||
void * alloc_addr =
|
||||
(void *) DkStreamMap(hdl->pal_handle, *addr, pal_prot, offset, size);
|
||||
void* alloc_addr = (void*)DkStreamMap(hdl->pal_handle, *addr, pal_prot, offset, size);
|
||||
|
||||
if (!alloc_addr)
|
||||
return -PAL_ERRNO();
|
||||
@@ -724,21 +702,20 @@ static int chroot_mmap (struct shim_handle * hdl, void ** addr, size_t size,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static off_t chroot_seek (struct shim_handle * hdl, off_t offset, int wence)
|
||||
{
|
||||
static off_t chroot_seek(struct shim_handle* hdl, off_t offset, int wence) {
|
||||
off_t ret = -EINVAL;
|
||||
|
||||
if (NEED_RECREATE(hdl) && (ret = chroot_recreate(hdl)) < 0)
|
||||
return ret;
|
||||
|
||||
struct shim_file_handle * file = &hdl->info.file;
|
||||
struct shim_file_handle* file = &hdl->info.file;
|
||||
lock(&hdl->lock);
|
||||
|
||||
off_t marker = file->marker;
|
||||
off_t size = file->size;
|
||||
|
||||
if (check_version(hdl)) {
|
||||
struct shim_file_data * data = FILE_HANDLE_DATA(hdl);
|
||||
struct shim_file_data* data = FILE_HANDLE_DATA(hdl);
|
||||
if (data->type != FILE_REGULAR) {
|
||||
ret = -ESPIPE;
|
||||
goto out;
|
||||
@@ -768,8 +745,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int chroot_truncate (struct shim_handle * hdl, off_t len)
|
||||
{
|
||||
static int chroot_truncate(struct shim_handle* hdl, off_t len) {
|
||||
int ret = 0;
|
||||
|
||||
if (NEED_RECREATE(hdl) && (ret = chroot_recreate(hdl)) < 0)
|
||||
@@ -778,7 +754,7 @@ static int chroot_truncate (struct shim_handle * hdl, off_t len)
|
||||
if (!(hdl->acc_mode & MAY_WRITE))
|
||||
return -EINVAL;
|
||||
|
||||
struct shim_file_handle * file = &hdl->info.file;
|
||||
struct shim_file_handle* file = &hdl->info.file;
|
||||
lock(&hdl->lock);
|
||||
|
||||
file->size = len;
|
||||
@@ -806,9 +782,8 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int chroot_dput (struct shim_dentry * dent)
|
||||
{
|
||||
struct shim_file_data * data = FILE_DENTRY_DATA(dent);
|
||||
static int chroot_dput(struct shim_dentry* dent) {
|
||||
struct shim_file_data* data = FILE_DENTRY_DATA(dent);
|
||||
|
||||
if (data) {
|
||||
__destroy_data(data);
|
||||
@@ -822,8 +797,8 @@ static int chroot_readdir(struct shim_dentry* dent, struct shim_dirent** dirent)
|
||||
struct shim_file_data* data = NULL;
|
||||
int ret = 0;
|
||||
PAL_HANDLE pal_hdl = NULL;
|
||||
size_t buf_size = MAX_PATH,
|
||||
dirent_buf_size = 0;
|
||||
size_t buf_size = MAX_PATH;
|
||||
size_t dirent_buf_size = 0;
|
||||
char* buf = NULL;
|
||||
char* dirent_buf = NULL;
|
||||
|
||||
@@ -910,7 +885,7 @@ static int chroot_readdir(struct shim_dentry* dent, struct shim_dirent** dirent)
|
||||
}
|
||||
|
||||
struct shim_dirent* dptr = (struct shim_dirent*)(dirent_buf + dirent_cur_off);
|
||||
dptr->ino = rehash_name(dent->ino, name, len);
|
||||
dptr->ino = rehash_name(dent->ino, name, len);
|
||||
dptr->type = is_dir ? LINUX_DT_DIR : LINUX_DT_REG;
|
||||
memcpy(dptr->name, name, len + 1);
|
||||
|
||||
@@ -928,7 +903,7 @@ static int chroot_readdir(struct shim_dentry* dent, struct shim_dirent** dirent)
|
||||
* rewritten as such one day).
|
||||
*/
|
||||
struct shim_dirent** last = NULL;
|
||||
for (size_t dirent_cur_off = 0; dirent_cur_off < dirent_buf_size; ) {
|
||||
for (size_t dirent_cur_off = 0; dirent_cur_off < dirent_buf_size;) {
|
||||
struct shim_dirent* dptr = (struct shim_dirent*)(dirent_buf + dirent_cur_off);
|
||||
size_t len = SHIM_DIRENT_ALIGNED_SIZE(strlen(dptr->name) + 1);
|
||||
dptr->next = (struct shim_dirent*)(dirent_buf + dirent_cur_off + len);
|
||||
@@ -949,13 +924,12 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int chroot_checkout (struct shim_handle * hdl)
|
||||
{
|
||||
static int chroot_checkout(struct shim_handle* hdl) {
|
||||
if (hdl->fs == &chroot_builtin_fs)
|
||||
hdl->fs = NULL;
|
||||
|
||||
if (hdl->type == TYPE_FILE) {
|
||||
struct shim_file_data * data = FILE_HANDLE_DATA(hdl);
|
||||
struct shim_file_data* data = FILE_HANDLE_DATA(hdl);
|
||||
if (data)
|
||||
hdl->info.file.data = NULL;
|
||||
}
|
||||
@@ -973,20 +947,18 @@ static int chroot_checkout (struct shim_handle * hdl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t chroot_checkpoint (void ** checkpoint, void * mount_data)
|
||||
{
|
||||
struct mount_data * mdata = mount_data;
|
||||
static ssize_t chroot_checkpoint(void** checkpoint, void* mount_data) {
|
||||
struct mount_data* mdata = mount_data;
|
||||
|
||||
*checkpoint = mount_data;
|
||||
return mdata->root_uri_len + sizeof(struct mount_data) + 1;
|
||||
}
|
||||
|
||||
static int chroot_migrate (void * checkpoint, void ** mount_data)
|
||||
{
|
||||
struct mount_data * mdata = checkpoint;
|
||||
static int chroot_migrate(void* checkpoint, void** mount_data) {
|
||||
struct mount_data* mdata = checkpoint;
|
||||
size_t alloc_len = mdata->root_uri_len + sizeof(struct mount_data) + 1;
|
||||
|
||||
void * new_data = malloc(alloc_len);
|
||||
void* new_data = malloc(alloc_len);
|
||||
if (!new_data)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -996,10 +968,9 @@ static int chroot_migrate (void * checkpoint, void ** mount_data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int chroot_unlink (struct shim_dentry * dir, struct shim_dentry * dent)
|
||||
{
|
||||
static int chroot_unlink(struct shim_dentry* dir, struct shim_dentry* dent) {
|
||||
int ret;
|
||||
struct shim_file_data * data;
|
||||
struct shim_file_data* data;
|
||||
if ((ret = try_create_data(dent, NULL, 0, &data)) < 0)
|
||||
return ret;
|
||||
|
||||
@@ -1017,7 +988,7 @@ static int chroot_unlink (struct shim_dentry * dir, struct shim_dentry * dent)
|
||||
__atomic_store_n(&data->size.counter, 0, __ATOMIC_SEQ_CST);
|
||||
|
||||
/* Drop the parent's link count */
|
||||
struct shim_file_data *parent_data = FILE_DENTRY_DATA(dir);
|
||||
struct shim_file_data* parent_data = FILE_DENTRY_DATA(dir);
|
||||
if (parent_data) {
|
||||
lock(&parent_data->lock);
|
||||
if (parent_data->queried)
|
||||
@@ -1028,13 +999,12 @@ static int chroot_unlink (struct shim_dentry * dir, struct shim_dentry * dent)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static off_t chroot_poll (struct shim_handle * hdl, int poll_type)
|
||||
{
|
||||
static off_t chroot_poll(struct shim_handle* hdl, int poll_type) {
|
||||
int ret;
|
||||
if (NEED_RECREATE(hdl) && (ret = chroot_recreate(hdl)) < 0)
|
||||
return ret;
|
||||
|
||||
struct shim_file_data * data = FILE_HANDLE_DATA(hdl);
|
||||
struct shim_file_data* data = FILE_HANDLE_DATA(hdl);
|
||||
off_t size = __atomic_load_n(&data->size.counter, __ATOMIC_SEQ_CST);
|
||||
|
||||
if (poll_type == FS_POLL_SZ)
|
||||
@@ -1042,9 +1012,8 @@ static off_t chroot_poll (struct shim_handle * hdl, int poll_type)
|
||||
|
||||
lock(&hdl->lock);
|
||||
|
||||
struct shim_file_handle * file = &hdl->info.file;
|
||||
if (check_version(hdl) &&
|
||||
file->size < size)
|
||||
struct shim_file_handle* file = &hdl->info.file;
|
||||
if (check_version(hdl) && file->size < size)
|
||||
file->size = size;
|
||||
|
||||
off_t marker = file->marker;
|
||||
@@ -1101,10 +1070,9 @@ static int chroot_rename(struct shim_dentry* old, struct shim_dentry* new) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int chroot_chmod (struct shim_dentry * dent, mode_t mode)
|
||||
{
|
||||
static int chroot_chmod(struct shim_dentry* dent, mode_t mode) {
|
||||
int ret;
|
||||
struct shim_file_data * data;
|
||||
struct shim_file_data* data;
|
||||
if ((ret = try_create_data(dent, NULL, 0, &data)) < 0)
|
||||
return ret;
|
||||
|
||||
@@ -1112,7 +1080,7 @@ static int chroot_chmod (struct shim_dentry * dent, mode_t mode)
|
||||
if (!pal_hdl)
|
||||
return -PAL_ERRNO();
|
||||
|
||||
PAL_STREAM_ATTR attr = { .share_flags = mode };
|
||||
PAL_STREAM_ATTR attr = {.share_flags = mode};
|
||||
|
||||
if (!DkStreamAttributesSetByHandle(pal_hdl, &attr)) {
|
||||
DkObjectClose(pal_hdl);
|
||||
@@ -1126,40 +1094,44 @@ static int chroot_chmod (struct shim_dentry * dent, mode_t mode)
|
||||
}
|
||||
|
||||
struct shim_fs_ops chroot_fs_ops = {
|
||||
.mount = &chroot_mount,
|
||||
.unmount = &chroot_unmount,
|
||||
.flush = &chroot_flush,
|
||||
.close = &chroot_close,
|
||||
.read = &chroot_read,
|
||||
.write = &chroot_write,
|
||||
.mmap = &chroot_mmap,
|
||||
.seek = &chroot_seek,
|
||||
.hstat = &chroot_hstat,
|
||||
.truncate = &chroot_truncate,
|
||||
.checkout = &chroot_checkout,
|
||||
.checkpoint = &chroot_checkpoint,
|
||||
.migrate = &chroot_migrate,
|
||||
.poll = &chroot_poll,
|
||||
};
|
||||
.mount = &chroot_mount,
|
||||
.unmount = &chroot_unmount,
|
||||
.flush = &chroot_flush,
|
||||
.close = &chroot_close,
|
||||
.read = &chroot_read,
|
||||
.write = &chroot_write,
|
||||
.mmap = &chroot_mmap,
|
||||
.seek = &chroot_seek,
|
||||
.hstat = &chroot_hstat,
|
||||
.truncate = &chroot_truncate,
|
||||
.checkout = &chroot_checkout,
|
||||
.checkpoint = &chroot_checkpoint,
|
||||
.migrate = &chroot_migrate,
|
||||
.poll = &chroot_poll,
|
||||
};
|
||||
|
||||
struct shim_d_ops chroot_d_ops = {
|
||||
.open = &chroot_open,
|
||||
.mode = &chroot_mode,
|
||||
.lookup = &chroot_lookup,
|
||||
.creat = &chroot_creat,
|
||||
.mkdir = &chroot_mkdir,
|
||||
.stat = &chroot_stat,
|
||||
.dput = &chroot_dput,
|
||||
.readdir = &chroot_readdir,
|
||||
.unlink = &chroot_unlink,
|
||||
.rename = &chroot_rename,
|
||||
.chmod = &chroot_chmod,
|
||||
};
|
||||
.open = &chroot_open,
|
||||
.mode = &chroot_mode,
|
||||
.lookup = &chroot_lookup,
|
||||
.creat = &chroot_creat,
|
||||
.mkdir = &chroot_mkdir,
|
||||
.stat = &chroot_stat,
|
||||
.dput = &chroot_dput,
|
||||
.readdir = &chroot_readdir,
|
||||
.unlink = &chroot_unlink,
|
||||
.rename = &chroot_rename,
|
||||
.chmod = &chroot_chmod,
|
||||
};
|
||||
|
||||
struct mount_data chroot_data = { .root_uri_len = 5,
|
||||
.root_uri = URI_PREFIX_FILE, };
|
||||
struct mount_data chroot_data = {
|
||||
.root_uri_len = 5,
|
||||
.root_uri = URI_PREFIX_FILE,
|
||||
};
|
||||
|
||||
struct shim_mount chroot_builtin_fs = { .type = "chroot",
|
||||
.fs_ops = &chroot_fs_ops,
|
||||
.d_ops = &chroot_d_ops,
|
||||
.data = &chroot_data, };
|
||||
struct shim_mount chroot_builtin_fs = {
|
||||
.type = "chroot",
|
||||
.fs_ops = &chroot_fs_ops,
|
||||
.d_ops = &chroot_d_ops,
|
||||
.data = &chroot_data,
|
||||
};
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
* these sizes are overapproximations of SGX requirements (report_data is 64B, target_info is
|
||||
* 512B, EPID quote is about 1KB, DCAP quote is about 4KB). */
|
||||
#define USER_REPORT_DATA_MAX_SIZE 256
|
||||
#define TARGET_INFO_MAX_SIZE 1024
|
||||
#define QUOTE_MAX_SIZE 8192
|
||||
#define TARGET_INFO_MAX_SIZE 1024
|
||||
#define QUOTE_MAX_SIZE 8192
|
||||
|
||||
static char g_user_report_data[USER_REPORT_DATA_MAX_SIZE] = {0};
|
||||
static size_t g_user_report_data_size = 0;
|
||||
@@ -68,8 +68,8 @@ static int dev_attestation_readwrite_mode(const char* name, mode_t* mode) {
|
||||
static int dev_attestation_readonly_stat(const char* name, struct stat* buf) {
|
||||
__UNUSED(name);
|
||||
memset(buf, 0, sizeof(*buf));
|
||||
buf->st_dev = 1; /* dummy ID of device containing file */
|
||||
buf->st_ino = 1; /* dummy inode number */
|
||||
buf->st_dev = 1; /* dummy ID of device containing file */
|
||||
buf->st_ino = 1; /* dummy inode number */
|
||||
buf->st_mode = FILE_R_MODE | S_IFREG;
|
||||
return 0;
|
||||
}
|
||||
@@ -77,8 +77,8 @@ static int dev_attestation_readonly_stat(const char* name, struct stat* buf) {
|
||||
static int dev_attestation_readwrite_stat(const char* name, struct stat* buf) {
|
||||
__UNUSED(name);
|
||||
memset(buf, 0, sizeof(*buf));
|
||||
buf->st_dev = 1; /* dummy ID of device containing file */
|
||||
buf->st_ino = 1; /* dummy inode number */
|
||||
buf->st_dev = 1; /* dummy ID of device containing file */
|
||||
buf->st_ino = 1; /* dummy inode number */
|
||||
buf->st_mode = FILE_RW_MODE | S_IFREG;
|
||||
return 0;
|
||||
}
|
||||
@@ -197,7 +197,8 @@ static int dev_attestation_target_info_open(struct shim_handle* hdl, const char*
|
||||
*
|
||||
* In case of SGX, target info is an opaque blob of size 512B.
|
||||
*/
|
||||
static int dev_attestation_my_target_info_open(struct shim_handle* hdl, const char* name, int flags) {
|
||||
static int dev_attestation_my_target_info_open(struct shim_handle* hdl, const char* name,
|
||||
int flags) {
|
||||
__UNUSED(name);
|
||||
int ret;
|
||||
|
||||
@@ -234,9 +235,8 @@ static int dev_attestation_my_target_info_open(struct shim_handle* hdl, const ch
|
||||
|
||||
/* below invocation returns this enclave's target info because we zeroed out (via calloc)
|
||||
* target_info: it's a hint to function to update target_info with this enclave's info */
|
||||
bool ok = DkAttestationReport(user_report_data, &user_report_data_size,
|
||||
target_info, &target_info_size,
|
||||
/*report=*/NULL, &report_size);
|
||||
bool ok = DkAttestationReport(user_report_data, &user_report_data_size, target_info,
|
||||
&target_info_size, /*report=*/NULL, &report_size);
|
||||
if (!ok) {
|
||||
ret = -EACCES;
|
||||
goto out;
|
||||
@@ -253,9 +253,9 @@ static int dev_attestation_my_target_info_open(struct shim_handle* hdl, const ch
|
||||
goto out;
|
||||
}
|
||||
|
||||
data->str = target_info;
|
||||
data->buf_size = target_info_size;
|
||||
data->len = target_info_size;
|
||||
data->str = target_info;
|
||||
data->buf_size = target_info_size;
|
||||
data->len = target_info_size;
|
||||
|
||||
hdl->type = TYPE_STR;
|
||||
hdl->acc_mode = MAY_READ;
|
||||
@@ -308,9 +308,8 @@ static int dev_attestation_report_open(struct shim_handle* hdl, const char* name
|
||||
goto out;
|
||||
}
|
||||
|
||||
bool ok = DkAttestationReport(&g_user_report_data, &g_user_report_data_size,
|
||||
&g_target_info, &g_target_info_size,
|
||||
report, &g_report_size);
|
||||
bool ok = DkAttestationReport(&g_user_report_data, &g_user_report_data_size, &g_target_info,
|
||||
&g_target_info_size, report, &g_report_size);
|
||||
if (!ok) {
|
||||
ret = -EACCES;
|
||||
goto out;
|
||||
@@ -389,8 +388,7 @@ static int dev_attestation_quote_open(struct shim_handle* hdl, const char* name,
|
||||
goto out;
|
||||
}
|
||||
|
||||
bool ok = DkAttestationQuote(&g_user_report_data, g_user_report_data_size,
|
||||
quote, "e_size);
|
||||
bool ok = DkAttestationQuote(&g_user_report_data, g_user_report_data_size, quote, "e_size);
|
||||
if (!ok) {
|
||||
ret = -EACCES;
|
||||
goto out;
|
||||
@@ -410,9 +408,9 @@ static int dev_attestation_quote_open(struct shim_handle* hdl, const char* name,
|
||||
|
||||
memcpy(data_str_quote, quote, quote_size);
|
||||
|
||||
data->str = data_str_quote;
|
||||
data->buf_size = quote_size;
|
||||
data->len = quote_size;
|
||||
data->str = data_str_quote;
|
||||
data->buf_size = quote_size;
|
||||
data->len = quote_size;
|
||||
|
||||
hdl->type = TYPE_STR;
|
||||
hdl->acc_mode = MAY_READ;
|
||||
@@ -525,23 +523,22 @@ struct pseudo_fs_ops dev_attestation_fs_ops = {
|
||||
struct pseudo_dir dev_attestation_dir = {
|
||||
.size = 6,
|
||||
.ent = {
|
||||
{ .name = "user_report_data",
|
||||
.fs_ops = &dev_attestation_user_report_data_fs_ops,
|
||||
.type = LINUX_DT_REG },
|
||||
{ .name = "target_info",
|
||||
.fs_ops = &dev_attestation_target_info_fs_ops,
|
||||
.type = LINUX_DT_REG },
|
||||
{ .name = "my_target_info",
|
||||
.fs_ops = &dev_attestation_my_target_info_fs_ops,
|
||||
.type = LINUX_DT_REG },
|
||||
{ .name = "report",
|
||||
.fs_ops = &dev_attestation_report_fs_ops,
|
||||
.type = LINUX_DT_REG },
|
||||
{ .name = "quote",
|
||||
.fs_ops = &dev_attestation_quote_fs_ops,
|
||||
.type = LINUX_DT_REG },
|
||||
{ .name = "protected_files_key",
|
||||
.fs_ops = &dev_attestation_pfkey_fs_ops,
|
||||
.type = LINUX_DT_REG },
|
||||
}
|
||||
};
|
||||
{.name = "user_report_data",
|
||||
.fs_ops = &dev_attestation_user_report_data_fs_ops,
|
||||
.type = LINUX_DT_REG},
|
||||
{.name = "target_info",
|
||||
.fs_ops = &dev_attestation_target_info_fs_ops,
|
||||
.type = LINUX_DT_REG},
|
||||
{.name = "my_target_info",
|
||||
.fs_ops = &dev_attestation_my_target_info_fs_ops,
|
||||
.type = LINUX_DT_REG},
|
||||
{.name = "report",
|
||||
.fs_ops = &dev_attestation_report_fs_ops,
|
||||
.type = LINUX_DT_REG},
|
||||
{.name = "quote",
|
||||
.fs_ops = &dev_attestation_quote_fs_ops,
|
||||
.type = LINUX_DT_REG},
|
||||
{.name = "protected_files_key",
|
||||
.fs_ops = &dev_attestation_pfkey_fs_ops,
|
||||
.type = LINUX_DT_REG},
|
||||
}};
|
||||
|
||||
@@ -23,35 +23,35 @@ extern const struct pseudo_dir dev_attestation_dir;
|
||||
|
||||
static const struct pseudo_dir dev_root_dir = {
|
||||
.size = 9,
|
||||
.ent = {
|
||||
{ .name = "null",
|
||||
.fs_ops = &dev_null_fs_ops,
|
||||
.type = LINUX_DT_CHR },
|
||||
{ .name = "tty",
|
||||
.fs_ops = &dev_tty_fs_ops,
|
||||
.type = LINUX_DT_CHR },
|
||||
{ .name = "zero",
|
||||
.fs_ops = &dev_zero_fs_ops,
|
||||
.type = LINUX_DT_CHR },
|
||||
{ .name = "random",
|
||||
.fs_ops = &dev_random_fs_ops,
|
||||
.type = LINUX_DT_CHR },
|
||||
{ .name = "urandom",
|
||||
.fs_ops = &dev_urandom_fs_ops,
|
||||
.type = LINUX_DT_CHR },
|
||||
{ .name = "stdin",
|
||||
.fs_ops = &dev_stdin_fs_ops,
|
||||
.type = LINUX_DT_LNK },
|
||||
{ .name = "stdout",
|
||||
.fs_ops = &dev_stdout_fs_ops,
|
||||
.type = LINUX_DT_LNK },
|
||||
{ .name = "stderr",
|
||||
.fs_ops = &dev_stderr_fs_ops,
|
||||
.type = LINUX_DT_LNK },
|
||||
{ .name = "attestation",
|
||||
.fs_ops = &dev_attestation_fs_ops,
|
||||
.type = LINUX_DT_DIR,
|
||||
.dir = &dev_attestation_dir },
|
||||
.ent = {
|
||||
{.name = "null",
|
||||
.fs_ops = &dev_null_fs_ops,
|
||||
.type = LINUX_DT_CHR},
|
||||
{.name = "tty",
|
||||
.fs_ops = &dev_tty_fs_ops,
|
||||
.type = LINUX_DT_CHR},
|
||||
{.name = "zero",
|
||||
.fs_ops = &dev_zero_fs_ops,
|
||||
.type = LINUX_DT_CHR},
|
||||
{.name = "random",
|
||||
.fs_ops = &dev_random_fs_ops,
|
||||
.type = LINUX_DT_CHR},
|
||||
{.name = "urandom",
|
||||
.fs_ops = &dev_urandom_fs_ops,
|
||||
.type = LINUX_DT_CHR},
|
||||
{.name = "stdin",
|
||||
.fs_ops = &dev_stdin_fs_ops,
|
||||
.type = LINUX_DT_LNK},
|
||||
{.name = "stdout",
|
||||
.fs_ops = &dev_stdout_fs_ops,
|
||||
.type = LINUX_DT_LNK},
|
||||
{.name = "stderr",
|
||||
.fs_ops = &dev_stderr_fs_ops,
|
||||
.type = LINUX_DT_LNK},
|
||||
{.name = "attestation",
|
||||
.fs_ops = &dev_attestation_fs_ops,
|
||||
.type = LINUX_DT_DIR,
|
||||
.dir = &dev_attestation_dir},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -49,11 +49,11 @@ static int dev_random_open(struct shim_handle* hdl, const char* name, int flags)
|
||||
__UNUSED(name);
|
||||
__UNUSED(flags);
|
||||
|
||||
struct shim_dev_ops ops = {.read = &dev_random_read,
|
||||
.write = &dev_random_write,
|
||||
.mode = &dev_random_mode,
|
||||
.stat = &dev_random_stat,
|
||||
.hstat = &dev_random_hstat};
|
||||
struct shim_dev_ops ops = {.read = &dev_random_read,
|
||||
.write = &dev_random_write,
|
||||
.mode = &dev_random_mode,
|
||||
.stat = &dev_random_stat,
|
||||
.hstat = &dev_random_hstat};
|
||||
|
||||
memcpy(&hdl->info.dev.dev_ops, &ops, sizeof(ops));
|
||||
return 0;
|
||||
|
||||
@@ -19,7 +19,7 @@ static int dev_std_stat(const char* name, struct stat* buf) {
|
||||
__UNUSED(name);
|
||||
memset(buf, 0, sizeof(*buf));
|
||||
|
||||
buf->st_mode = FILE_RW_MODE | S_IFLNK;
|
||||
buf->st_mode = FILE_RW_MODE | S_IFLNK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -49,22 +49,22 @@ static int dev_stderr_follow_link(const char* name, struct shim_qstr* link) {
|
||||
}
|
||||
|
||||
struct pseudo_fs_ops dev_stdin_fs_ops = {
|
||||
.open = &dev_std_open,
|
||||
.mode = &dev_std_mode,
|
||||
.stat = &dev_std_stat,
|
||||
.open = &dev_std_open,
|
||||
.mode = &dev_std_mode,
|
||||
.stat = &dev_std_stat,
|
||||
.follow_link = &dev_stdin_follow_link,
|
||||
};
|
||||
|
||||
struct pseudo_fs_ops dev_stdout_fs_ops = {
|
||||
.open = &dev_std_open,
|
||||
.mode = &dev_std_mode,
|
||||
.stat = &dev_std_stat,
|
||||
.open = &dev_std_open,
|
||||
.mode = &dev_std_mode,
|
||||
.stat = &dev_std_stat,
|
||||
.follow_link = &dev_stdout_follow_link,
|
||||
};
|
||||
|
||||
struct pseudo_fs_ops dev_stderr_fs_ops = {
|
||||
.open = &dev_std_open,
|
||||
.mode = &dev_std_mode,
|
||||
.stat = &dev_std_stat,
|
||||
.open = &dev_std_open,
|
||||
.mode = &dev_std_mode,
|
||||
.stat = &dev_std_stat,
|
||||
.follow_link = &dev_stderr_follow_link,
|
||||
};
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
/* Copyright (C) 2019 Intel Corporation */
|
||||
|
||||
/*
|
||||
* fs.c
|
||||
*
|
||||
* This file contains codes for implementation of 'eventfd' filesystem.
|
||||
* This file contains code for implementation of 'eventfd' filesystem.
|
||||
*/
|
||||
|
||||
#include <asm/fcntl.h>
|
||||
@@ -13,10 +11,10 @@
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/stat.h>
|
||||
|
||||
#include <pal.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include "pal.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
|
||||
static ssize_t eventfd_read(struct shim_handle* hdl, void* buf, size_t count) {
|
||||
if (count < sizeof(uint64_t))
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
/* Copyright (C) 2014 Stony Brook University */
|
||||
|
||||
/*
|
||||
* fs.c
|
||||
*
|
||||
* This file contains codes for implementation of 'pipe' filesystem.
|
||||
* This file contains code for implementation of 'pipe' filesystem.
|
||||
*/
|
||||
|
||||
#define __KERNEL__
|
||||
@@ -16,13 +14,13 @@
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/stat.h>
|
||||
|
||||
#include <pal.h>
|
||||
#include <pal_debug.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_thread.h>
|
||||
#include "pal.h"
|
||||
#include "pal_debug.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_thread.h"
|
||||
|
||||
static ssize_t pipe_read(struct shim_handle* hdl, void* buf, size_t count) {
|
||||
if (!hdl->info.pipe.ready_for_ops)
|
||||
|
||||
@@ -24,23 +24,22 @@ extern const struct pseudo_fs_ops fs_cpuinfo;
|
||||
static const struct pseudo_dir proc_root_dir = {
|
||||
.size = 5,
|
||||
.ent = {
|
||||
{ .name = "self",
|
||||
.fs_ops = &fs_thread,
|
||||
.dir = &dir_thread },
|
||||
{ .name_ops = &nm_thread,
|
||||
.fs_ops = &fs_thread,
|
||||
.dir = &dir_thread },
|
||||
{ .name_ops = &nm_ipc_thread,
|
||||
.fs_ops = &fs_ipc_thread,
|
||||
.dir = &dir_ipc_thread },
|
||||
{ .name = "meminfo",
|
||||
.fs_ops = &fs_meminfo,
|
||||
.type = LINUX_DT_REG },
|
||||
{ .name = "cpuinfo",
|
||||
.fs_ops = &fs_cpuinfo,
|
||||
.type = LINUX_DT_REG },
|
||||
}
|
||||
};
|
||||
{.name = "self",
|
||||
.fs_ops = &fs_thread,
|
||||
.dir = &dir_thread},
|
||||
{.name_ops = &nm_thread,
|
||||
.fs_ops = &fs_thread,
|
||||
.dir = &dir_thread},
|
||||
{.name_ops = &nm_ipc_thread,
|
||||
.fs_ops = &fs_ipc_thread,
|
||||
.dir = &dir_ipc_thread},
|
||||
{.name = "meminfo",
|
||||
.fs_ops = &fs_meminfo,
|
||||
.type = LINUX_DT_REG},
|
||||
{.name = "cpuinfo",
|
||||
.fs_ops = &fs_cpuinfo,
|
||||
.type = LINUX_DT_REG},
|
||||
}};
|
||||
|
||||
static const struct pseudo_fs_ops proc_root_fs = {
|
||||
.open = &pseudo_dir_open,
|
||||
|
||||
@@ -18,8 +18,8 @@ static int proc_info_mode(const char* name, mode_t* mode) {
|
||||
static int proc_info_stat(const char* name, struct stat* buf) {
|
||||
__UNUSED(name);
|
||||
memset(buf, 0, sizeof(struct stat));
|
||||
buf->st_dev = 1; /* dummy ID of device containing file */
|
||||
buf->st_ino = 1; /* dummy inode number */
|
||||
buf->st_dev = 1; /* dummy ID of device containing file */
|
||||
buf->st_ino = 1; /* dummy inode number */
|
||||
buf->st_mode = FILE_R_MODE | S_IFREG;
|
||||
return 0;
|
||||
}
|
||||
@@ -126,20 +126,21 @@ static int proc_cpuinfo_open(struct shim_handle* hdl, const char* name, int flag
|
||||
if (flags & (O_WRONLY | O_RDWR))
|
||||
return -EACCES;
|
||||
|
||||
size_t len = 0,
|
||||
max = 128;
|
||||
size_t len = 0;
|
||||
size_t max = 128;
|
||||
char* str = malloc(max);
|
||||
if (!str) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
#define ADD_INFO(fmt, ...) do { \
|
||||
int ret = print_to_str(&str, len, &max, fmt, ##__VA_ARGS__); \
|
||||
if (ret < 0) { \
|
||||
free(str); \
|
||||
return ret; \
|
||||
} \
|
||||
len += ret; \
|
||||
#define ADD_INFO(fmt, ...) \
|
||||
do { \
|
||||
int ret = print_to_str(&str, len, &max, fmt, ##__VA_ARGS__); \
|
||||
if (ret < 0) { \
|
||||
free(str); \
|
||||
return ret; \
|
||||
} \
|
||||
len += ret; \
|
||||
} while (0)
|
||||
|
||||
for (size_t n = 0; n < pal_control.cpu_info.cpu_num; n++) {
|
||||
@@ -155,8 +156,7 @@ static int proc_cpuinfo_open(struct shim_handle* hdl, const char* name, int flag
|
||||
ADD_INFO("cpu cores\t: %lu\n", pal_control.cpu_info.cpu_num);
|
||||
double bogomips = pal_control.cpu_info.cpu_bogomips;
|
||||
// Apparently graphene snprintf cannot into floats.
|
||||
ADD_INFO("bogomips\t: %lu.%02lu\n",
|
||||
(unsigned long)bogomips,
|
||||
ADD_INFO("bogomips\t: %lu.%02lu\n", (unsigned long)bogomips,
|
||||
(unsigned long)(bogomips * 100.0 + 0.5) % 100);
|
||||
ADD_INFO("\n");
|
||||
}
|
||||
|
||||
@@ -7,15 +7,15 @@
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/stat.h>
|
||||
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_ipc.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_utils.h>
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_ipc.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
static int parse_ipc_thread_name(const char* name, IDTYPE* pidptr, const char** next,
|
||||
size_t* next_len, const char** nextnext) {
|
||||
@@ -57,8 +57,8 @@ static int parse_ipc_thread_name(const char* name, IDTYPE* pidptr, const char**
|
||||
|
||||
static int find_ipc_thread_link(const char* name, struct shim_qstr* link,
|
||||
struct shim_dentry** dentptr) {
|
||||
const char *next;
|
||||
const char *nextnext;
|
||||
const char* next;
|
||||
const char* nextnext;
|
||||
size_t next_len;
|
||||
IDTYPE pid;
|
||||
|
||||
@@ -266,7 +266,7 @@ static int proc_list_ipc_thread(const char* name, struct shim_dirent** buf, int
|
||||
// Only one valid name
|
||||
__UNUSED(name);
|
||||
struct pid_status_cache* status = NULL;
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (!create_lock_runtime(&status_lock)) {
|
||||
return -ENOMEM;
|
||||
@@ -375,14 +375,8 @@ const struct pseudo_fs_ops fs_ipc_thread = {
|
||||
const struct pseudo_dir dir_ipc_thread = {
|
||||
.size = 3,
|
||||
.ent = {
|
||||
{ .name = "cwd",
|
||||
.fs_ops = &fs_ipc_thread_link,
|
||||
.type = LINUX_DT_LNK },
|
||||
{ .name = "exe",
|
||||
.fs_ops = &fs_ipc_thread_link,
|
||||
.type = LINUX_DT_LNK },
|
||||
{ .name = "root",
|
||||
.fs_ops = &fs_ipc_thread_link,
|
||||
.type = LINUX_DT_LNK },
|
||||
}
|
||||
{.name = "cwd", .fs_ops = &fs_ipc_thread_link, .type = LINUX_DT_LNK},
|
||||
{.name = "exe", .fs_ops = &fs_ipc_thread_link, .type = LINUX_DT_LNK},
|
||||
{.name = "root", .fs_ops = &fs_ipc_thread_link, .type = LINUX_DT_LNK},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/stat.h>
|
||||
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_utils.h>
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
static int parse_thread_name(const char* name, IDTYPE* pidptr, const char** next, size_t* next_len,
|
||||
const char** nextnext) {
|
||||
@@ -554,13 +554,13 @@ static int proc_thread_maps_open(struct shim_handle* hdl, const char* name, int
|
||||
goto err;
|
||||
}
|
||||
|
||||
data->str = buffer;
|
||||
data->len = offset;
|
||||
data->str = buffer;
|
||||
data->len = offset;
|
||||
hdl->type = TYPE_STR;
|
||||
hdl->flags = flags & ~O_RDONLY;
|
||||
hdl->acc_mode = MAY_READ;
|
||||
hdl->info.str.data = data;
|
||||
ret = 0;
|
||||
ret = 0;
|
||||
|
||||
err:
|
||||
if (ret < 0) {
|
||||
@@ -728,20 +728,9 @@ const struct pseudo_fs_ops fs_thread = {
|
||||
const struct pseudo_dir dir_thread = {
|
||||
.size = 5,
|
||||
.ent = {
|
||||
{ .name = "cwd",
|
||||
.fs_ops = &fs_thread_link,
|
||||
.type = LINUX_DT_LNK },
|
||||
{ .name = "exe",
|
||||
.fs_ops = &fs_thread_link,
|
||||
.type = LINUX_DT_LNK },
|
||||
{ .name = "root",
|
||||
.fs_ops = &fs_thread_link,
|
||||
.type = LINUX_DT_LNK },
|
||||
{ .name = "fd",
|
||||
.fs_ops = &fs_thread_fd,
|
||||
.dir = &dir_fd },
|
||||
{ .name = "maps",
|
||||
.fs_ops = &fs_thread_maps,
|
||||
.type = LINUX_DT_REG },
|
||||
}
|
||||
};
|
||||
{.name = "cwd", .fs_ops = &fs_thread_link, .type = LINUX_DT_LNK},
|
||||
{.name = "exe", .fs_ops = &fs_thread_link, .type = LINUX_DT_LNK},
|
||||
{.name = "root", .fs_ops = &fs_thread_link, .type = LINUX_DT_LNK},
|
||||
{.name = "fd", .fs_ops = &fs_thread_fd, .dir = &dir_fd},
|
||||
{.name = "maps", .fs_ops = &fs_thread_maps, .type = LINUX_DT_REG},
|
||||
}};
|
||||
|
||||
@@ -4,17 +4,15 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* shim_dcache.c
|
||||
*
|
||||
* This file contains codes for maintaining directory cache in library OS.
|
||||
* This file contains code for maintaining directory cache in library OS.
|
||||
*/
|
||||
|
||||
#include <list.h>
|
||||
#include <shim_checkpoint.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_types.h>
|
||||
#include "list.h"
|
||||
#include "shim_checkpoint.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_types.h"
|
||||
|
||||
static struct shim_lock dcache_mgr_lock;
|
||||
|
||||
@@ -25,7 +23,7 @@ static struct shim_lock dcache_mgr_lock;
|
||||
#define DCACHE_MGR_ALLOC 64
|
||||
|
||||
#define OBJ_TYPE struct shim_dentry
|
||||
#include <memmgr.h>
|
||||
#include "memmgr.h"
|
||||
|
||||
struct shim_lock dcache_lock;
|
||||
|
||||
|
||||
@@ -2,21 +2,19 @@
|
||||
/* Copyright (C) 2014 Stony Brook University */
|
||||
|
||||
/*
|
||||
* shim_fs.c
|
||||
*
|
||||
* This file contains codes for creating filesystems in library OS.
|
||||
* This file contains code for creating filesystems in library OS.
|
||||
*/
|
||||
|
||||
#include <linux/fcntl.h>
|
||||
|
||||
#include <list.h>
|
||||
#include <pal.h>
|
||||
#include <pal_debug.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_checkpoint.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_utils.h>
|
||||
#include "list.h"
|
||||
#include "pal.h"
|
||||
#include "pal_debug.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_checkpoint.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
struct shim_fs {
|
||||
char name[8];
|
||||
@@ -60,7 +58,7 @@ static struct shim_lock mount_mgr_lock;
|
||||
#define MOUNT_MGR_ALLOC 64
|
||||
|
||||
#define OBJ_TYPE struct shim_mount
|
||||
#include <memmgr.h>
|
||||
#include "memmgr.h"
|
||||
|
||||
static MEM_MGR mount_mgr = NULL;
|
||||
DEFINE_LISTP(shim_mount);
|
||||
@@ -195,8 +193,8 @@ static int __mount_others(void) {
|
||||
if (nkeys <= 0)
|
||||
goto out;
|
||||
|
||||
const char *key = keybuf;
|
||||
const char *next = NULL;
|
||||
const char* key = keybuf;
|
||||
const char* next = NULL;
|
||||
for (int n = 0; n < nkeys; key = next, n++) {
|
||||
for (next = key; *next; next++)
|
||||
;
|
||||
@@ -408,7 +406,7 @@ int mount_fs(const char* type, const char* uri, const char* mount_point, struct
|
||||
if (parent && last_len > 0) {
|
||||
/* Newly created dentry's relative path will be a concatenation of parent
|
||||
* + last strings (see get_new_dentry), make sure it fits into qstr */
|
||||
if (parent->rel_path.len + 1 + last_len >= STR_SIZE) { /* +1 for '/' */
|
||||
if (parent->rel_path.len + 1 + last_len >= STR_SIZE) { /* +1 for '/' */
|
||||
debug("Relative path exceeds the limit %d\n", STR_SIZE);
|
||||
ret = -ENAMETOOLONG;
|
||||
goto out_with_unlock;
|
||||
@@ -490,12 +488,12 @@ out:
|
||||
*/
|
||||
void get_mount(struct shim_mount* mount) {
|
||||
__UNUSED(mount);
|
||||
//REF_INC(mount->ref_count);
|
||||
// REF_INC(mount->ref_count);
|
||||
}
|
||||
|
||||
void put_mount(struct shim_mount* mount) {
|
||||
__UNUSED(mount);
|
||||
//REF_DEC(mount->ref_count);
|
||||
// REF_DEC(mount->ref_count);
|
||||
}
|
||||
|
||||
int walk_mounts(int (*walk)(struct shim_mount* mount, void* arg), void* arg) {
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
* This file contains functions to generate hash values for FS paths.
|
||||
*/
|
||||
|
||||
#include <shim_fs.h>
|
||||
#include <shim_internal.h>
|
||||
#include "shim_fs.h"
|
||||
#include "shim_internal.h"
|
||||
|
||||
static HASHTYPE __hash(const char* p, size_t len) {
|
||||
HASHTYPE hash = 0;
|
||||
|
||||
@@ -26,8 +26,8 @@ static int pseudo_findent(const char* path, const struct pseudo_ent* root_ent,
|
||||
const struct pseudo_ent** found_ent) {
|
||||
assert(path);
|
||||
|
||||
size_t token_len = 0;
|
||||
const char* token = path;
|
||||
size_t token_len = 0;
|
||||
const char* token = path;
|
||||
const char* next_token = NULL;
|
||||
const struct pseudo_ent* ent = root_ent;
|
||||
|
||||
@@ -102,7 +102,7 @@ static int populate_dirent(const char* path, const struct pseudo_dir* dir, struc
|
||||
dirent_in_buf->ino = rehash_name(dir_hash, ent->name, name_size - 1);
|
||||
dirent_in_buf->type = ent->dir ? LINUX_DT_DIR : ent->type;
|
||||
|
||||
dirent_in_buf = dirent_in_buf->next;
|
||||
dirent_in_buf = dirent_in_buf->next;
|
||||
} else if (ent->name_ops && ent->name_ops->list_name) {
|
||||
/* directory entry has a list of entries calculated at runtime (via list_name) */
|
||||
struct shim_dirent* old_dirent_in_buf = dirent_in_buf;
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
/* Copyright (C) 2017, University of North Carolina at Chapel Hill and Fortanix, Inc. */
|
||||
|
||||
/*
|
||||
* shim_namei.c
|
||||
*
|
||||
* This file contains codes for parsing a FS path and looking up in the
|
||||
* directory cache.
|
||||
* This file contains code for parsing a FS path and looking up in the directory cache.
|
||||
*/
|
||||
|
||||
#include <asm/fcntl.h>
|
||||
@@ -13,30 +10,28 @@
|
||||
#include <linux/stat.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <pal.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_utils.h>
|
||||
#include "pal.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
/* Advances a char pointer (string) past any repeated slashes and returns the result.
|
||||
* Must be a null-terminated string. */
|
||||
static inline const char * eat_slashes (const char * string)
|
||||
{
|
||||
static inline const char* eat_slashes(const char* string) {
|
||||
while (*string == '/')
|
||||
string++;
|
||||
return string;
|
||||
}
|
||||
|
||||
static inline int __lookup_flags (int flags)
|
||||
{
|
||||
static inline int __lookup_flags(int flags) {
|
||||
int retval = LOOKUP_FOLLOW;
|
||||
|
||||
if (flags & O_NOFOLLOW)
|
||||
retval &= ~LOOKUP_FOLLOW;
|
||||
|
||||
if ((flags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
|
||||
if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
||||
retval &= ~LOOKUP_FOLLOW;
|
||||
|
||||
if (flags & O_DIRECTORY)
|
||||
@@ -105,7 +100,6 @@ int __permission(struct shim_dentry* dent, mode_t mask) {
|
||||
|
||||
mode = dent->mode;
|
||||
|
||||
|
||||
if (((mode >> 6) & mask) == mask)
|
||||
return 0;
|
||||
|
||||
@@ -136,11 +130,11 @@ int __permission(struct shim_dentry* dent, mode_t mask) {
|
||||
*
|
||||
* The caller should hold the dcache_lock.
|
||||
*/
|
||||
int lookup_dentry (struct shim_dentry * parent, const char * name, int namelen, struct shim_dentry ** new, struct shim_mount * fs)
|
||||
{
|
||||
int lookup_dentry(struct shim_dentry* parent, const char* name, int namelen,
|
||||
struct shim_dentry** new, struct shim_mount* fs) {
|
||||
assert(locked(&dcache_lock));
|
||||
|
||||
struct shim_dentry * dent = NULL;
|
||||
struct shim_dentry* dent = NULL;
|
||||
int do_fs_lookup = 0;
|
||||
int err = 0;
|
||||
|
||||
@@ -151,7 +145,7 @@ int lookup_dentry (struct shim_dentry * parent, const char * name, int namelen,
|
||||
if (parent) {
|
||||
/* Newly created dentry's relative path will be a concatenation of parent
|
||||
* + name strings (see get_new_dentry), make sure it fits into qstr */
|
||||
if (parent->rel_path.len + 1 + namelen >= STR_SIZE) { /* +1 for '/' */
|
||||
if (parent->rel_path.len + 1 + namelen >= STR_SIZE) { /* +1 for '/' */
|
||||
debug("Relative path exceeds the limit %d\n", STR_SIZE);
|
||||
err = -ENAMETOOLONG;
|
||||
goto out;
|
||||
@@ -187,7 +181,6 @@ int lookup_dentry (struct shim_dentry * parent, const char * name, int namelen,
|
||||
* negative dentries, so they can still be cached */
|
||||
dent->state |= DENTRY_NEGATIVE;
|
||||
} else {
|
||||
|
||||
/* Trying to weed out ESKIPPED */
|
||||
assert(err != -ESKIPPED);
|
||||
goto out;
|
||||
@@ -245,25 +238,24 @@ out:
|
||||
* If the LOOKUP_DIRECTORY flag is set, and the found file isn't a directory,
|
||||
* returns -ENOTDIR.
|
||||
*/
|
||||
int __path_lookupat (struct shim_dentry * start, const char * path, int flags,
|
||||
struct shim_dentry ** dent, int link_depth,
|
||||
struct shim_mount * fs, bool make_ancestor)
|
||||
{
|
||||
int __path_lookupat(struct shim_dentry* start, const char* path, int flags,
|
||||
struct shim_dentry** dent, int link_depth, struct shim_mount* fs,
|
||||
bool make_ancestor) {
|
||||
assert(locked(&dcache_lock));
|
||||
// Basic idea: recursively iterate over path, peeling off one atom at a
|
||||
// time.
|
||||
/* Chia-Che 12/5/2014:
|
||||
* XXX I am not a big fan of recursion. I am giving a pass to this code
|
||||
* for now, but eventually someone (probably me) should rewrite it. */
|
||||
const char * my_path;
|
||||
const char* my_path;
|
||||
int my_pathlen = 0;
|
||||
int err = 0;
|
||||
struct shim_dentry *my_dent = NULL;
|
||||
struct shim_dentry* my_dent = NULL;
|
||||
struct shim_qstr this = QSTR_INIT;
|
||||
bool leaf_case = false; // Leaf call in case of recursion
|
||||
bool no_start = false; // start not passed
|
||||
bool no_fs = false; // fs not passed
|
||||
struct shim_thread * cur_thread = get_cur_thread();
|
||||
struct shim_thread* cur_thread = get_cur_thread();
|
||||
|
||||
if (cur_thread && *path == '/') {
|
||||
/*
|
||||
@@ -376,7 +368,7 @@ int __path_lookupat (struct shim_dentry * start, const char * path, int flags,
|
||||
if (path) {
|
||||
/* symlink name starts with a slash, restart lookup at root */
|
||||
if (*path == '/') {
|
||||
struct shim_dentry * root;
|
||||
struct shim_dentry* root;
|
||||
// not sure how to deal with this case if cur_thread isn't defined
|
||||
assert(cur_thread);
|
||||
|
||||
@@ -406,7 +398,6 @@ int __path_lookupat (struct shim_dentry * start, const char * path, int flags,
|
||||
|
||||
// If we found something, and there is more, recur
|
||||
if (*my_path != '\0') {
|
||||
|
||||
/* If we have more to look up, but got a negative DENTRY,
|
||||
* we need to fail or (unlikely) create an ancestor dentry.*/
|
||||
if (my_dent->state & DENTRY_NEGATIVE) {
|
||||
@@ -423,8 +414,8 @@ int __path_lookupat (struct shim_dentry * start, const char * path, int flags,
|
||||
/* Although this is slight over-kill, let's just always increment the
|
||||
* mount ref count on a recursion, for easier bookkeeping */
|
||||
get_mount(my_dent->fs);
|
||||
err = __path_lookupat (my_dent, my_path, flags, dent, link_depth,
|
||||
my_dent->fs, make_ancestor);
|
||||
err = __path_lookupat(my_dent, my_path, flags, dent, link_depth, my_dent->fs,
|
||||
make_ancestor);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
/* If we aren't returning a live reference to the target dentry, go
|
||||
@@ -475,17 +466,15 @@ out:
|
||||
|
||||
/* Just wraps __path_lookupat, but also acquires and releases the dcache_lock.
|
||||
*/
|
||||
int path_lookupat (struct shim_dentry * start, const char * name, int flags,
|
||||
struct shim_dentry ** dent, struct shim_mount * fs)
|
||||
{
|
||||
int path_lookupat(struct shim_dentry* start, const char* name, int flags, struct shim_dentry** dent,
|
||||
struct shim_mount* fs) {
|
||||
int ret = 0;
|
||||
lock(&dcache_lock);
|
||||
ret = __path_lookupat (start, name, flags, dent, 0, fs, 0);
|
||||
ret = __path_lookupat(start, name, flags, dent, 0, fs, 0);
|
||||
unlock(&dcache_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Open path with given flags, in mode, similar to Unix open.
|
||||
*
|
||||
* The start dentry specifies where to begin the search, and can be null. If
|
||||
@@ -500,14 +489,12 @@ int path_lookupat (struct shim_dentry * start, const char * name, int flags,
|
||||
* The result is stored in dent.
|
||||
*/
|
||||
|
||||
int open_namei (struct shim_handle * hdl, struct shim_dentry * start,
|
||||
const char * path, int flags, int mode,
|
||||
struct shim_dentry ** dent)
|
||||
{
|
||||
int open_namei(struct shim_handle* hdl, struct shim_dentry* start, const char* path, int flags,
|
||||
int mode, struct shim_dentry** dent) {
|
||||
int lookup_flags = __lookup_flags(flags);
|
||||
mode_t acc_mode = ACC_MODE(flags & O_ACCMODE);
|
||||
int err = 0, newly_created = 0;
|
||||
struct shim_dentry *mydent = NULL;
|
||||
struct shim_dentry* mydent = NULL;
|
||||
|
||||
if (*path == '\0') {
|
||||
/* corner case: trying to open with empty filename */
|
||||
@@ -530,7 +517,7 @@ int open_namei (struct shim_handle * hdl, struct shim_dentry * start,
|
||||
// of directories.
|
||||
if (mydent && err == -ENOENT && (flags & O_CREAT)) {
|
||||
// Create the file
|
||||
struct shim_dentry * dir = mydent->parent;
|
||||
struct shim_dentry* dir = mydent->parent;
|
||||
|
||||
if (!dir) {
|
||||
err = -ENOENT;
|
||||
@@ -571,7 +558,7 @@ int open_namei (struct shim_handle * hdl, struct shim_dentry * start,
|
||||
|
||||
// Set err back to zero and fall through
|
||||
err = 0;
|
||||
} else if (err == 0 && ((flags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))) {
|
||||
} else if (err == 0 && ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))) {
|
||||
err = -EEXIST;
|
||||
}
|
||||
|
||||
@@ -608,11 +595,9 @@ out:
|
||||
* the underlying truncate function.
|
||||
*/
|
||||
|
||||
int dentry_open (struct shim_handle * hdl, struct shim_dentry * dent,
|
||||
int flags)
|
||||
{
|
||||
int dentry_open(struct shim_handle* hdl, struct shim_dentry* dent, int flags) {
|
||||
int ret = 0;
|
||||
struct shim_mount * fs = dent->fs;
|
||||
struct shim_mount* fs = dent->fs;
|
||||
|
||||
/* I think missing functionality should be treated as EINVAL, or maybe
|
||||
* ENOSYS?*/
|
||||
@@ -649,8 +634,8 @@ int dentry_open (struct shim_handle * hdl, struct shim_dentry * dent,
|
||||
|
||||
// Let's defer setting the DENTRY_LISTED flag until we need it
|
||||
// Use -1 to indicate that the buf/ptr isn't initialized
|
||||
hdl->dir_info.buf = (void *)-1;
|
||||
hdl->dir_info.ptr = (void *)-1;
|
||||
hdl->dir_info.buf = (void*)-1;
|
||||
hdl->dir_info.ptr = (void*)-1;
|
||||
}
|
||||
|
||||
if (!dentry_get_path_into_qstr(dent, &hdl->path)) {
|
||||
@@ -675,8 +660,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void set_dirent_type (mode_t * type, int d_type)
|
||||
{
|
||||
static inline void set_dirent_type(mode_t* type, int d_type) {
|
||||
switch (d_type) {
|
||||
case LINUX_DT_DIR:
|
||||
*type = S_IFDIR;
|
||||
@@ -716,17 +700,16 @@ static inline void set_dirent_type (mode_t * type, int d_type)
|
||||
* have no consistency semantics, we can apply the principle of laziness and
|
||||
* not do the work until we are sure we really need to.
|
||||
*/
|
||||
int list_directory_dentry (struct shim_dentry *dent) {
|
||||
|
||||
int list_directory_dentry(struct shim_dentry* dent) {
|
||||
int ret = 0;
|
||||
struct shim_mount * fs = dent->fs;
|
||||
struct shim_mount* fs = dent->fs;
|
||||
lock(&dcache_lock);
|
||||
|
||||
/* DEP 8/4/17: Another process could list this directory
|
||||
* while we are waiting on the dcache lock. This is ok,
|
||||
* no need to blow an assert.
|
||||
*/
|
||||
if (dent->state & DENTRY_LISTED){
|
||||
if (dent->state & DENTRY_LISTED) {
|
||||
unlock(&dcache_lock);
|
||||
return 0;
|
||||
}
|
||||
@@ -742,18 +725,17 @@ int list_directory_dentry (struct shim_dentry *dent) {
|
||||
|
||||
assert(dent->state & DENTRY_ISDIRECTORY);
|
||||
|
||||
struct shim_dirent * dirent = NULL;
|
||||
struct shim_dirent* dirent = NULL;
|
||||
|
||||
if ((ret = fs->d_ops->readdir(dent, &dirent)) < 0 || !dirent) {
|
||||
dirent = NULL;
|
||||
goto done_read;
|
||||
}
|
||||
|
||||
struct shim_dirent * d = dirent;
|
||||
for ( ; d ; d = d->next) {
|
||||
struct shim_dentry * child;
|
||||
if ((ret = lookup_dentry(dent, d->name, strlen(d->name),
|
||||
&child, fs)) < 0) {
|
||||
struct shim_dirent* d = dirent;
|
||||
for (; d; d = d->next) {
|
||||
struct shim_dentry* child;
|
||||
if ((ret = lookup_dentry(dent, d->name, strlen(d->name), &child, fs)) < 0) {
|
||||
if (ret != -ENOENT) {
|
||||
/* if the file is recently deleted or inaccessible, ignore it */
|
||||
goto done_read;
|
||||
@@ -765,7 +747,7 @@ int list_directory_dentry (struct shim_dentry *dent) {
|
||||
|
||||
if (!(child->state & DENTRY_VALID)) {
|
||||
set_dirent_type(&child->type, d->type);
|
||||
child->state |= DENTRY_VALID|DENTRY_RECENTLY;
|
||||
child->state |= DENTRY_VALID | DENTRY_RECENTLY;
|
||||
}
|
||||
|
||||
child->ino = d->ino;
|
||||
@@ -789,12 +771,11 @@ done_read:
|
||||
*
|
||||
* Returns 0 on success, <0 on failure.
|
||||
*/
|
||||
int list_directory_handle (struct shim_dentry * dent, struct shim_handle * hdl)
|
||||
{
|
||||
struct shim_dentry ** children = NULL;
|
||||
int list_directory_handle(struct shim_dentry* dent, struct shim_handle* hdl) {
|
||||
struct shim_dentry** children = NULL;
|
||||
|
||||
int nchildren = dent->nchildren, count = 0;
|
||||
struct shim_dentry * child;
|
||||
struct shim_dentry* child;
|
||||
|
||||
assert(hdl->dir_info.buf == (void*)-1);
|
||||
assert(hdl->dir_info.ptr == (void*)-1);
|
||||
@@ -808,7 +789,7 @@ int list_directory_handle (struct shim_dentry * dent, struct shim_handle * hdl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
children = malloc(sizeof(struct shim_dentry *) * (nchildren + 1));
|
||||
children = malloc(sizeof(struct shim_dentry*) * (nchildren + 1));
|
||||
if (!children)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -817,7 +798,7 @@ int list_directory_handle (struct shim_dentry * dent, struct shim_handle * hdl)
|
||||
if (count >= nchildren)
|
||||
break;
|
||||
|
||||
struct shim_dentry * c = child;
|
||||
struct shim_dentry* c = child;
|
||||
|
||||
while (c->state & DENTRY_MOUNTPOINT)
|
||||
c = c->mounted->root;
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
/* Copyright (C) 2014 Stony Brook University */
|
||||
|
||||
/*
|
||||
* fs.c
|
||||
*
|
||||
* This file contains codes for implementation of 'socket' filesystem.
|
||||
* This file contains code for implementation of 'socket' filesystem.
|
||||
*/
|
||||
|
||||
#define __KERNEL__
|
||||
@@ -18,7 +16,6 @@
|
||||
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
|
||||
#include "shim_fs.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_thread.h"
|
||||
@@ -133,7 +130,7 @@ static int socket_checkout(struct shim_handle* hdl) {
|
||||
|
||||
static off_t socket_poll(struct shim_handle* hdl, int poll_type) {
|
||||
struct shim_sock_handle* sock = &hdl->info.sock;
|
||||
off_t ret = 0;
|
||||
off_t ret = 0;
|
||||
|
||||
lock(&hdl->lock);
|
||||
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
/* Copyright (C) 2014 Stony Brook University */
|
||||
|
||||
/*
|
||||
* fs.c
|
||||
*
|
||||
* This file contains codes for implementation of 'str' filesystem.
|
||||
* This file contains code for implementation of 'str' filesystem.
|
||||
*/
|
||||
|
||||
#include <asm/fcntl.h>
|
||||
@@ -13,10 +11,11 @@
|
||||
#include <errno.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/stat.h>
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_internal.h>
|
||||
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_internal.h"
|
||||
|
||||
int str_open(struct shim_handle* hdl, struct shim_dentry* dent, int flags) {
|
||||
struct shim_str_data* data = dent->data;
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
#include <generated-offsets-build.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <shim_internal.h>
|
||||
#include <shim_tcb.h>
|
||||
#include "generated-offsets-build.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_tcb.h"
|
||||
|
||||
/* prototype needed due to -Wmissing-prototypes */
|
||||
void dummy(void);
|
||||
|
||||
void dummy(void)
|
||||
{
|
||||
__attribute__((__used__)) static void dummy(void) {
|
||||
OFFSET_T(SHIM_TCB_OFFSET, PAL_TCB, libos_tcb);
|
||||
OFFSET_T(TCB_REGS, shim_tcb_t, context.regs);
|
||||
OFFSET(SHIM_REGS_RSP, shim_regs, rsp);
|
||||
|
||||
@@ -2,23 +2,21 @@
|
||||
/* Copyright (C) 2014 Stony Brook University */
|
||||
|
||||
/*
|
||||
* shim_ipc.c
|
||||
*
|
||||
* This file contains code to maintain generic bookkeeping of IPC: operations
|
||||
* on shim_ipc_msg (one-way IPC messages), shim_ipc_msg_with_ack (IPC messages
|
||||
* with acknowledgement), shim_ipc_info (IPC ports of process), shim_process.
|
||||
* This file contains code to maintain generic bookkeeping of IPC: operations on shim_ipc_msg
|
||||
* (one-way IPC messages), shim_ipc_msg_with_ack (IPC messages with acknowledgement), shim_ipc_info
|
||||
* (IPC ports of process), shim_process.
|
||||
*/
|
||||
|
||||
#include <list.h>
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_checkpoint.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_ipc.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_unistd.h>
|
||||
#include <shim_utils.h>
|
||||
#include "list.h"
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_checkpoint.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_ipc.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_unistd.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
static struct shim_lock ipc_info_mgr_lock;
|
||||
|
||||
@@ -324,7 +322,7 @@ struct shim_ipc_msg_with_ack* pop_ipc_msg_with_ack(struct shim_ipc_port* port, u
|
||||
}
|
||||
|
||||
int send_ipc_message_with_ack(struct shim_ipc_msg_with_ack* msg, struct shim_ipc_port* port,
|
||||
unsigned long* seq, void* private_data) {
|
||||
unsigned long* seq, void* private_data) {
|
||||
int ret = 0;
|
||||
|
||||
struct shim_thread* thread = get_cur_thread();
|
||||
|
||||
@@ -9,13 +9,14 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_ipc.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_utils.h>
|
||||
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_ipc.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
struct thread_info {
|
||||
IDTYPE vmid;
|
||||
|
||||
@@ -2,21 +2,19 @@
|
||||
/* Copyright (C) 2014 Stony Brook University */
|
||||
|
||||
/*
|
||||
* shim_ipc_helper.c
|
||||
*
|
||||
* This file contains code to create an IPC helper thread inside library OS and maintain bookkeeping
|
||||
* of IPC ports.
|
||||
*/
|
||||
|
||||
#include <list.h>
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_checkpoint.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_ipc.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_utils.h>
|
||||
#include "list.h"
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_checkpoint.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_ipc.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
#define IPC_HELPER_STACK_SIZE (g_pal_alloc_align * 4)
|
||||
|
||||
@@ -106,7 +104,7 @@ static int init_parent_ipc_port(void) {
|
||||
assert(cur_process.parent && cur_process.parent->vmid);
|
||||
|
||||
/* for execve case, my parent is the parent of my parent (current process transparently inherits
|
||||
* the "real" parent through already opened pal_handle on "temporary" parent's
|
||||
* the "real" parent through already opened pal_handle on "temporary" parent's
|
||||
* cur_process.parent) */
|
||||
if (!cur_process.parent->pal_handle) {
|
||||
/* for clone/fork case, parent is connected on parent_process */
|
||||
@@ -474,14 +472,14 @@ int broadcast_ipc(struct shim_ipc_msg* msg, int target_type, struct shim_ipc_por
|
||||
for (size_t i = 0; i < target_ports_cnt; i++) {
|
||||
port = target_ports[i];
|
||||
|
||||
debug("Broadcast to port %p (handle %p) for process %u (type %x, target %x)\n",
|
||||
port, port->pal_handle, port->vmid & 0xFFFF, port->type, target_type);
|
||||
debug("Broadcast to port %p (handle %p) for process %u (type %x, target %x)\n", port,
|
||||
port->pal_handle, port->vmid & 0xFFFF, port->type, target_type);
|
||||
|
||||
msg->dst = port->vmid;
|
||||
ret = send_ipc_message(msg, port);
|
||||
if (ret < 0) {
|
||||
debug("Broadcast to port %p (handle %p) for process %u failed (errno = %d)!\n",
|
||||
port, port->pal_handle, port->vmid & 0xFFFF, ret);
|
||||
debug("Broadcast to port %p (handle %p) for process %u failed (errno = %d)!\n", port,
|
||||
port->pal_handle, port->vmid & 0xFFFF, ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@@ -520,7 +518,7 @@ int send_response_ipc_message(struct shim_ipc_port* port, IDTYPE dest, int ret,
|
||||
ret = (ret == RESPONSE_CALLBACK) ? 0 : ret;
|
||||
|
||||
/* create IPC_MSG_RESP msg to send to dest, with sequence number seq, and in-body retval ret */
|
||||
size_t total_msg_size = get_ipc_msg_size(sizeof(struct shim_ipc_resp));
|
||||
size_t total_msg_size = get_ipc_msg_size(sizeof(struct shim_ipc_resp));
|
||||
struct shim_ipc_msg* resp_msg = __alloca(total_msg_size);
|
||||
init_ipc_msg(resp_msg, IPC_MSG_RESP, total_msg_size, dest);
|
||||
resp_msg->seq = seq;
|
||||
@@ -535,14 +533,14 @@ int send_response_ipc_message(struct shim_ipc_port* port, IDTYPE dest, int ret,
|
||||
static int receive_ipc_message(struct shim_ipc_port* port) {
|
||||
int ret;
|
||||
size_t readahead = IPC_MSG_MINIMAL_SIZE * 2;
|
||||
size_t bufsize = IPC_MSG_MINIMAL_SIZE + readahead;
|
||||
size_t bufsize = IPC_MSG_MINIMAL_SIZE + readahead;
|
||||
|
||||
struct shim_ipc_msg* msg = malloc(bufsize);
|
||||
if (!msg) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
size_t expected_size = IPC_MSG_MINIMAL_SIZE;
|
||||
size_t bytes = 0;
|
||||
size_t expected_size = IPC_MSG_MINIMAL_SIZE;
|
||||
size_t bytes = 0;
|
||||
|
||||
do {
|
||||
while (bytes < expected_size) {
|
||||
@@ -606,7 +604,7 @@ static int receive_ipc_message(struct shim_ipc_port* port) {
|
||||
}
|
||||
}
|
||||
|
||||
bytes -= expected_size; /* one message was received and handled */
|
||||
bytes -= expected_size; /* one message was received and handled */
|
||||
|
||||
if (bytes > 0) {
|
||||
/* we may have started reading the next message, move this message to beginning of msg
|
||||
@@ -699,7 +697,7 @@ noreturn static void shim_ipc_helper(void* dummy) {
|
||||
debug("shim_ipc_helper: allocation of tmp_ports failed\n");
|
||||
goto out_err_unlock;
|
||||
}
|
||||
PAL_HANDLE* tmp_pals = malloc(sizeof(*tmp_pals) * (1 + ports_max_cnt * 2));
|
||||
PAL_HANDLE* tmp_pals = malloc(sizeof(*tmp_pals) * (1 + ports_max_cnt * 2));
|
||||
if (!tmp_pals) {
|
||||
debug("shim_ipc_helper: allocation of tmp_pals failed\n");
|
||||
goto out_err_unlock;
|
||||
@@ -742,7 +740,8 @@ noreturn static void shim_ipc_helper(void* dummy) {
|
||||
unlock(&ipc_helper_lock);
|
||||
|
||||
/* wait on collected ports' PAL handles + install_new_event_pal */
|
||||
PAL_BOL polled = DkStreamsWaitEvents(ports_cnt + 1, pals, pal_events, ret_events, NO_TIMEOUT);
|
||||
PAL_BOL polled = DkStreamsWaitEvents(ports_cnt + 1, pals, pal_events, ret_events,
|
||||
NO_TIMEOUT);
|
||||
|
||||
for (size_t i = 0; polled && i < ports_cnt + 1; i++) {
|
||||
if (ret_events[i]) {
|
||||
@@ -765,7 +764,8 @@ noreturn static void shim_ipc_helper(void* dummy) {
|
||||
if (client) {
|
||||
/* type of client port is the same as original server port but with LISTEN
|
||||
* (for remote client) and without SERVER (doesn't wait for new clients) */
|
||||
IDTYPE client_type = (polled_port->type & ~IPC_PORT_SERVER) | IPC_PORT_LISTEN;
|
||||
IDTYPE client_type =
|
||||
(polled_port->type & ~IPC_PORT_SERVER) | IPC_PORT_LISTEN;
|
||||
add_ipc_port_by_id(polled_port->vmid, client, client_type, NULL, NULL);
|
||||
} else {
|
||||
debug("Port %p (handle %p) was removed during accepting client\n",
|
||||
@@ -781,13 +781,13 @@ noreturn static void shim_ipc_helper(void* dummy) {
|
||||
receive_ipc_message(polled_port);
|
||||
}
|
||||
if (attr.disconnected) {
|
||||
debug("Port %p (handle %p) disconnected\n",
|
||||
polled_port, polled_port->pal_handle);
|
||||
debug("Port %p (handle %p) disconnected\n", polled_port,
|
||||
polled_port->pal_handle);
|
||||
del_ipc_port_fini(polled_port, -ECONNRESET);
|
||||
}
|
||||
} else {
|
||||
debug("Port %p (handle %p) was removed during attr querying\n",
|
||||
polled_port, polled_port->pal_handle);
|
||||
debug("Port %p (handle %p) was removed during attr querying\n", polled_port,
|
||||
polled_port->pal_handle);
|
||||
del_ipc_port_fini(polled_port, -PAL_ERRNO());
|
||||
}
|
||||
}
|
||||
@@ -868,7 +868,7 @@ static int create_ipc_helper(void) {
|
||||
PAL_HANDLE handle = thread_create(shim_ipc_helper_prepare, new);
|
||||
|
||||
if (!handle) {
|
||||
int ret = -PAL_ERRNO(); /* put_thread() may overwrite errno */
|
||||
int ret = -PAL_ERRNO(); /* put_thread() may overwrite errno */
|
||||
ipc_helper_thread = NULL;
|
||||
ipc_helper_state = HELPER_NOTALIVE;
|
||||
put_thread(new);
|
||||
@@ -903,9 +903,8 @@ struct shim_thread* terminate_ipc_helper(void) {
|
||||
* through the host-OS stream, the host OS will close the stream, and the message will never be
|
||||
* seen by child. To prevent such cases, we simply wait for a bit before exiting.
|
||||
*/
|
||||
debug(
|
||||
"Waiting for 0.5s for all in-flight IPC messages to reach their destinations\n");
|
||||
DkThreadDelayExecution(500000); /* in microseconds */
|
||||
debug("Waiting for 0.5s for all in-flight IPC messages to reach their destinations\n");
|
||||
DkThreadDelayExecution(500000); /* in microseconds */
|
||||
|
||||
lock(&ipc_helper_lock);
|
||||
if (ipc_helper_state != HELPER_ALIVE) {
|
||||
|
||||
@@ -71,7 +71,8 @@ int ipc_pid_kill_send(IDTYPE sender, IDTYPE target, enum kill_type type, int sig
|
||||
|
||||
if (type == KILL_ALL) {
|
||||
debug("IPC broadcast: IPC_MSG_PID_KILL(%u, %d, %u, %d)\n", sender, type, target, signum);
|
||||
ret = broadcast_ipc(msg, IPC_PORT_DIRECTCHILD | IPC_PORT_DIRECTPARENT, /*exclude_port=*/NULL);
|
||||
ret = broadcast_ipc(msg, IPC_PORT_DIRECTCHILD | IPC_PORT_DIRECTPARENT,
|
||||
/*exclude_port=*/NULL);
|
||||
} else {
|
||||
debug("IPC send to %u: IPC_MSG_PID_KILL(%u, %d, %u, %d)\n", dest & 0xFFFF, sender, type,
|
||||
target, signum);
|
||||
|
||||
@@ -72,9 +72,9 @@ static LISTP_TYPE(range) range_table[RANGE_HASH_NUM];
|
||||
static LISTP_TYPE(range) owned_ranges;
|
||||
static LISTP_TYPE(range) offered_ranges;
|
||||
|
||||
static int nowned = 0;
|
||||
static int nowned = 0;
|
||||
static int noffered = 0;
|
||||
static int nsubed = 0;
|
||||
static int nsubed = 0;
|
||||
|
||||
DEFINE_LIST(ns_query);
|
||||
struct ns_query {
|
||||
@@ -129,15 +129,15 @@ static int __extend_range_bitmap(IDTYPE expected) {
|
||||
}
|
||||
|
||||
new_map->map_size = size;
|
||||
range_map = new_map;
|
||||
range_map = new_map;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __set_range_bitmap(IDTYPE off, bool unset) {
|
||||
assert(locked(&range_map_lock));
|
||||
|
||||
IDTYPE i = off / BITS;
|
||||
IDTYPE j = off - i * BITS;
|
||||
IDTYPE i = off / BITS;
|
||||
IDTYPE j = off - i * BITS;
|
||||
unsigned char* m = range_map->map + i;
|
||||
unsigned char f = 1U << j;
|
||||
if (unset) {
|
||||
@@ -155,8 +155,8 @@ static int __set_range_bitmap(IDTYPE off, bool unset) {
|
||||
static bool __check_range_bitmap(IDTYPE off) {
|
||||
assert(locked(&range_map_lock));
|
||||
|
||||
IDTYPE i = off / BITS;
|
||||
IDTYPE j = off - i * BITS;
|
||||
IDTYPE i = off / BITS;
|
||||
IDTYPE j = off - i * BITS;
|
||||
unsigned char* m = range_map->map + i;
|
||||
unsigned char f = 1U << j;
|
||||
return (*m) && ((*m) & f);
|
||||
@@ -188,7 +188,7 @@ static int __add_range(struct range* r, IDTYPE off, IDTYPE owner, const char* ur
|
||||
assert(locked(&range_map_lock));
|
||||
|
||||
LISTP_TYPE(range)* head = range_table + RANGE_HASH(off);
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (!range_map || range_map->map_size <= off) {
|
||||
ret = __extend_range_bitmap(off);
|
||||
@@ -272,7 +272,7 @@ static int add_ipc_range(IDTYPE base, IDTYPE owner, const char* uri, LEASETYPE l
|
||||
|
||||
lock(&range_map_lock);
|
||||
r->owner = NULL;
|
||||
ret = __add_range(r, off, owner, uri, lease);
|
||||
ret = __add_range(r, off, owner, uri, lease);
|
||||
if (ret < 0)
|
||||
free(r);
|
||||
unlock(&range_map_lock);
|
||||
@@ -281,16 +281,16 @@ static int add_ipc_range(IDTYPE base, IDTYPE owner, const char* uri, LEASETYPE l
|
||||
|
||||
static void __del_ipc_subrange(struct subrange** ptr) {
|
||||
struct subrange* s = *ptr;
|
||||
*ptr = NULL;
|
||||
*ptr = NULL;
|
||||
put_ipc_info(s->owner);
|
||||
free(s);
|
||||
nsubed--;
|
||||
}
|
||||
|
||||
int add_ipc_subrange(IDTYPE idx, IDTYPE owner, const char* uri, LEASETYPE* lease) {
|
||||
IDTYPE off = (idx - 1) / RANGE_SIZE;
|
||||
IDTYPE base = off * RANGE_SIZE + 1;
|
||||
int err = 0;
|
||||
IDTYPE off = (idx - 1) / RANGE_SIZE;
|
||||
IDTYPE base = off * RANGE_SIZE + 1;
|
||||
int err = 0;
|
||||
struct subrange* s = malloc(sizeof(struct subrange));
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
@@ -375,7 +375,7 @@ static int alloc_ipc_range(IDTYPE owner, const char* uri, IDTYPE* base, LEASETYP
|
||||
}
|
||||
|
||||
LEASETYPE l = get_lease();
|
||||
ret = __add_range(r, i * BITS + j, owner, uri, l);
|
||||
ret = __add_range(r, i * BITS + j, owner, uri, l);
|
||||
if (ret < 0) {
|
||||
if (r->owner)
|
||||
put_ipc_info(r->owner);
|
||||
@@ -404,17 +404,17 @@ static int get_ipc_range(IDTYPE idx, struct ipc_range* range, struct shim_ipc_in
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
IDTYPE base = r->offset * RANGE_SIZE + 1;
|
||||
IDTYPE sz = RANGE_SIZE;
|
||||
LEASETYPE l = r->lease;
|
||||
IDTYPE base = r->offset * RANGE_SIZE + 1;
|
||||
IDTYPE sz = RANGE_SIZE;
|
||||
LEASETYPE l = r->lease;
|
||||
struct shim_ipc_info* p = r->owner;
|
||||
|
||||
if (r->subranges && r->subranges->map[idx - base]) {
|
||||
struct subrange* s = r->subranges->map[idx - base];
|
||||
base = idx;
|
||||
sz = 1;
|
||||
l = s->lease;
|
||||
p = s->owner;
|
||||
base = idx;
|
||||
sz = 1;
|
||||
l = s->lease;
|
||||
p = s->owner;
|
||||
}
|
||||
|
||||
if (!p) {
|
||||
@@ -444,7 +444,7 @@ static int get_ipc_range(IDTYPE idx, struct ipc_range* range, struct shim_ipc_in
|
||||
#if 0 /* unused */
|
||||
static int del_ipc_range(IDTYPE idx) {
|
||||
IDTYPE off = (idx - 1) / RANGE_SIZE;
|
||||
int ret = -ESRCH;
|
||||
int ret = -ESRCH;
|
||||
|
||||
lock(&range_map_lock);
|
||||
|
||||
@@ -494,9 +494,9 @@ failed:
|
||||
}
|
||||
|
||||
int del_ipc_subrange(IDTYPE idx) {
|
||||
IDTYPE off = (idx - 1) / RANGE_SIZE;
|
||||
IDTYPE off = (idx - 1) / RANGE_SIZE;
|
||||
IDTYPE base = off * RANGE_SIZE + 1;
|
||||
int ret = -ESRCH;
|
||||
int ret = -ESRCH;
|
||||
|
||||
lock(&range_map_lock);
|
||||
|
||||
@@ -534,7 +534,7 @@ static int renew_ipc_range(IDTYPE idx, LEASETYPE* lease) {
|
||||
}
|
||||
|
||||
static int renew_ipc_subrange(IDTYPE idx, LEASETYPE* lease) {
|
||||
IDTYPE off = (idx - 1) / RANGE_SIZE;
|
||||
IDTYPE off = (idx - 1) / RANGE_SIZE;
|
||||
IDTYPE base = off * RANGE_SIZE + 1;
|
||||
|
||||
lock(&range_map_lock);
|
||||
@@ -604,7 +604,7 @@ out:
|
||||
}
|
||||
|
||||
void release_ipc_id(IDTYPE idx) {
|
||||
IDTYPE off = (idx - 1) / RANGE_SIZE;
|
||||
IDTYPE off = (idx - 1) / RANGE_SIZE;
|
||||
IDTYPE base = off * RANGE_SIZE + 1;
|
||||
|
||||
lock(&range_map_lock);
|
||||
@@ -622,8 +622,8 @@ void release_ipc_id(IDTYPE idx) {
|
||||
if (idx < base || idx >= base + RANGE_SIZE)
|
||||
goto out;
|
||||
|
||||
IDTYPE i = (idx - base) / BITS;
|
||||
IDTYPE j = (idx - base) - i * BITS;
|
||||
IDTYPE i = (idx - base) / BITS;
|
||||
IDTYPE j = (idx - base) - i * BITS;
|
||||
unsigned char* m = r->used->map + i;
|
||||
unsigned char f = 1U << j;
|
||||
if ((*m) & f) {
|
||||
@@ -877,7 +877,7 @@ int ipc_findns_send(bool block) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
IDTYPE dest = cur_process.parent->vmid;
|
||||
IDTYPE dest = cur_process.parent->vmid;
|
||||
struct shim_ipc_port* port = cur_process.parent->port;
|
||||
get_ipc_port(port);
|
||||
unlock(&cur_process.lock);
|
||||
@@ -893,7 +893,7 @@ int ipc_findns_send(bool block) {
|
||||
goto out_port;
|
||||
}
|
||||
|
||||
size_t total_msg_size = get_ipc_msg_size(0);
|
||||
size_t total_msg_size = get_ipc_msg_size(0);
|
||||
struct shim_ipc_msg* msg = __alloca(total_msg_size);
|
||||
init_ipc_msg(msg, IPC_MSG_FINDNS, total_msg_size, dest);
|
||||
|
||||
@@ -941,7 +941,7 @@ int ipc_tellns_send(struct shim_ipc_port* port, IDTYPE dest, struct shim_ipc_inf
|
||||
init_ipc_msg(msg, IPC_MSG_TELLNS, total_msg_size, dest);
|
||||
|
||||
struct shim_ipc_tellns* msgin = (void*)&msg->msg;
|
||||
msgin->vmid = leader->vmid;
|
||||
msgin->vmid = leader->vmid;
|
||||
memcpy(msgin->uri, qstrgetstr(&leader->uri), leader->uri.len + 1);
|
||||
msg->seq = seq;
|
||||
|
||||
@@ -1034,7 +1034,7 @@ int ipc_lease_callback(struct shim_ipc_msg* msg, struct shim_ipc_port* port) {
|
||||
|
||||
debug("ipc callback from %u: IPC_MSG_LEASE(%s)\n", msg->src, msgin->uri);
|
||||
|
||||
IDTYPE base = 0;
|
||||
IDTYPE base = 0;
|
||||
LEASETYPE lease = 0;
|
||||
|
||||
int ret = alloc_ipc_range(msg->src, msgin->uri, &base, &lease);
|
||||
@@ -1050,7 +1050,7 @@ out:
|
||||
int ipc_offer_send(struct shim_ipc_port* port, IDTYPE dest, IDTYPE base, IDTYPE size,
|
||||
LEASETYPE lease, unsigned long seq) {
|
||||
int ret = 0;
|
||||
size_t total_msg_size = get_ipc_msg_size(sizeof(struct shim_ipc_offer));
|
||||
size_t total_msg_size = get_ipc_msg_size(sizeof(struct shim_ipc_offer));
|
||||
struct shim_ipc_msg* msg = __alloca(total_msg_size);
|
||||
init_ipc_msg(msg, IPC_MSG_OFFER, total_msg_size, dest);
|
||||
|
||||
@@ -1058,7 +1058,7 @@ int ipc_offer_send(struct shim_ipc_port* port, IDTYPE dest, IDTYPE base, IDTYPE
|
||||
msgin->base = base;
|
||||
msgin->size = size;
|
||||
msgin->lease = lease;
|
||||
msg->seq = seq;
|
||||
msg->seq = seq;
|
||||
|
||||
debug("ipc send to %u: IPC_MSG_OFFER(%u, %u, %lu)\n", port->vmid, base, size, lease);
|
||||
ret = send_ipc_message(msg, port);
|
||||
@@ -1068,8 +1068,8 @@ int ipc_offer_send(struct shim_ipc_port* port, IDTYPE dest, IDTYPE base, IDTYPE
|
||||
int ipc_offer_callback(struct shim_ipc_msg* msg, struct shim_ipc_port* port) {
|
||||
struct shim_ipc_offer* msgin = (void*)&msg->msg;
|
||||
|
||||
debug("ipc callback from %u: IPC_MSG_OFFER(%u, %u, %lu)\n", msg->src, msgin->base,
|
||||
msgin->size, msgin->lease);
|
||||
debug("ipc callback from %u: IPC_MSG_OFFER(%u, %u, %lu)\n", msg->src, msgin->base, msgin->size,
|
||||
msgin->lease);
|
||||
|
||||
struct shim_ipc_msg_with_ack* obj = pop_ipc_msg_with_ack(port, msg->seq);
|
||||
|
||||
@@ -1106,7 +1106,7 @@ out:
|
||||
int ipc_renew_send(IDTYPE base, IDTYPE size) {
|
||||
IDTYPE leader;
|
||||
struct shim_ipc_port* port = NULL;
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
if ((ret = connect_ns(&leader, &port)) < 0)
|
||||
goto out;
|
||||
@@ -1116,8 +1116,8 @@ int ipc_renew_send(IDTYPE base, IDTYPE size) {
|
||||
init_ipc_msg(msg, IPC_MSG_RENEW, total_msg_size, leader);
|
||||
|
||||
struct shim_ipc_renew* msgin = (void*)&msg->msg;
|
||||
msgin->base = base;
|
||||
msgin->size = size;
|
||||
msgin->base = base;
|
||||
msgin->size = size;
|
||||
|
||||
debug("ipc send to : IPC_MSG_RENEW(%u, %u)\n", base, size);
|
||||
ret = send_ipc_message(msg, port);
|
||||
@@ -1164,7 +1164,7 @@ out:
|
||||
int ipc_sublease_send(IDTYPE tenant, IDTYPE idx, const char* uri, LEASETYPE* lease) {
|
||||
IDTYPE leader;
|
||||
struct shim_ipc_port* port = NULL;
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
if ((ret = connect_ns(&leader, &port)) < 0)
|
||||
goto out;
|
||||
@@ -1210,7 +1210,7 @@ int ipc_query_send(IDTYPE idx) {
|
||||
struct ipc_range range;
|
||||
IDTYPE leader;
|
||||
struct shim_ipc_port* port = NULL;
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
memset(&range, 0, sizeof(struct ipc_range));
|
||||
|
||||
if (!get_ipc_range(idx, &range, NULL))
|
||||
@@ -1258,13 +1258,13 @@ int ipc_query_callback(struct shim_ipc_msg* msg, struct shim_ipc_port* port) {
|
||||
assert(!qstrempty(&range.uri));
|
||||
|
||||
struct ipc_ns_offered ans;
|
||||
ans.base = range.base;
|
||||
ans.size = range.size;
|
||||
ans.lease = range.lease;
|
||||
ans.owner_offset = 0;
|
||||
size_t ownerdatasz = sizeof(struct ipc_ns_client) + range.uri.len;
|
||||
ans.base = range.base;
|
||||
ans.size = range.size;
|
||||
ans.lease = range.lease;
|
||||
ans.owner_offset = 0;
|
||||
size_t ownerdatasz = sizeof(struct ipc_ns_client) + range.uri.len;
|
||||
struct ipc_ns_client* owner = __alloca(ownerdatasz);
|
||||
owner->vmid = range.owner;
|
||||
owner->vmid = range.owner;
|
||||
assert(!qstrempty(&range.uri));
|
||||
memcpy(owner->uri, qstrgetstr(&range.uri), range.uri.len + 1);
|
||||
|
||||
@@ -1276,7 +1276,7 @@ out:
|
||||
int ipc_queryall_send(void) {
|
||||
IDTYPE leader;
|
||||
struct shim_ipc_port* port = NULL;
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
if ((ret = connect_ns(&leader, &port)) < 0)
|
||||
goto out;
|
||||
@@ -1307,22 +1307,22 @@ int ipc_queryall_callback(struct shim_ipc_msg* msg, struct shim_ipc_port* port)
|
||||
|
||||
size_t maxanswers = nowned + noffered + nsubed;
|
||||
size_t answers_cnt = 0, owners_cnt = 0, i;
|
||||
struct ipc_ns_offered* answers = __alloca(sizeof(struct ipc_ns_offered) * maxanswers);
|
||||
struct ipc_ns_offered* answers = __alloca(sizeof(struct ipc_ns_offered) * maxanswers);
|
||||
struct ipc_ns_client** ownerdata = __alloca(sizeof(struct ipc_ns_client*) * maxanswers);
|
||||
size_t* ownerdatasz = __alloca(sizeof(size_t) * maxanswers);
|
||||
size_t owner_offset = 0;
|
||||
size_t* ownerdatasz = __alloca(sizeof(size_t) * maxanswers);
|
||||
size_t owner_offset = 0;
|
||||
|
||||
retry:
|
||||
LISTP_FOR_EACH_ENTRY(r, list, list) {
|
||||
struct shim_ipc_info* p = r->owner;
|
||||
size_t datasz = sizeof(struct ipc_ns_client) + p->uri.len;
|
||||
struct shim_ipc_info* p = r->owner;
|
||||
size_t datasz = sizeof(struct ipc_ns_client) + p->uri.len;
|
||||
struct ipc_ns_client* owner = __alloca(datasz);
|
||||
|
||||
assert(!qstrempty(&p->uri));
|
||||
owner->vmid = p->vmid;
|
||||
memcpy(owner->uri, qstrgetstr(&p->uri), p->uri.len + 1);
|
||||
|
||||
IDTYPE base = r->offset * RANGE_SIZE + 1;
|
||||
IDTYPE base = r->offset * RANGE_SIZE + 1;
|
||||
answers[answers_cnt].base = base;
|
||||
answers[answers_cnt].size = RANGE_SIZE;
|
||||
answers[answers_cnt].lease = r->lease;
|
||||
@@ -1343,9 +1343,9 @@ retry:
|
||||
continue;
|
||||
|
||||
struct subrange* s = r->subranges->map[i];
|
||||
p = s->owner;
|
||||
datasz = sizeof(struct ipc_ns_client) + p->uri.len;
|
||||
owner = __alloca(datasz);
|
||||
p = s->owner;
|
||||
datasz = sizeof(struct ipc_ns_client) + p->uri.len;
|
||||
owner = __alloca(datasz);
|
||||
|
||||
assert(!qstrempty(&p->uri));
|
||||
owner->vmid = p->vmid;
|
||||
@@ -1381,13 +1381,14 @@ retry:
|
||||
int ipc_answer_send(struct shim_ipc_port* port, IDTYPE dest, size_t answers_cnt,
|
||||
struct ipc_ns_offered* answers, size_t owners_cnt,
|
||||
struct ipc_ns_client** ownerdata, size_t* ownerdatasz, unsigned long seq) {
|
||||
size_t owner_offset = sizeof(struct shim_ipc_answer) + sizeof(struct ipc_ns_offered) * answers_cnt;
|
||||
size_t owner_offset = sizeof(struct shim_ipc_answer)
|
||||
+ sizeof(struct ipc_ns_offered) * answers_cnt;
|
||||
size_t total_ownerdatasz = 0;
|
||||
for (size_t i = 0; i < owners_cnt; i++) {
|
||||
total_ownerdatasz += ownerdatasz[i];
|
||||
}
|
||||
|
||||
size_t total_msg_size = get_ipc_msg_size(owner_offset + total_ownerdatasz);
|
||||
size_t total_msg_size = get_ipc_msg_size(owner_offset + total_ownerdatasz);
|
||||
struct shim_ipc_msg* msg = __alloca(total_msg_size);
|
||||
init_ipc_msg(msg, IPC_MSG_ANSWER, total_msg_size, dest);
|
||||
|
||||
@@ -1416,8 +1417,8 @@ int ipc_answer_callback(struct shim_ipc_msg* msg, struct shim_ipc_port* port) {
|
||||
struct shim_ipc_answer* msgin = (void*)&msg->msg;
|
||||
|
||||
if (msgin->answers_cnt == 1)
|
||||
debug("ipc callback from %u: IPC_MSG_ANSWER([%u, %u])\n", msg->src,
|
||||
msgin->answers[0].base, msgin->answers[0].size);
|
||||
debug("ipc callback from %u: IPC_MSG_ANSWER([%u, %u])\n", msg->src, msgin->answers[0].base,
|
||||
msgin->answers[0].size);
|
||||
else if (msgin->answers_cnt)
|
||||
debug("ipc callback from %u: IPC_MSG_ANSWER([%u, %u], ...)\n", msg->src,
|
||||
msgin->answers[0].base, msgin->answers[0].size);
|
||||
@@ -1452,7 +1453,7 @@ int get_all_pid_status(struct pid_status** status) {
|
||||
ipc_queryall_send();
|
||||
|
||||
size_t statuses_cnt = 0;
|
||||
size_t bufsize = RANGE_SIZE;
|
||||
size_t bufsize = RANGE_SIZE;
|
||||
|
||||
struct pid_status* status_buf = malloc(bufsize);
|
||||
if (!status_buf)
|
||||
@@ -1476,8 +1477,8 @@ retry:
|
||||
#define UNDEF_IDX ((IDTYPE)-1)
|
||||
|
||||
next_range:
|
||||
idx = UNDEF_IDX;
|
||||
off = r->offset;
|
||||
idx = UNDEF_IDX;
|
||||
off = r->offset;
|
||||
base = off * RANGE_SIZE + 1;
|
||||
|
||||
next_sub:
|
||||
@@ -1502,10 +1503,10 @@ retry:
|
||||
}
|
||||
|
||||
if (!p->port) {
|
||||
IDTYPE type = IPC_PORT_OWNER | IPC_PORT_LISTEN;
|
||||
IDTYPE owner = p->vmid;
|
||||
IDTYPE type = IPC_PORT_OWNER | IPC_PORT_LISTEN;
|
||||
IDTYPE owner = p->vmid;
|
||||
struct shim_ipc_port* port = NULL;
|
||||
size_t uri_len = p->uri.len;
|
||||
size_t uri_len = p->uri.len;
|
||||
char uri[uri_len + 1];
|
||||
|
||||
memcpy(&uri, qstrgetstr(&p->uri), uri_len);
|
||||
@@ -1665,4 +1666,3 @@ int sysv_get_key(struct sysv_key* key, bool delete) {
|
||||
unlock(&range_map_lock);
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ int ipc_sysv_findkey_callback(struct shim_ipc_msg* msg, struct shim_ipc_port* po
|
||||
int ipc_sysv_tellkey_send(struct shim_ipc_port* port, IDTYPE dest, struct sysv_key* key, IDTYPE id,
|
||||
unsigned long seq) {
|
||||
bool owned = true;
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (!dest) {
|
||||
if ((ret = sysv_add_key(key, id)) < 0)
|
||||
@@ -98,7 +98,7 @@ int ipc_sysv_tellkey_send(struct shim_ipc_port* port, IDTYPE dest, struct sysv_k
|
||||
msgin->key.key = key->key;
|
||||
msgin->key.type = key->type;
|
||||
msgin->id = id;
|
||||
msg->seq = seq;
|
||||
msg->seq = seq;
|
||||
|
||||
debug("ipc send to %u: IPC_MSG_SYSV_TELLKEY(%lu, %u)\n", dest, key->key, id);
|
||||
|
||||
@@ -147,7 +147,7 @@ out:
|
||||
|
||||
int ipc_sysv_delres_send(struct shim_ipc_port* port, IDTYPE dest, IDTYPE resid,
|
||||
enum sysv_type type) {
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
bool owned = false;
|
||||
|
||||
if (!port) {
|
||||
@@ -198,14 +198,14 @@ int ipc_sysv_delres_callback(struct shim_ipc_msg* msg, struct shim_ipc_port* por
|
||||
SYSV_TYPE_STR(msgin->type));
|
||||
|
||||
bool owned = false;
|
||||
ret = -ENOENT;
|
||||
ret = -ENOENT;
|
||||
switch (msgin->type) {
|
||||
case SYSV_MSGQ: {
|
||||
struct shim_msg_handle* msgq = get_msg_handle_by_id(msgin->resid);
|
||||
if (!msgq)
|
||||
goto out;
|
||||
owned = msgq->owned;
|
||||
ret = del_msg_handle(msgq);
|
||||
ret = del_msg_handle(msgq);
|
||||
break;
|
||||
}
|
||||
case SYSV_SEM: {
|
||||
@@ -213,7 +213,7 @@ int ipc_sysv_delres_callback(struct shim_ipc_msg* msg, struct shim_ipc_port* por
|
||||
if (!sem)
|
||||
goto out;
|
||||
owned = sem->owned;
|
||||
ret = del_sem_handle(sem);
|
||||
ret = del_sem_handle(sem);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -280,7 +280,7 @@ out:
|
||||
|
||||
int ipc_sysv_msgsnd_send(struct shim_ipc_port* port, IDTYPE dest, IDTYPE msgid, long msgtype,
|
||||
const void* buf, size_t size, unsigned long seq) {
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
bool owned = true;
|
||||
|
||||
if (!dest) {
|
||||
@@ -349,7 +349,7 @@ int ipc_sysv_msgsnd_callback(struct shim_ipc_msg* msg, struct shim_ipc_port* por
|
||||
src.port = port;
|
||||
src.vmid = msg->src;
|
||||
src.seq = msg->seq;
|
||||
ret = add_sysv_msg(msgq, msgin->msgtype, size, msgin->msg, &src);
|
||||
ret = add_sysv_msg(msgq, msgin->msgtype, size, msgin->msg, &src);
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -359,7 +359,7 @@ out:
|
||||
int ipc_sysv_msgrcv_send(IDTYPE msgid, long msgtype, int flags, void* buf, size_t size) {
|
||||
IDTYPE owner;
|
||||
struct shim_ipc_port* port = NULL;
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
if ((ret = connect_owner(msgid, &port, &owner)) < 0)
|
||||
goto out;
|
||||
@@ -426,8 +426,8 @@ int ipc_sysv_semop_send(IDTYPE semid, struct sembuf* sops, int nsops, unsigned l
|
||||
unsigned long* seq) {
|
||||
IDTYPE owner;
|
||||
struct shim_ipc_port* port = NULL;
|
||||
int ret = 0;
|
||||
bool waitforreply = false;
|
||||
int ret = 0;
|
||||
bool waitforreply = false;
|
||||
|
||||
for (int i = 0; i < nsops; i++)
|
||||
if (sops[i].sem_op <= 0) {
|
||||
@@ -502,7 +502,7 @@ int ipc_sysv_semop_callback(struct shim_ipc_msg* msg, struct shim_ipc_port* port
|
||||
client.port = port;
|
||||
client.vmid = msg->src;
|
||||
client.seq = msg->seq;
|
||||
ret = submit_sysv_sem(sem, msgin->sops, msgin->nsops, msgin->timeout, &client);
|
||||
ret = submit_sysv_sem(sem, msgin->sops, msgin->nsops, msgin->timeout, &client);
|
||||
put_sem_handle(sem);
|
||||
out:
|
||||
return ret;
|
||||
@@ -511,7 +511,7 @@ out:
|
||||
int ipc_sysv_semctl_send(IDTYPE semid, int semnum, int cmd, void* vals, size_t valsize) {
|
||||
IDTYPE owner;
|
||||
struct shim_ipc_port* port = NULL;
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
if ((ret = connect_owner(semid, &port, &owner)) < 0)
|
||||
goto out;
|
||||
|
||||
@@ -7,23 +7,23 @@
|
||||
* This file contains functions to add asyncronous events triggered by timer.
|
||||
*/
|
||||
|
||||
#include <list.h>
|
||||
#include <pal.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_utils.h>
|
||||
#include "list.h"
|
||||
#include "pal.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
#define IDLE_SLEEP_TIME 1000000
|
||||
#define MAX_IDLE_CYCLES 10000
|
||||
|
||||
DEFINE_LIST(async_event);
|
||||
struct async_event {
|
||||
IDTYPE caller; /* thread installing this event */
|
||||
IDTYPE caller; /* thread installing this event */
|
||||
LIST_TYPE(async_event) list;
|
||||
void (*callback)(IDTYPE caller, void* arg);
|
||||
void* arg;
|
||||
PAL_HANDLE object; /* handle (async IO) to wait on */
|
||||
uint64_t expire_time; /* alarm/timer to wait on */
|
||||
PAL_HANDLE object; /* handle (async IO) to wait on */
|
||||
uint64_t expire_time; /* alarm/timer to wait on */
|
||||
};
|
||||
DEFINE_LISTP(async_event);
|
||||
static LISTP_TYPE(async_event) async_list;
|
||||
@@ -70,11 +70,11 @@ int64_t install_async_event(PAL_HANDLE object, uint64_t time,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
event->callback = callback;
|
||||
event->arg = arg;
|
||||
event->caller = get_cur_tid();
|
||||
event->object = object;
|
||||
event->expire_time = time ? now + time : 0;
|
||||
event->callback = callback;
|
||||
event->arg = arg;
|
||||
event->caller = get_cur_tid();
|
||||
event->object = object;
|
||||
event->expire_time = time ? now + time : 0;
|
||||
|
||||
lock(&async_helper_lock);
|
||||
|
||||
@@ -184,7 +184,7 @@ static void shim_async_helper(void* arg) {
|
||||
PAL_FLG* ret_events = pal_events + 1 + pals_max_cnt;
|
||||
|
||||
PAL_HANDLE install_new_event_pal = event_handle(&install_new_event);
|
||||
pals[0] = install_new_event_pal;
|
||||
pals[0] = install_new_event_pal;
|
||||
pal_events[0] = PAL_WAIT_READ;
|
||||
ret_events[0] = 0;
|
||||
|
||||
@@ -203,7 +203,7 @@ static void shim_async_helper(void* arg) {
|
||||
}
|
||||
|
||||
uint64_t next_expire_time = 0;
|
||||
size_t pals_cnt = 0;
|
||||
size_t pals_cnt = 0;
|
||||
|
||||
struct async_event* tmp;
|
||||
struct async_event* n;
|
||||
@@ -218,7 +218,8 @@ static void shim_async_helper(void* arg) {
|
||||
debug("tmp_pals allocation failed\n");
|
||||
goto out_err_unlock;
|
||||
}
|
||||
PAL_FLG* tmp_pal_events = malloc(sizeof(*tmp_pal_events) * (2 + pals_max_cnt * 4));
|
||||
PAL_FLG* tmp_pal_events =
|
||||
malloc(sizeof(*tmp_pal_events) * (2 + pals_max_cnt * 4));
|
||||
if (!tmp_pal_events) {
|
||||
debug("tmp_pal_events allocation failed\n");
|
||||
goto out_err_unlock;
|
||||
@@ -226,8 +227,10 @@ static void shim_async_helper(void* arg) {
|
||||
PAL_FLG* tmp_ret_events = tmp_pal_events + 1 + pals_max_cnt * 2;
|
||||
|
||||
memcpy(tmp_pals, pals, sizeof(*tmp_pals) * (1 + pals_max_cnt));
|
||||
memcpy(tmp_pal_events, pal_events, sizeof(*tmp_pal_events) * (1 + pals_max_cnt));
|
||||
memcpy(tmp_ret_events, ret_events, sizeof(*tmp_ret_events) * (1 + pals_max_cnt));
|
||||
memcpy(tmp_pal_events, pal_events,
|
||||
sizeof(*tmp_pal_events) * (1 + pals_max_cnt));
|
||||
memcpy(tmp_ret_events, ret_events,
|
||||
sizeof(*tmp_ret_events) * (1 + pals_max_cnt));
|
||||
|
||||
pals_max_cnt *= 2;
|
||||
|
||||
@@ -277,7 +280,8 @@ static void shim_async_helper(void* arg) {
|
||||
unlock(&async_helper_lock);
|
||||
|
||||
/* wait on async IO events + install_new_event + next expiring alarm/timer */
|
||||
PAL_BOL polled = DkStreamsWaitEvents(pals_cnt + 1, pals, pal_events, ret_events, sleep_time);
|
||||
PAL_BOL polled = DkStreamsWaitEvents(pals_cnt + 1, pals, pal_events, ret_events,
|
||||
sleep_time);
|
||||
|
||||
now = DkSystemTimeQuery();
|
||||
if ((int64_t)now < 0) {
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
* This file contains implementation of checkpoint and restore.
|
||||
*/
|
||||
|
||||
#include "shim_checkpoint.h"
|
||||
|
||||
#include <asm/fcntl.h>
|
||||
#include <asm/mman.h>
|
||||
#include <stdarg.h>
|
||||
@@ -15,8 +17,6 @@
|
||||
#include "list.h"
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
|
||||
#include "shim_checkpoint.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
@@ -25,9 +25,9 @@
|
||||
#include "shim_utils.h"
|
||||
#include "shim_vma.h"
|
||||
|
||||
#define CP_MMAP_FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | VMA_INTERNAL)
|
||||
#define CP_MMAP_FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | VMA_INTERNAL)
|
||||
#define CP_MAP_ENTRY_NUM 64
|
||||
#define CP_HASH_SIZE 256
|
||||
#define CP_HASH_SIZE 256
|
||||
|
||||
DEFINE_LIST(cp_map_entry);
|
||||
struct cp_map_entry {
|
||||
@@ -129,10 +129,10 @@ struct shim_cp_map_entry* get_cp_map_entry(void* _map, void* addr, bool create)
|
||||
BEGIN_CP_FUNC(memory) {
|
||||
struct shim_mem_entry* entry = (void*)(base + ADD_CP_OFFSET(sizeof(*entry)));
|
||||
|
||||
entry->addr = obj;
|
||||
entry->size = size;
|
||||
entry->prot = PAL_PROT_READ | PAL_PROT_WRITE;
|
||||
entry->next = store->first_mem_entry;
|
||||
entry->addr = obj;
|
||||
entry->size = size;
|
||||
entry->prot = PAL_PROT_READ | PAL_PROT_WRITE;
|
||||
entry->next = store->first_mem_entry;
|
||||
|
||||
store->first_mem_entry = entry;
|
||||
store->mem_entries_cnt++;
|
||||
@@ -147,10 +147,10 @@ BEGIN_CP_FUNC(palhdl) {
|
||||
size_t off = ADD_CP_OFFSET(sizeof(struct shim_palhdl_entry));
|
||||
struct shim_palhdl_entry* entry = (void*)(base + off);
|
||||
|
||||
entry->handle = (PAL_HANDLE) obj;
|
||||
entry->uri = NULL;
|
||||
entry->handle = (PAL_HANDLE)obj;
|
||||
entry->uri = NULL;
|
||||
entry->phandle = NULL;
|
||||
entry->prev = store->last_palhdl_entry;
|
||||
entry->prev = store->last_palhdl_entry;
|
||||
|
||||
store->last_palhdl_entry = entry;
|
||||
store->palhdl_entries_cnt++;
|
||||
@@ -526,8 +526,7 @@ static void* cp_alloc(void* addr, size_t size) {
|
||||
debug("extending checkpoint store: %p-%p (size = %lu)\n", addr, addr + size, size);
|
||||
|
||||
if (bkeep_mmap_fixed(addr, size, PROT_READ | PROT_WRITE,
|
||||
CP_MMAP_FLAGS | MAP_FIXED_NOREPLACE,
|
||||
NULL, 0, "cpstore") < 0)
|
||||
CP_MMAP_FLAGS | MAP_FIXED_NOREPLACE, NULL, 0, "cpstore") < 0)
|
||||
return NULL;
|
||||
} else {
|
||||
/* FIXME: It is unclear if the below strategy helps */
|
||||
@@ -541,8 +540,8 @@ static void* cp_alloc(void* addr, size_t size) {
|
||||
|
||||
debug("allocating checkpoint store (size = %ld, reserve = %ld)\n", size, reserve_size);
|
||||
|
||||
int ret = bkeep_mmap_any(size + reserve_size, PROT_READ | PROT_WRITE, CP_MMAP_FLAGS,
|
||||
NULL, 0, "cpstore", &addr);
|
||||
int ret = bkeep_mmap_any(size + reserve_size, PROT_READ | PROT_WRITE, CP_MMAP_FLAGS, NULL,
|
||||
0, "cpstore", &addr);
|
||||
if (ret < 0) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -603,8 +602,8 @@ int create_process_and_send_checkpoint(migrate_func_t migrate_func, struct shim_
|
||||
/* allocate a space for dumping the checkpoint data */
|
||||
struct shim_cp_store cpstore;
|
||||
memset(&cpstore, 0, sizeof(cpstore));
|
||||
cpstore.alloc = cp_alloc;
|
||||
cpstore.bound = CP_INIT_VMA_SIZE;
|
||||
cpstore.alloc = cp_alloc;
|
||||
cpstore.bound = CP_INIT_VMA_SIZE;
|
||||
|
||||
while (1) {
|
||||
/* try allocating checkpoint; if allocation fails, try with smaller sizes */
|
||||
@@ -760,7 +759,7 @@ int receive_checkpoint_and_restore(struct checkpoint_hdr* hdr) {
|
||||
|
||||
if (!base) {
|
||||
/* address used by parent process is occupied; allocate checkpoint anywhere */
|
||||
ret = bkeep_mmap_any(ALLOC_ALIGN_UP(hdr->size), PROT_READ|PROT_WRITE, CP_MMAP_FLAGS, NULL,
|
||||
ret = bkeep_mmap_any(ALLOC_ALIGN_UP(hdr->size), PROT_READ | PROT_WRITE, CP_MMAP_FLAGS, NULL,
|
||||
0, "cpstore", &base);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
@@ -801,7 +800,7 @@ int receive_checkpoint_and_restore(struct checkpoint_hdr* hdr) {
|
||||
}
|
||||
|
||||
migrated_memory_start = (void*)mapaddr;
|
||||
migrated_memory_end = (void*)mapaddr + mapsize;
|
||||
migrated_memory_end = (void*)mapaddr + mapsize;
|
||||
|
||||
ret = restore_checkpoint(hdr, (uintptr_t)base);
|
||||
if (ret < 0) {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-3.0-or-later */
|
||||
|
||||
/*
|
||||
* shim_context-x86_64.c
|
||||
*
|
||||
* This file contains code for x86-specific CPU context manipulation.
|
||||
*/
|
||||
|
||||
@@ -66,6 +64,6 @@ void fixup_child_context(struct shim_regs* regs) {
|
||||
*/
|
||||
/* regs->rsp += RED_ZONE_SIZE; */
|
||||
regs->rflags = regs->r11;
|
||||
regs->rip = regs->rcx;
|
||||
regs->rip = regs->rcx;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,20 +2,18 @@
|
||||
/* Copyright (C) 2014 Stony Brook University */
|
||||
|
||||
/*
|
||||
* shim_debug.c
|
||||
*
|
||||
* This file contains codes for registering libraries to GDB.
|
||||
* This file contains code for registering libraries to GDB.
|
||||
*/
|
||||
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_checkpoint.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_ipc.h>
|
||||
#include <shim_tcb.h>
|
||||
#include <shim_vma.h>
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_checkpoint.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_ipc.h"
|
||||
#include "shim_tcb.h"
|
||||
#include "shim_vma.h"
|
||||
|
||||
#ifndef DEBUG
|
||||
|
||||
|
||||
@@ -7,31 +7,29 @@
|
||||
* This file contains entry and exit functions of library OS.
|
||||
*/
|
||||
|
||||
#include <shim_context.h>
|
||||
#include <shim_defs.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_tcb.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_vma.h>
|
||||
#include <shim_checkpoint.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_ipc.h>
|
||||
#include <shim_vdso.h>
|
||||
#include <asm/fcntl.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "hex.h"
|
||||
#include "pal.h"
|
||||
#include "pal_debug.h"
|
||||
#include "pal_error.h"
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/fcntl.h>
|
||||
#include "shim_checkpoint.h"
|
||||
#include "shim_context.h"
|
||||
#include "shim_defs.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_ipc.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_tcb.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_vdso.h"
|
||||
#include "shim_vma.h"
|
||||
|
||||
static_assert(sizeof(shim_tcb_t) <= PAL_LIBOS_TCB_SIZE,
|
||||
"shim_tcb_t does not fit into PAL_TCB; "
|
||||
"please increase PAL_LIBOS_TCB_SIZE");
|
||||
"shim_tcb_t does not fit into PAL_TCB; please increase PAL_LIBOS_TCB_SIZE");
|
||||
|
||||
size_t g_pal_alloc_align;
|
||||
|
||||
@@ -41,12 +39,11 @@ size_t g_pal_alloc_align;
|
||||
|
||||
const unsigned int glibc_version = GLIBC_VERSION;
|
||||
|
||||
static void handle_failure (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
|
||||
{
|
||||
static void handle_failure(PAL_PTR event, PAL_NUM arg, PAL_CONTEXT* context) {
|
||||
__UNUSED(event);
|
||||
__UNUSED(context);
|
||||
if ((arg <= PAL_ERROR_NATIVE_COUNT) || (arg >= PAL_ERROR_CRYPTO_START &&
|
||||
arg <= PAL_ERROR_CRYPTO_END))
|
||||
if ((arg <= PAL_ERROR_NATIVE_COUNT) ||
|
||||
(arg >= PAL_ERROR_CRYPTO_START && arg <= PAL_ERROR_CRYPTO_END))
|
||||
shim_get_tcb()->pal_errno = arg;
|
||||
else
|
||||
shim_get_tcb()->pal_errno = PAL_ERROR_DENIED;
|
||||
@@ -57,48 +54,45 @@ noreturn void __abort(void) {
|
||||
shim_clean_and_exit(-ENOTRECOVERABLE);
|
||||
}
|
||||
|
||||
void warn (const char *format, ...)
|
||||
{
|
||||
void warn(const char* format, ...) {
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
va_start(args, format);
|
||||
__SYS_VPRINTF(format, args);
|
||||
va_end (args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static int pal_errno_to_unix_errno [PAL_ERROR_NATIVE_COUNT + 1] = {
|
||||
/* reserved */ 0,
|
||||
/* PAL_ERROR_NOTIMPLEMENTED */ ENOSYS,
|
||||
/* PAL_ERROR_NOTDEFINED */ ENOSYS,
|
||||
/* PAL_ERROR_NOTSUPPORT */ EACCES,
|
||||
/* PAL_ERROR_INVAL */ EINVAL,
|
||||
/* PAL_ERROR_TOOLONG */ ENAMETOOLONG,
|
||||
/* PAL_ERROR_DENIED */ EACCES,
|
||||
/* PAL_ERROR_BADHANDLE */ EFAULT,
|
||||
/* PAL_ERROR_STREAMEXIST */ EEXIST,
|
||||
/* PAL_ERROR_STREAMNOTEXIST */ ENOENT,
|
||||
/* PAL_ERROR_STREAMISFILE */ ENOTDIR,
|
||||
/* PAL_ERROR_STREAMISDIR */ EISDIR,
|
||||
/* PAL_ERROR_STREAMISDEVICE */ ESPIPE,
|
||||
/* PAL_ERROR_INTERRUPTED */ EINTR,
|
||||
/* PAL_ERROR_OVERFLOW */ EFAULT,
|
||||
/* PAL_ERROR_BADADDR */ EFAULT,
|
||||
/* PAL_ERROR_NOMEM */ ENOMEM,
|
||||
/* PAL_ERROR_NOTKILLABLE */ EACCES,
|
||||
/* PAL_ERROR_INCONSIST */ EFAULT,
|
||||
/* PAL_ERROR_TRYAGAIN */ EAGAIN,
|
||||
/* PAL_ERROR_ENDOFSTREAM */ 0,
|
||||
/* PAL_ERROR_NOTSERVER */ EINVAL,
|
||||
/* PAL_ERROR_NOTCONNECTION */ ENOTCONN,
|
||||
/* PAL_ERROR_CONNFAILED */ ECONNRESET,
|
||||
/* PAL_ERROR_ADDRNOTEXIST */ EADDRNOTAVAIL,
|
||||
/* PAL_ERROR_AFNOSUPPORT */ EAFNOSUPPORT,
|
||||
/* PAL_ERROR_CONNFAILED_PIPE */ EPIPE,
|
||||
};
|
||||
static int pal_errno_to_unix_errno[PAL_ERROR_NATIVE_COUNT + 1] = {
|
||||
[0] = 0,
|
||||
[PAL_ERROR_NOTIMPLEMENTED] = ENOSYS,
|
||||
[PAL_ERROR_NOTDEFINED] = ENOSYS,
|
||||
[PAL_ERROR_NOTSUPPORT] = EACCES,
|
||||
[PAL_ERROR_INVAL] = EINVAL,
|
||||
[PAL_ERROR_TOOLONG] = ENAMETOOLONG,
|
||||
[PAL_ERROR_DENIED] = EACCES,
|
||||
[PAL_ERROR_BADHANDLE] = EFAULT,
|
||||
[PAL_ERROR_STREAMEXIST] = EEXIST,
|
||||
[PAL_ERROR_STREAMNOTEXIST] = ENOENT,
|
||||
[PAL_ERROR_STREAMISFILE] = ENOTDIR,
|
||||
[PAL_ERROR_STREAMISDIR] = EISDIR,
|
||||
[PAL_ERROR_STREAMISDEVICE] = ESPIPE,
|
||||
[PAL_ERROR_INTERRUPTED] = EINTR,
|
||||
[PAL_ERROR_OVERFLOW] = EFAULT,
|
||||
[PAL_ERROR_BADADDR] = EFAULT,
|
||||
[PAL_ERROR_NOMEM] = ENOMEM,
|
||||
[PAL_ERROR_NOTKILLABLE] = EACCES,
|
||||
[PAL_ERROR_INCONSIST] = EFAULT,
|
||||
[PAL_ERROR_TRYAGAIN] = EAGAIN,
|
||||
[PAL_ERROR_ENDOFSTREAM] = 0,
|
||||
[PAL_ERROR_NOTSERVER] = EINVAL,
|
||||
[PAL_ERROR_NOTCONNECTION] = ENOTCONN,
|
||||
[PAL_ERROR_CONNFAILED] = ECONNRESET,
|
||||
[PAL_ERROR_ADDRNOTEXIST] = EADDRNOTAVAIL,
|
||||
[PAL_ERROR_AFNOSUPPORT] = EAFNOSUPPORT,
|
||||
[PAL_ERROR_CONNFAILED_PIPE] = EPIPE,
|
||||
};
|
||||
|
||||
long convert_pal_errno (long err)
|
||||
{
|
||||
return (err >= 0 && err <= PAL_ERROR_NATIVE_COUNT) ?
|
||||
pal_errno_to_unix_errno[err] : EACCES;
|
||||
long convert_pal_errno(long err) {
|
||||
return (err >= 0 && err <= PAL_ERROR_NATIVE_COUNT) ? pal_errno_to_unix_errno[err] : EACCES;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -150,8 +144,8 @@ unsigned long parse_int (const char * str)
|
||||
return num;
|
||||
}
|
||||
|
||||
void * migrated_memory_start;
|
||||
void * migrated_memory_end;
|
||||
void* migrated_memory_start;
|
||||
void* migrated_memory_end;
|
||||
|
||||
const char** migrated_argv __attribute_migratable;
|
||||
const char** migrated_envp __attribute_migratable;
|
||||
@@ -160,7 +154,7 @@ const char** migrated_envp __attribute_migratable;
|
||||
* initialization and is used in __load_interp_object() to search for ELF
|
||||
* program interpreter in specific paths. Once allocated, its memory is
|
||||
* never freed or updated. */
|
||||
char ** library_paths = NULL;
|
||||
char** library_paths = NULL;
|
||||
|
||||
struct shim_lock __master_lock;
|
||||
bool lock_enabled;
|
||||
@@ -216,15 +210,19 @@ static int populate_stack(void* stack, size_t stack_size, const char** argv, con
|
||||
void* stack_low_addr = stack;
|
||||
void* stack_high_addr = stack + stack_size;
|
||||
|
||||
#define ALLOCATE_FROM_HIGH_ADDR(size) \
|
||||
({ if ((stack_high_addr -= (size)) < stack_low_addr) \
|
||||
return -ENOMEM; \
|
||||
stack_high_addr; })
|
||||
#define ALLOCATE_FROM_HIGH_ADDR(size) \
|
||||
({ \
|
||||
if ((stack_high_addr -= (size)) < stack_low_addr) \
|
||||
return -ENOMEM; \
|
||||
stack_high_addr; \
|
||||
})
|
||||
|
||||
#define ALLOCATE_FROM_LOW_ADDR(size) \
|
||||
({ if ((stack_low_addr += (size)) > stack_high_addr) \
|
||||
return -ENOMEM; \
|
||||
stack_low_addr - (size); })
|
||||
#define ALLOCATE_FROM_LOW_ADDR(size) \
|
||||
({ \
|
||||
if ((stack_low_addr += (size)) > stack_high_addr) \
|
||||
return -ENOMEM; \
|
||||
stack_low_addr - (size); \
|
||||
})
|
||||
|
||||
/* create stack layout as follows for ld.so:
|
||||
*
|
||||
@@ -348,8 +346,8 @@ int init_stack(const char** argv, const char** envp, const char*** out_argp,
|
||||
return -ENOMEM;
|
||||
|
||||
/* if there are argv/envp inherited from parent, use them */
|
||||
argv = migrated_argv ? : argv;
|
||||
envp = migrated_envp ? : envp;
|
||||
argv = migrated_argv ?: argv;
|
||||
envp = migrated_envp ?: envp;
|
||||
|
||||
int ret = populate_stack(stack, stack_size, argv, envp, out_argp, out_auxv);
|
||||
if (ret < 0)
|
||||
@@ -362,26 +360,25 @@ int init_stack(const char** argv, const char** envp, const char*** out_argp,
|
||||
}
|
||||
|
||||
static int read_environs(const char** envp) {
|
||||
for (const char ** e = envp ; *e ; e++) {
|
||||
for (const char** e = envp; *e; e++) {
|
||||
if (strstartswith_static(*e, "LD_LIBRARY_PATH=")) {
|
||||
/* populate library_paths with entries from LD_LIBRARY_PATH envvar */
|
||||
const char * s = *e + static_strlen("LD_LIBRARY_PATH=");
|
||||
size_t npaths = 2; // One for the first entry, one for the last
|
||||
// NULL.
|
||||
for (const char * tmp = s ; *tmp ; tmp++)
|
||||
const char* s = *e + static_strlen("LD_LIBRARY_PATH=");
|
||||
size_t npaths = 2; // One for the first entry, one for the last NULL.
|
||||
for (const char* tmp = s; *tmp; tmp++)
|
||||
if (*tmp == ':')
|
||||
npaths++;
|
||||
char** paths = malloc(sizeof(const char *) *
|
||||
npaths);
|
||||
char** paths = malloc(sizeof(const char*) * npaths);
|
||||
if (!paths)
|
||||
return -ENOMEM;
|
||||
|
||||
size_t cnt = 0;
|
||||
while (*s) {
|
||||
const char * next;
|
||||
for (next = s ; *next && *next != ':' ; next++);
|
||||
const char* next;
|
||||
for (next = s; *next && *next != ':'; next++)
|
||||
;
|
||||
size_t len = next - s;
|
||||
char * str = malloc(len + 1);
|
||||
char* str = malloc(len + 1);
|
||||
if (!str) {
|
||||
for (size_t i = 0; i < cnt; i++)
|
||||
free(paths[i]);
|
||||
@@ -405,19 +402,17 @@ static int read_environs(const char** envp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct config_store * root_config = NULL;
|
||||
struct config_store* root_config = NULL;
|
||||
|
||||
static void * __malloc (size_t size)
|
||||
{
|
||||
static void* __malloc(size_t size) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static void __free (void * mem)
|
||||
{
|
||||
static void __free(void* mem) {
|
||||
free(mem);
|
||||
}
|
||||
|
||||
int init_manifest (PAL_HANDLE manifest_handle) {
|
||||
int init_manifest(PAL_HANDLE manifest_handle) {
|
||||
int ret = 0;
|
||||
void* addr = NULL;
|
||||
size_t size = 0, map_size = 0;
|
||||
@@ -458,10 +453,10 @@ int init_manifest (PAL_HANDLE manifest_handle) {
|
||||
|
||||
new_root_config->raw_data = addr;
|
||||
new_root_config->raw_size = size;
|
||||
new_root_config->malloc = __malloc;
|
||||
new_root_config->free = __free;
|
||||
new_root_config->malloc = __malloc;
|
||||
new_root_config->free = __free;
|
||||
|
||||
const char * errstring = "Unexpected error";
|
||||
const char* errstring = "Unexpected error";
|
||||
|
||||
if ((ret = read_config(new_root_config, NULL, &errstring)) < 0) {
|
||||
SYS_PRINTF("Unable to read manifest file: %s\n", errstring);
|
||||
@@ -487,22 +482,22 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define CALL_INIT(func, args ...) func(args)
|
||||
#define CALL_INIT(func, args...) func(args)
|
||||
|
||||
#define RUN_INIT(func, ...) \
|
||||
do { \
|
||||
int _err = CALL_INIT(func, ##__VA_ARGS__); \
|
||||
if (_err < 0) { \
|
||||
SYS_PRINTF("shim_init() in " #func " (%d)\n", _err); \
|
||||
DkProcessExit(_err); \
|
||||
} \
|
||||
#define RUN_INIT(func, ...) \
|
||||
do { \
|
||||
int _err = CALL_INIT(func, ##__VA_ARGS__); \
|
||||
if (_err < 0) { \
|
||||
SYS_PRINTF("shim_init() in " #func " (%d)\n", _err); \
|
||||
DkProcessExit(_err); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
extern PAL_HANDLE thread_start_event;
|
||||
|
||||
noreturn void* shim_init(int argc, void* args) {
|
||||
debug_handle = PAL_CB(debug_stream);
|
||||
cur_process.vmid = (IDTYPE) PAL_CB(process_id);
|
||||
cur_process.vmid = (IDTYPE)PAL_CB(process_id);
|
||||
|
||||
/* create the initial TCB, shim can not be run without a tcb */
|
||||
shim_tcb_init();
|
||||
@@ -598,8 +593,8 @@ noreturn void* shim_init(int argc, void* args) {
|
||||
if (thread_start_event)
|
||||
DkEventSet(thread_start_event);
|
||||
|
||||
shim_tcb_t * cur_tcb = shim_get_tcb();
|
||||
struct shim_thread * cur_thread = (struct shim_thread *) cur_tcb->tp;
|
||||
shim_tcb_t* cur_tcb = shim_get_tcb();
|
||||
struct shim_thread* cur_thread = (struct shim_thread*)cur_tcb->tp;
|
||||
|
||||
if (cur_tcb->context.regs && shim_context_get_sp(&cur_tcb->context)) {
|
||||
vdso_map_migrate();
|
||||
@@ -611,13 +606,9 @@ noreturn void* shim_init(int argc, void* args) {
|
||||
shim_do_exit(0);
|
||||
}
|
||||
|
||||
static int create_unique (int (*mkname) (char *, size_t, void *),
|
||||
int (*create) (const char *, void *),
|
||||
int (*output) (char *, size_t, const void *,
|
||||
struct shim_qstr *),
|
||||
char * name, size_t size, void * id, void * obj,
|
||||
struct shim_qstr * qstr)
|
||||
{
|
||||
static int create_unique(int (*mkname)(char*, size_t, void*), int (*create)(const char*, void*),
|
||||
int (*output)(char*, size_t, const void*, struct shim_qstr*), char* name,
|
||||
size_t size, void* id, void* obj, struct shim_qstr* qstr) {
|
||||
int ret, len;
|
||||
while (1) {
|
||||
len = mkname(name, size, id);
|
||||
@@ -636,7 +627,7 @@ static int create_unique (int (*mkname) (char *, size_t, void *),
|
||||
}
|
||||
|
||||
static int get_256b_random_hex_string(char* buf, size_t size) {
|
||||
char random[32]; /* 256-bit random value, sufficiently crypto secure */
|
||||
char random[32]; /* 256-bit random value, sufficiently crypto secure */
|
||||
|
||||
if (size < sizeof(random) * 2 + 1)
|
||||
return -ENOMEM;
|
||||
@@ -717,8 +708,7 @@ int create_pipe(char* name, char* uri, size_t size, PAL_HANDLE* hdl, struct shim
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int name_path (char * path, size_t size, void * id)
|
||||
{
|
||||
static int name_path(char* path, size_t size, void* id) {
|
||||
unsigned int suffix;
|
||||
int prefix_len = strlen(path);
|
||||
size_t len;
|
||||
@@ -728,13 +718,12 @@ static int name_path (char * path, size_t size, void * id)
|
||||
len = snprintf(path + prefix_len, size - prefix_len, "%08x", suffix);
|
||||
if (len == size)
|
||||
return -ERANGE;
|
||||
*((unsigned int *) id) = suffix;
|
||||
*((unsigned int*)id) = suffix;
|
||||
return prefix_len + len;
|
||||
}
|
||||
|
||||
static int open_dir (const char * path, void * obj)
|
||||
{
|
||||
struct shim_handle * dir = NULL;
|
||||
static int open_dir(const char* path, void* obj) {
|
||||
struct shim_handle* dir = NULL;
|
||||
|
||||
if (obj) {
|
||||
dir = get_new_handle();
|
||||
@@ -742,19 +731,17 @@ static int open_dir (const char * path, void * obj)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int ret = open_namei(dir, NULL, path, O_CREAT|O_EXCL|O_DIRECTORY, 0700,
|
||||
NULL);
|
||||
int ret = open_namei(dir, NULL, path, O_CREAT | O_EXCL | O_DIRECTORY, 0700, NULL);
|
||||
if (ret < 0)
|
||||
return ret = -EEXIST ? 1 : ret;
|
||||
if (obj)
|
||||
*((struct shim_handle **) obj) = dir;
|
||||
*((struct shim_handle**)obj) = dir;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open_file (const char * path, void * obj)
|
||||
{
|
||||
struct shim_handle * file = NULL;
|
||||
static int open_file(const char* path, void* obj) {
|
||||
struct shim_handle* file = NULL;
|
||||
|
||||
if (obj) {
|
||||
file = get_new_handle();
|
||||
@@ -762,31 +749,24 @@ static int open_file (const char * path, void * obj)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int ret = open_namei(file, NULL, path, O_CREAT|O_EXCL|O_RDWR, 0600,
|
||||
NULL);
|
||||
int ret = open_namei(file, NULL, path, O_CREAT | O_EXCL | O_RDWR, 0600, NULL);
|
||||
if (ret < 0)
|
||||
return ret = -EEXIST ? 1 : ret;
|
||||
if (obj)
|
||||
*((struct shim_handle **) obj) = file;
|
||||
*((struct shim_handle**)obj) = file;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open_pal_handle (const char * uri, void * obj)
|
||||
{
|
||||
static int open_pal_handle(const char* uri, void* obj) {
|
||||
PAL_HANDLE hdl;
|
||||
|
||||
if (strstartswith_static(uri, URI_PREFIX_DEV))
|
||||
hdl = DkStreamOpen(uri, 0,
|
||||
PAL_SHARE_OWNER_X|PAL_SHARE_OWNER_W|
|
||||
PAL_SHARE_OWNER_R,
|
||||
PAL_CREATE_TRY|PAL_CREATE_ALWAYS,
|
||||
0);
|
||||
hdl = DkStreamOpen(uri, 0, PAL_SHARE_OWNER_X | PAL_SHARE_OWNER_W | PAL_SHARE_OWNER_R,
|
||||
PAL_CREATE_TRY | PAL_CREATE_ALWAYS, 0);
|
||||
else
|
||||
hdl = DkStreamOpen(uri, PAL_ACCESS_RDWR,
|
||||
PAL_SHARE_OWNER_W|PAL_SHARE_OWNER_R,
|
||||
PAL_CREATE_TRY|PAL_CREATE_ALWAYS,
|
||||
0);
|
||||
hdl = DkStreamOpen(uri, PAL_ACCESS_RDWR, PAL_SHARE_OWNER_W | PAL_SHARE_OWNER_R,
|
||||
PAL_CREATE_TRY | PAL_CREATE_ALWAYS, 0);
|
||||
|
||||
if (!hdl) {
|
||||
if (PAL_NATIVE_ERRNO() == PAL_ERROR_STREAMEXIST)
|
||||
@@ -796,7 +776,7 @@ static int open_pal_handle (const char * uri, void * obj)
|
||||
}
|
||||
|
||||
if (obj) {
|
||||
*((PAL_HANDLE *) obj) = hdl;
|
||||
*((PAL_HANDLE*)obj) = hdl;
|
||||
} else {
|
||||
DkObjectClose(hdl);
|
||||
}
|
||||
@@ -804,9 +784,7 @@ static int open_pal_handle (const char * uri, void * obj)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int output_path (char * path, size_t size, const void * id,
|
||||
struct shim_qstr * qstr)
|
||||
{
|
||||
static int output_path(char* path, size_t size, const void* id, struct shim_qstr* qstr) {
|
||||
size_t len = strlen(path);
|
||||
// API compatibility
|
||||
__UNUSED(size);
|
||||
@@ -817,9 +795,7 @@ static int output_path (char * path, size_t size, const void * id,
|
||||
return len;
|
||||
}
|
||||
|
||||
int create_dir (const char * prefix, char * path, size_t size,
|
||||
struct shim_handle ** hdl)
|
||||
{
|
||||
int create_dir(const char* prefix, char* path, size_t size, struct shim_handle** hdl) {
|
||||
unsigned int suffix;
|
||||
|
||||
if (prefix) {
|
||||
@@ -829,13 +805,10 @@ int create_dir (const char * prefix, char * path, size_t size,
|
||||
memcpy(path, prefix, len + 1);
|
||||
}
|
||||
|
||||
return create_unique(&name_path, &open_dir, &output_path, path, size,
|
||||
&suffix, hdl, NULL);
|
||||
return create_unique(&name_path, &open_dir, &output_path, path, size, &suffix, hdl, NULL);
|
||||
}
|
||||
|
||||
int create_file (const char * prefix, char * path, size_t size,
|
||||
struct shim_handle ** hdl)
|
||||
{
|
||||
int create_file(const char* prefix, char* path, size_t size, struct shim_handle** hdl) {
|
||||
unsigned int suffix;
|
||||
|
||||
if (prefix) {
|
||||
@@ -845,13 +818,10 @@ int create_file (const char * prefix, char * path, size_t size,
|
||||
memcpy(path, prefix, len + 1);
|
||||
}
|
||||
|
||||
return create_unique(&name_path, &open_file, &output_path, path, size,
|
||||
&suffix, hdl, NULL);
|
||||
return create_unique(&name_path, &open_file, &output_path, path, size, &suffix, hdl, NULL);
|
||||
}
|
||||
|
||||
int create_handle (const char * prefix, char * uri, size_t size,
|
||||
PAL_HANDLE * hdl, unsigned int * id)
|
||||
{
|
||||
int create_handle(const char* prefix, char* uri, size_t size, PAL_HANDLE* hdl, unsigned int* id) {
|
||||
unsigned int suffix;
|
||||
|
||||
if (prefix) {
|
||||
@@ -861,8 +831,8 @@ int create_handle (const char * prefix, char * uri, size_t size,
|
||||
memcpy(uri, prefix, len + 1);
|
||||
}
|
||||
|
||||
return create_unique(&name_path, &open_pal_handle, &output_path, uri, size,
|
||||
id ? : &suffix, hdl, NULL);
|
||||
return create_unique(&name_path, &open_pal_handle, &output_path, uri, size, id ?: &suffix, hdl,
|
||||
NULL);
|
||||
}
|
||||
|
||||
noreturn void shim_clean_and_exit(int exit_code) {
|
||||
@@ -877,7 +847,7 @@ noreturn void shim_clean_and_exit(int exit_code) {
|
||||
store_all_msg_persist();
|
||||
del_all_ipc_ports();
|
||||
|
||||
if (shim_stdio && shim_stdio != (PAL_HANDLE) -1)
|
||||
if (shim_stdio && shim_stdio != (PAL_HANDLE)-1)
|
||||
DkObjectClose(shim_stdio);
|
||||
|
||||
shim_stdio = NULL;
|
||||
@@ -892,16 +862,16 @@ noreturn void shim_clean_and_exit(int exit_code) {
|
||||
DkProcessExit(cur_process.exit_code);
|
||||
}
|
||||
|
||||
int message_confirm (const char * message, const char * options)
|
||||
{
|
||||
int message_confirm(const char* message, const char* options) {
|
||||
char answer;
|
||||
int noptions = strlen(options);
|
||||
char * option_str = __alloca(noptions * 2 + 3), * str = option_str;
|
||||
char* option_str = __alloca(noptions * 2 + 3);
|
||||
char* str = option_str;
|
||||
int ret = 0;
|
||||
|
||||
*(str++) = ' ';
|
||||
*(str++) = '[';
|
||||
for (int i = 0 ; i < noptions ; i++) {
|
||||
for (int i = 0; i < noptions; i++) {
|
||||
*(str++) = options[i];
|
||||
*(str++) = '/';
|
||||
}
|
||||
|
||||
@@ -12,12 +12,13 @@
|
||||
*/
|
||||
|
||||
#include <asm/mman.h>
|
||||
#include <pal.h>
|
||||
#include <pal_debug.h>
|
||||
#include <shim_checkpoint.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_utils.h>
|
||||
#include <shim_vma.h>
|
||||
|
||||
#include "pal.h"
|
||||
#include "pal_debug.h"
|
||||
#include "shim_checkpoint.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_utils.h"
|
||||
#include "shim_vma.h"
|
||||
|
||||
static struct shim_lock slab_mgr_lock;
|
||||
|
||||
@@ -28,7 +29,7 @@ static struct shim_lock slab_mgr_lock;
|
||||
#define SLAB_CANARY
|
||||
#define STARTUP_SIZE 16
|
||||
|
||||
#include <slabmgr.h>
|
||||
#include "slabmgr.h"
|
||||
|
||||
static SLAB_MGR slab_mgr = NULL;
|
||||
|
||||
@@ -145,7 +146,6 @@ void* realloc(void* ptr, size_t new_size) {
|
||||
EXTERN_ALIAS(realloc);
|
||||
#endif
|
||||
|
||||
|
||||
// Copies data from `mem` to a newly allocated buffer of a specified size.
|
||||
void* malloc_copy(const void* mem, size_t size) {
|
||||
void* buff = malloc(size);
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
#include <pal.h>
|
||||
#include <shim_internal.h>
|
||||
#include "pal.h"
|
||||
#include "shim_internal.h"
|
||||
|
||||
int object_wait_with_retry(PAL_HANDLE handle) {
|
||||
PAL_BOL ret;
|
||||
do {
|
||||
ret = DkSynchronizationObjectWait(handle, NO_TIMEOUT);
|
||||
} while (!ret &&
|
||||
(PAL_NATIVE_ERRNO() == PAL_ERROR_INTERRUPTED
|
||||
|| PAL_NATIVE_ERRNO() == PAL_ERROR_TRYAGAIN));
|
||||
} while (!ret && (PAL_NATIVE_ERRNO() == PAL_ERROR_INTERRUPTED ||
|
||||
PAL_NATIVE_ERRNO() == PAL_ERROR_TRYAGAIN));
|
||||
|
||||
if (!ret) {
|
||||
debug("waiting on %p resulted in error %s", handle, pal_strerror(PAL_NATIVE_ERRNO()));
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
/* Copyright (C) 2014 Stony Brook University */
|
||||
|
||||
/*
|
||||
* shim_parser.c
|
||||
*
|
||||
* This file contains code for parsing system call arguments for debug purpose.
|
||||
*/
|
||||
|
||||
@@ -24,7 +22,6 @@
|
||||
#include "api.h"
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_tcb.h"
|
||||
|
||||
@@ -13,14 +13,15 @@
|
||||
#endif
|
||||
#include <asm/unistd.h>
|
||||
#include <errno.h>
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_tcb.h>
|
||||
#include <shim_unistd.h>
|
||||
#include <shim_utils.h>
|
||||
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_tcb.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_unistd.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// Mappings from system calls to shim calls
|
||||
@@ -527,8 +528,8 @@ DEFINE_SHIM_SYSCALL(sched_setparam, 2, shim_do_sched_setparam, int, pid_t, pid,
|
||||
DEFINE_SHIM_SYSCALL(sched_getparam, 2, shim_do_sched_getparam, int, pid_t, pid,
|
||||
struct __kernel_sched_param*, param)
|
||||
|
||||
DEFINE_SHIM_SYSCALL(sched_setscheduler, 3, shim_do_sched_setscheduler, int, pid_t, pid,
|
||||
int, policy, struct __kernel_sched_param*, param)
|
||||
DEFINE_SHIM_SYSCALL(sched_setscheduler, 3, shim_do_sched_setscheduler, int, pid_t, pid, int, policy,
|
||||
struct __kernel_sched_param*, param)
|
||||
|
||||
DEFINE_SHIM_SYSCALL(sched_getscheduler, 1, shim_do_sched_getscheduler, int, pid_t, pid)
|
||||
|
||||
@@ -648,15 +649,15 @@ SHIM_SYSCALL_RETURN_ENOSYS(nfsservctl, 3, int, int, cmd, struct nfsctl_arg*, arg
|
||||
this? */
|
||||
|
||||
/* shim_afs_syscall MISSING
|
||||
TODO: afs_syscall is not implemented (kernel always returns -ENOSYS), how should we handle
|
||||
TODO: afs_syscall is not implemented (kernel always returns -ENOSYS), how should we handle
|
||||
this? */
|
||||
|
||||
/* shim_tuxcall MISSING
|
||||
TODO: tuxcall syscall is not implemented (kernel always returns -ENOSYS), how should we handle
|
||||
TODO: tuxcall syscall is not implemented (kernel always returns -ENOSYS), how should we handle
|
||||
this? */
|
||||
|
||||
/* shim_security MISSING
|
||||
TODO: security syscall is not implemented (kernel always returns -ENOSYS), how should we handle
|
||||
TODO: security syscall is not implemented (kernel always returns -ENOSYS), how should we handle
|
||||
this? */
|
||||
|
||||
/* gettid: sys/shim_getpid.c */
|
||||
@@ -812,8 +813,8 @@ DEFINE_SHIM_SYSCALL(mbind, 6, shim_do_mbind, int, void*, start, unsigned long, l
|
||||
SHIM_SYSCALL_RETURN_ENOSYS(set_mempolicy, 3, int, int, mode, unsigned long*, nmask, unsigned long,
|
||||
maxnode)
|
||||
|
||||
SHIM_SYSCALL_RETURN_ENOSYS(get_mempolicy, 5, int, int*, policy, unsigned long*, nmask, unsigned long,
|
||||
maxnode, unsigned long, addr, unsigned long, flags)
|
||||
SHIM_SYSCALL_RETURN_ENOSYS(get_mempolicy, 5, int, int*, policy, unsigned long*, nmask,
|
||||
unsigned long, maxnode, unsigned long, addr, unsigned long, flags)
|
||||
|
||||
SHIM_SYSCALL_RETURN_ENOSYS(mq_open, 4, int, const char*, name, int, oflag, mode_t, mode,
|
||||
struct __kernel_mq_attr*, attr)
|
||||
@@ -968,15 +969,15 @@ SHIM_SYSCALL_RETURN_ENOSYS(timerfd_settime, 4, int, int, ufd, int, flags,
|
||||
SHIM_SYSCALL_RETURN_ENOSYS(timerfd_gettime, 2, int, int, ufd, struct __kernel_itimerspec*, otmr)
|
||||
|
||||
/* accept4: sys/shim_socket.c */
|
||||
DEFINE_SHIM_SYSCALL(accept4, 4, shim_do_accept4, int, int, sockfd, struct sockaddr*, addr,
|
||||
int*, addrlen, int, flags)
|
||||
DEFINE_SHIM_SYSCALL(accept4, 4, shim_do_accept4, int, int, sockfd, struct sockaddr*, addr, int*,
|
||||
addrlen, int, flags)
|
||||
|
||||
SHIM_SYSCALL_RETURN_ENOSYS(signalfd4, 4, int, int, ufd, __sigset_t*, user_mask, size_t, sizemask,
|
||||
int, flags)
|
||||
|
||||
DEFINE_SHIM_SYSCALL(eventfd, 1, shim_do_eventfd, int, unsigned int, count)
|
||||
|
||||
DEFINE_SHIM_SYSCALL (eventfd2, 2, shim_do_eventfd2, int, unsigned int, count, int, flags)
|
||||
DEFINE_SHIM_SYSCALL(eventfd2, 2, shim_do_eventfd2, int, unsigned int, count, int, flags)
|
||||
|
||||
/* epoll_create1: sys/shim_epoll.c */
|
||||
DEFINE_SHIM_SYSCALL(epoll_create1, 1, shim_do_epoll_create1, int, int, flags)
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
* This file contains the system call table used by application libraries.
|
||||
*/
|
||||
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
|
||||
void debug_unsupp(int num) {
|
||||
debug("Unsupported system call %d\n", num);
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
#include <errno.h>
|
||||
#include <linux/fcntl.h>
|
||||
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_thread.h>
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_thread.h"
|
||||
|
||||
int shim_do_access(const char* file, mode_t mode) {
|
||||
if (!file)
|
||||
|
||||
@@ -28,7 +28,7 @@ int shim_do_alarm(unsigned int seconds) {
|
||||
return ret;
|
||||
|
||||
uint64_t usecs_left = (uint64_t)ret;
|
||||
int secs = usecs_left / 1000000ULL;
|
||||
int secs = usecs_left / 1000000ULL;
|
||||
if (usecs_left % 1000000ULL)
|
||||
secs++;
|
||||
return secs;
|
||||
@@ -74,16 +74,18 @@ int shim_do_setitimer(int which, struct __kernel_itimerval* value,
|
||||
uint64_t setup_time = DkSystemTimeQuery();
|
||||
|
||||
uint64_t next_value = value->it_value.tv_sec * (uint64_t)1000000 + value->it_value.tv_usec;
|
||||
uint64_t next_reset = value->it_interval.tv_sec * (uint64_t)1000000 + value->it_interval.tv_usec;
|
||||
uint64_t next_reset = value->it_interval.tv_sec * (uint64_t)1000000
|
||||
+ value->it_interval.tv_usec;
|
||||
|
||||
MASTER_LOCK();
|
||||
|
||||
uint64_t current_timeout =
|
||||
real_itimer.timeout > setup_time ? real_itimer.timeout - setup_time : 0;
|
||||
uint64_t current_timeout = real_itimer.timeout > setup_time
|
||||
? real_itimer.timeout - setup_time
|
||||
: 0;
|
||||
uint64_t current_reset = real_itimer.reset;
|
||||
|
||||
int64_t ret =
|
||||
install_async_event(NULL, next_value, &signal_itimer, (void*)(setup_time + next_value));
|
||||
int64_t ret = install_async_event(NULL, next_value, &signal_itimer,
|
||||
(void*)(setup_time + next_value));
|
||||
|
||||
if (ret < 0) {
|
||||
MASTER_UNLOCK();
|
||||
@@ -117,8 +119,9 @@ int shim_do_getitimer(int which, struct __kernel_itimerval* value) {
|
||||
uint64_t setup_time = DkSystemTimeQuery();
|
||||
|
||||
MASTER_LOCK();
|
||||
uint64_t current_timeout =
|
||||
real_itimer.timeout > setup_time ? real_itimer.timeout - setup_time : 0;
|
||||
uint64_t current_timeout = real_itimer.timeout > setup_time
|
||||
? real_itimer.timeout - setup_time
|
||||
: 0;
|
||||
uint64_t current_reset = real_itimer.reset;
|
||||
MASTER_UNLOCK();
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ static struct {
|
||||
char* brk_end;
|
||||
} brk_region;
|
||||
|
||||
static struct shim_lock brk_lock = { .lock = NULL };
|
||||
static struct shim_lock brk_lock = {.lock = NULL};
|
||||
|
||||
int init_brk_region(void* brk_start, size_t data_segment_size) {
|
||||
if (!create_lock(&brk_lock)) {
|
||||
@@ -71,7 +71,7 @@ int init_brk_region(void* brk_start, size_t data_segment_size) {
|
||||
/* Linux randomizes brk at offset from 0 to 0x2000000 from main executable data section
|
||||
* https://elixir.bootlin.com/linux/v5.6.3/source/arch/x86/kernel/process.c#L914 */
|
||||
offset %= MIN((size_t)0x2000000, (size_t)((char*)PAL_CB(user_address.end) -
|
||||
brk_max_size - (char*)brk_start));
|
||||
brk_max_size - (char*)brk_start));
|
||||
offset = ALLOC_ALIGN_DOWN(offset);
|
||||
}
|
||||
|
||||
@@ -101,9 +101,9 @@ int init_brk_region(void* brk_start, size_t data_segment_size) {
|
||||
}
|
||||
}
|
||||
|
||||
brk_region.brk_start = brk_start;
|
||||
brk_region.brk_current = brk_region.brk_start;
|
||||
brk_region.brk_end = (char*)brk_start + brk_max_size;
|
||||
brk_region.brk_start = brk_start;
|
||||
brk_region.brk_current = brk_region.brk_start;
|
||||
brk_region.brk_end = (char*)brk_start + brk_max_size;
|
||||
brk_region.data_segment_size = data_segment_size;
|
||||
|
||||
set_rlimit_cur(RLIMIT_DATA, brk_max_size + data_segment_size);
|
||||
@@ -124,9 +124,9 @@ void reset_brk(void) {
|
||||
DkVirtualMemoryFree(brk_region.brk_start, allocated_size);
|
||||
bkeep_remove_tmp_vma(tmp_vma);
|
||||
|
||||
brk_region.brk_start = NULL;
|
||||
brk_region.brk_current = NULL;
|
||||
brk_region.brk_end = NULL;
|
||||
brk_region.brk_start = NULL;
|
||||
brk_region.brk_current = NULL;
|
||||
brk_region.brk_end = NULL;
|
||||
brk_region.data_segment_size = 0;
|
||||
unlock(&brk_lock);
|
||||
|
||||
@@ -175,8 +175,7 @@ void* shim_do_brk(void* _brk) {
|
||||
assert(size);
|
||||
|
||||
if (bkeep_mmap_fixed(brk_current, size, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
|
||||
NULL, 0, "heap") < 0) {
|
||||
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, NULL, 0, "heap") < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,25 +8,23 @@
|
||||
* implemented yet.)
|
||||
*/
|
||||
|
||||
#include "shim_context.h"
|
||||
#include "shim_fork.h"
|
||||
#include "shim_types.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_utils.h"
|
||||
#include "shim_checkpoint.h"
|
||||
#include <errno.h>
|
||||
#include <linux/sched.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_checkpoint.h"
|
||||
#include "shim_context.h"
|
||||
#include "shim_fork.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_types.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/mman.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
void __attribute__((weak)) syscall_wrapper_after_syscalldb(void)
|
||||
{
|
||||
void __attribute__((weak)) syscall_wrapper_after_syscalldb(void) {
|
||||
/*
|
||||
* workaround for linking.
|
||||
* syscalldb.S is excluded for libsysdb_debug.so so it fails to link
|
||||
@@ -74,11 +72,10 @@ void __attribute__((weak)) syscall_wrapper_after_syscalldb(void)
|
||||
* 7.In the wrapper function ,we just do the stack switch to user
|
||||
* Provided stack and execute the user Provided function.
|
||||
*/
|
||||
static int clone_implementation_wrapper(struct shim_clone_args * arg)
|
||||
{
|
||||
//The child thread created by PAL is now running on the
|
||||
//PAL allocated stack. We need to switch the stack to use
|
||||
//the user provided stack.
|
||||
static int clone_implementation_wrapper(struct shim_clone_args* arg) {
|
||||
// The child thread created by PAL is now running on the
|
||||
// PAL allocated stack. We need to switch the stack to use
|
||||
// the user provided stack.
|
||||
|
||||
/* We acquired ownership of arg->thread from the caller, hence there is
|
||||
* no need to call get_thread. */
|
||||
@@ -88,7 +85,7 @@ static int clone_implementation_wrapper(struct shim_clone_args * arg)
|
||||
shim_tcb_init();
|
||||
set_cur_thread(my_thread);
|
||||
update_fs_base(arg->fs_base);
|
||||
shim_tcb_t * tcb = my_thread->shim_tcb;
|
||||
shim_tcb_t* tcb = my_thread->shim_tcb;
|
||||
|
||||
/* only now we can call LibOS/PAL functions because they require a set-up TCB;
|
||||
* do not move the below functions before shim_tcb_init/set_cur_thread()! */
|
||||
@@ -109,7 +106,7 @@ static int clone_implementation_wrapper(struct shim_clone_args * arg)
|
||||
my_thread->set_child_tid = NULL;
|
||||
}
|
||||
|
||||
void * stack = arg->stack;
|
||||
void* stack = arg->stack;
|
||||
|
||||
struct shim_vma_info vma_info;
|
||||
if (lookup_vma(ALLOC_ALIGN_DOWN_PTR(stack), &vma_info) < 0) {
|
||||
@@ -130,11 +127,11 @@ static int clone_implementation_wrapper(struct shim_clone_args * arg)
|
||||
|
||||
/***** From here down, we are switching to the user-provided stack ****/
|
||||
|
||||
//user_stack_addr[0] ==> user provided function address
|
||||
//user_stack_addr[1] ==> arguments to user provided function.
|
||||
// user_stack_addr[0] ==> user provided function address
|
||||
// user_stack_addr[1] ==> arguments to user provided function.
|
||||
|
||||
debug("child swapping stack to %p return 0x%lx: %d\n",
|
||||
stack, shim_regs_get_ip(®s), my_thread->tid);
|
||||
debug("child swapping stack to %p return 0x%lx: %d\n", stack, shim_regs_get_ip(®s),
|
||||
my_thread->tid);
|
||||
|
||||
tcb->context.regs = ®s;
|
||||
fixup_child_context(tcb->context.regs);
|
||||
@@ -150,14 +147,13 @@ static int clone_implementation_wrapper(struct shim_clone_args * arg)
|
||||
* long int __arg1 - 16 bytes ( 2 words ) offset into the child stack allocated
|
||||
* by the parent */
|
||||
|
||||
int shim_do_clone (int flags, void * user_stack_addr, int * parent_tidptr,
|
||||
int * child_tidptr, void * tls)
|
||||
{
|
||||
//The Clone Implementation in glibc has setup the child's stack
|
||||
//with the function pointer and the argument to the funciton.
|
||||
struct shim_thread * self = get_cur_thread();
|
||||
int shim_do_clone(int flags, void* user_stack_addr, int* parent_tidptr, int* child_tidptr,
|
||||
void* tls) {
|
||||
// The Clone Implementation in glibc has setup the child's stack
|
||||
// with the function pointer and the argument to the funciton.
|
||||
struct shim_thread* self = get_cur_thread();
|
||||
assert(self);
|
||||
int * set_parent_tid = NULL;
|
||||
int* set_parent_tid = NULL;
|
||||
int ret = 0;
|
||||
|
||||
/* special case of vfork: call shim_do_vfork() */
|
||||
@@ -192,7 +188,7 @@ int shim_do_clone (int flags, void * user_stack_addr, int * parent_tidptr,
|
||||
"Additional parameters are ignored:", user_stack_addr);
|
||||
if (flags & CLONE_PARENT_SETTID)
|
||||
debug(" parent_tidptr = %p", parent_tidptr);
|
||||
if (flags & (CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID))
|
||||
if (flags & (CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID))
|
||||
debug(" child_tidptr = %p", child_tidptr);
|
||||
if (flags & CLONE_SETTLS)
|
||||
debug(" tls = %p", tls);
|
||||
@@ -281,7 +277,7 @@ int shim_do_clone (int flags, void * user_stack_addr, int * parent_tidptr,
|
||||
|
||||
disable_preempt(NULL);
|
||||
|
||||
struct shim_thread * thread = get_new_thread(0);
|
||||
struct shim_thread* thread = get_new_thread(0);
|
||||
if (!thread) {
|
||||
ret = -ENOMEM;
|
||||
goto failed;
|
||||
@@ -312,14 +308,14 @@ int shim_do_clone (int flags, void * user_stack_addr, int * parent_tidptr,
|
||||
if (!(flags & CLONE_THREAD))
|
||||
thread->tgid = thread->tid;
|
||||
|
||||
struct shim_handle_map * handle_map = get_cur_handle_map(self);
|
||||
struct shim_handle_map* handle_map = get_cur_handle_map(self);
|
||||
|
||||
if (flags & CLONE_FILES) {
|
||||
set_handle_map(thread, handle_map);
|
||||
} else {
|
||||
/* if CLONE_FILES is not given, the new thread should receive
|
||||
a copy of current descriptor table */
|
||||
struct shim_handle_map * new_map = NULL;
|
||||
struct shim_handle_map* new_map = NULL;
|
||||
|
||||
dup_handle_map(&new_map, handle_map);
|
||||
set_handle_map(thread, new_map);
|
||||
@@ -327,7 +323,7 @@ int shim_do_clone (int flags, void * user_stack_addr, int * parent_tidptr,
|
||||
}
|
||||
|
||||
if (!(flags & CLONE_VM)) {
|
||||
void * parent_stack = NULL;
|
||||
void* parent_stack = NULL;
|
||||
|
||||
if (!fs_base) {
|
||||
fs_base = self->shim_tcb->context.fs_base;
|
||||
@@ -355,7 +351,7 @@ int shim_do_clone (int flags, void * user_stack_addr, int * parent_tidptr,
|
||||
}
|
||||
|
||||
thread->is_alive = true;
|
||||
thread->in_vm = false;
|
||||
thread->in_vm = false;
|
||||
add_thread(thread);
|
||||
set_as_child(self, thread);
|
||||
|
||||
@@ -403,10 +399,10 @@ int shim_do_clone (int flags, void * user_stack_addr, int * parent_tidptr,
|
||||
/* Increasing refcount due to copy below. Passing ownership of the new copy
|
||||
* of this pointer to the new thread (receiver of new_args). */
|
||||
get_thread(thread);
|
||||
new_args.thread = thread;
|
||||
new_args.parent = self;
|
||||
new_args.stack = user_stack_addr;
|
||||
new_args.fs_base = fs_base;
|
||||
new_args.thread = thread;
|
||||
new_args.parent = self;
|
||||
new_args.stack = user_stack_addr;
|
||||
new_args.fs_base = fs_base;
|
||||
|
||||
// Invoke DkThreadCreate to spawn off a child process using the actual
|
||||
// "clone" system call. DkThreadCreate allocates a stack for the child
|
||||
@@ -414,8 +410,7 @@ int shim_do_clone (int flags, void * user_stack_addr, int * parent_tidptr,
|
||||
// child to run on the Parent allocated stack , so once the DkThreadCreate
|
||||
// returns .The parent comes back here - however, the child is Happily
|
||||
// running the function we gave to DkThreadCreate.
|
||||
PAL_HANDLE pal_handle = thread_create(clone_implementation_wrapper,
|
||||
&new_args);
|
||||
PAL_HANDLE pal_handle = thread_create(clone_implementation_wrapper, &new_args);
|
||||
if (!pal_handle) {
|
||||
ret = -PAL_ERRNO();
|
||||
put_thread(new_args.thread);
|
||||
|
||||
@@ -8,14 +8,15 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_utils.h>
|
||||
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
int shim_do_dup(unsigned int fd) {
|
||||
struct shim_handle_map* handle_map = get_cur_handle_map(NULL);
|
||||
|
||||
@@ -10,14 +10,15 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <linux/eventpoll.h>
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_checkpoint.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_thread.h>
|
||||
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_checkpoint.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_thread.h"
|
||||
|
||||
/* Avoid duplicated definitions */
|
||||
#ifndef EPOLLIN
|
||||
@@ -47,8 +48,8 @@ int shim_do_epoll_create1(int flags) {
|
||||
|
||||
hdl->type = TYPE_EPOLL;
|
||||
set_handle_fs(hdl, &epoll_builtin_fs);
|
||||
epoll->pal_cnt = 0;
|
||||
epoll->waiter_cnt = 0;
|
||||
epoll->pal_cnt = 0;
|
||||
epoll->waiter_cnt = 0;
|
||||
create_event(&epoll->event);
|
||||
INIT_LISTP(&epoll->fds);
|
||||
|
||||
@@ -120,7 +121,7 @@ void delete_from_epoll_handles(struct shim_handle* handle) {
|
||||
|
||||
int shim_do_epoll_ctl(int epfd, int op, int fd, struct __kernel_epoll_event* event) {
|
||||
struct shim_thread* cur = get_cur_thread();
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (epfd == fd)
|
||||
return -EINVAL;
|
||||
@@ -176,7 +177,6 @@ int shim_do_epoll_ctl(int epfd, int op, int fd, struct __kernel_epoll_event* eve
|
||||
ret = -ENOMEM;
|
||||
put_handle(hdl);
|
||||
goto out;
|
||||
|
||||
}
|
||||
|
||||
debug("add fd %d (handle %p) to epoll handle %p\n", fd, hdl, epoll);
|
||||
@@ -309,9 +309,13 @@ int shim_do_epoll_wait(int epfd, struct __kernel_epoll_event* events, int maxeve
|
||||
continue;
|
||||
|
||||
pal_handles[pal_cnt] = epoll_item->handle->pal_handle;
|
||||
pal_events[pal_cnt] = (epoll_item->events & (EPOLLIN | EPOLLRDNORM)) ? PAL_WAIT_READ : 0;
|
||||
pal_events[pal_cnt] |= (epoll_item->events & (EPOLLOUT | EPOLLWRNORM)) ? PAL_WAIT_WRITE : 0;
|
||||
ret_events[pal_cnt] = 0;
|
||||
pal_events[pal_cnt] = (epoll_item->events & (EPOLLIN | EPOLLRDNORM))
|
||||
? PAL_WAIT_READ
|
||||
: 0;
|
||||
pal_events[pal_cnt] |= (epoll_item->events & (EPOLLOUT | EPOLLWRNORM))
|
||||
? PAL_WAIT_WRITE
|
||||
: 0;
|
||||
ret_events[pal_cnt] = 0;
|
||||
pal_cnt++;
|
||||
}
|
||||
|
||||
@@ -321,11 +325,12 @@ int shim_do_epoll_wait(int epfd, struct __kernel_epoll_event* events, int maxeve
|
||||
pal_events[pal_cnt] = PAL_WAIT_READ;
|
||||
ret_events[pal_cnt] = 0;
|
||||
|
||||
epoll->waiter_cnt++; /* mark epoll as being waited on (so epoll-update signal is sent) */
|
||||
epoll->waiter_cnt++; /* mark epoll as being waited on (so epoll-update signal is sent) */
|
||||
unlock(&epoll_hdl->lock);
|
||||
|
||||
/* TODO: Timeout must be updated in case of retries; otherwise, we may wait for too long */
|
||||
PAL_BOL polled = DkStreamsWaitEvents(pal_cnt + 1, pal_handles, pal_events, ret_events, timeout_ms * 1000);
|
||||
PAL_BOL polled = DkStreamsWaitEvents(pal_cnt + 1, pal_handles, pal_events, ret_events,
|
||||
timeout_ms * 1000);
|
||||
|
||||
lock(&epoll_hdl->lock);
|
||||
epoll->waiter_cnt--;
|
||||
@@ -454,12 +459,12 @@ BEGIN_CP_FUNC(epoll_item) {
|
||||
|
||||
struct shim_epoll_item* new_epoll_item = (struct shim_epoll_item*)(base + off);
|
||||
|
||||
new_epoll_item->fd = epoll_item->fd;
|
||||
new_epoll_item->events = epoll_item->events;
|
||||
new_epoll_item->data = epoll_item->data;
|
||||
new_epoll_item->revents = epoll_item->revents;
|
||||
new_epoll_item->connected = epoll_item->connected;
|
||||
new_epoll_item->epoll = NULL; // To be filled by epoll handle RS_FUNC
|
||||
new_epoll_item->fd = epoll_item->fd;
|
||||
new_epoll_item->events = epoll_item->events;
|
||||
new_epoll_item->data = epoll_item->data;
|
||||
new_epoll_item->revents = epoll_item->revents;
|
||||
new_epoll_item->connected = epoll_item->connected;
|
||||
new_epoll_item->epoll = NULL; // To be filled by epoll handle RS_FUNC
|
||||
|
||||
LISTP_ADD(new_epoll_item, new_list, list);
|
||||
|
||||
@@ -484,8 +489,9 @@ BEGIN_RS_FUNC(epoll_item) {
|
||||
CP_REBASE(epoll_item->back);
|
||||
CP_REBASE(epoll_item->list);
|
||||
|
||||
DEBUG_RS("fd=%d,path=%s,type=%s,uri=%s", epoll_item->fd, qstrgetstr(&epoll_item->handle->path),
|
||||
epoll_item->handle->fs_type, qstrgetstr(&epoll_item->handle->uri));
|
||||
DEBUG_RS("fd=%d,path=%s,type=%s,uri=%s", epoll_item->fd,
|
||||
qstrgetstr(&epoll_item->handle->path), epoll_item->handle->fs_type,
|
||||
qstrgetstr(&epoll_item->handle->uri));
|
||||
}
|
||||
}
|
||||
END_RS_FUNC(epoll_item)
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
#include <asm/fcntl.h>
|
||||
#include <sys/eventfd.h>
|
||||
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_utils.h>
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
static int create_eventfd(PAL_HANDLE* efd, unsigned count, int flags) {
|
||||
if (!root_config) {
|
||||
|
||||
@@ -12,13 +12,14 @@
|
||||
#include <sys/mman.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_ipc.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_thread.h>
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_checkpoint.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_ipc.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_thread.h"
|
||||
|
||||
/* returns 0 if normalized URIs are the same; assumes file URIs */
|
||||
static int normalize_and_cmp_uris(const char* uri1, const char* uri2) {
|
||||
@@ -156,8 +157,6 @@ static int shim_do_execve_rtld(struct shim_handle* hdl, const char** argv, const
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <shim_checkpoint.h>
|
||||
|
||||
static BEGIN_MIGRATION_DEF(execve, struct shim_thread* thread, struct shim_process* proc,
|
||||
const char** argv, const char** envp) {
|
||||
DEFINE_MIGRATE(process, proc, sizeof(struct shim_process));
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_ipc.h"
|
||||
@@ -41,11 +40,11 @@ int thread_destroy(struct shim_thread* thread, bool send_ipc) {
|
||||
|
||||
int exit_code = thread->exit_code;
|
||||
|
||||
struct shim_handle_map * handle_map = thread->handle_map;
|
||||
struct shim_handle * exec = thread->exec;
|
||||
struct shim_thread * parent = thread->parent;
|
||||
struct shim_handle_map* handle_map = thread->handle_map;
|
||||
struct shim_handle* exec = thread->exec;
|
||||
struct shim_thread* parent = thread->parent;
|
||||
thread->handle_map = NULL;
|
||||
thread->exec = NULL;
|
||||
thread->exec = NULL;
|
||||
|
||||
if (parent) {
|
||||
assert(parent != thread);
|
||||
@@ -58,14 +57,13 @@ int thread_destroy(struct shim_thread* thread, bool send_ipc) {
|
||||
unlock(&parent->lock);
|
||||
|
||||
if (!thread->in_vm) {
|
||||
debug("deliver SIGCHLD (thread = %d, exitval = %d)\n",
|
||||
thread->tid, exit_code);
|
||||
debug("deliver SIGCHLD (thread = %d, exitval = %d)\n", thread->tid, exit_code);
|
||||
|
||||
siginfo_t info;
|
||||
memset(&info, 0, sizeof(siginfo_t));
|
||||
info.si_signo = SIGCHLD;
|
||||
info.si_pid = thread->tid;
|
||||
info.si_uid = thread->uid;
|
||||
info.si_signo = SIGCHLD;
|
||||
info.si_pid = thread->tid;
|
||||
info.si_uid = thread->uid;
|
||||
info.si_status = (exit_code & 0xff) << 8;
|
||||
|
||||
if (append_signal(parent, &info) >= 0) {
|
||||
|
||||
@@ -9,14 +9,15 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_utils.h>
|
||||
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
#define FCNTL_SETFL_MASK (O_APPEND | O_NONBLOCK)
|
||||
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/stat.h>
|
||||
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_utils.h>
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
/* The kernel would look up the parent directory, and remove the child from the inode. But we are
|
||||
* working with the PAL, so we open the file, truncate and close it. */
|
||||
@@ -323,8 +323,8 @@ int shim_do_fchown(int fd, uid_t uid, gid_t gid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAP_SIZE (g_pal_alloc_align * 256) /* mmap/memcpy in 1MB chunks for sendfile() */
|
||||
#define BUF_SIZE 2048 /* read/write in 2KB chunks for sendfile() */
|
||||
#define MAP_SIZE (g_pal_alloc_align * 256) /* mmap/memcpy in 1MB chunks for sendfile() */
|
||||
#define BUF_SIZE 2048 /* read/write in 2KB chunks for sendfile() */
|
||||
|
||||
/* TODO: The below implementation needs to be refactored: (1) remove offseto, it is always zero;
|
||||
* (2) simplify handling of non-blocking handles, (3) instead of relying on PAL to mmap
|
||||
|
||||
@@ -210,8 +210,7 @@ static void maybe_dequeue_two_futexes(struct shim_futex* futex1, struct shim_fut
|
||||
* and of `futex` by 1.
|
||||
* `futex->lock` needs to be held.
|
||||
*/
|
||||
static void add_futex_waiter(struct futex_waiter* waiter,
|
||||
struct shim_futex* futex,
|
||||
static void add_futex_waiter(struct futex_waiter* waiter, struct shim_futex* futex,
|
||||
uint32_t bitset) {
|
||||
assert(spinlock_is_locked(&futex->lock));
|
||||
|
||||
@@ -243,8 +242,7 @@ static struct shim_thread* remove_futex_waiter(struct futex_waiter* waiter,
|
||||
*
|
||||
* `futex1->lock` and `futex2->lock` need to be held.
|
||||
*/
|
||||
static void move_futex_waiter(struct futex_waiter* waiter,
|
||||
struct shim_futex* futex1,
|
||||
static void move_futex_waiter(struct futex_waiter* waiter, struct shim_futex* futex1,
|
||||
struct shim_futex* futex2) {
|
||||
assert(spinlock_is_locked(&futex1->lock));
|
||||
assert(spinlock_is_locked(&futex2->lock));
|
||||
@@ -332,7 +330,7 @@ static int futex_wait(uint32_t* uaddr, uint32_t val, uint64_t timeout, uint32_t
|
||||
goto out_with_futex_lock;
|
||||
}
|
||||
|
||||
struct futex_waiter waiter = { 0 };
|
||||
struct futex_waiter waiter = {0};
|
||||
add_futex_waiter(&waiter, futex, bitset);
|
||||
|
||||
spinlock_unlock_signal_on(&futex->lock);
|
||||
@@ -367,7 +365,7 @@ static int futex_wait(uint32_t* uaddr, uint32_t val, uint64_t timeout, uint32_t
|
||||
* NB: actually `futex` and this point to the same futex, so this won't call free. */
|
||||
put_futex(waiter.futex);
|
||||
|
||||
out_with_futex_lock: ; // C is awesome!
|
||||
out_with_futex_lock:; // C is awesome!
|
||||
/* Because dequeuing a futex requires `g_futex_list_lock` which we do not hold at this moment,
|
||||
* we check if we actually need to do it now (locks acquisition and dequeuing). */
|
||||
bool needs_dequeue = check_dequeue_futex(futex);
|
||||
@@ -429,7 +427,7 @@ static int move_to_wake_queue(struct shim_futex* futex, uint32_t bitset, int to_
|
||||
|
||||
static int futex_wake(uint32_t* uaddr, int to_wake, uint32_t bitset) {
|
||||
struct shim_futex* futex;
|
||||
struct wake_queue_head queue = { .first = WAKE_QUEUE_TAIL };
|
||||
struct wake_queue_head queue = {.first = WAKE_QUEUE_TAIL};
|
||||
int woken = 0;
|
||||
|
||||
if (!bitset) {
|
||||
@@ -472,10 +470,11 @@ static int wakeop_arg_extend(int x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
static int futex_wake_op(uint32_t* uaddr1, uint32_t* uaddr2, int to_wake1, int to_wake2, uint32_t val3) {
|
||||
static int futex_wake_op(uint32_t* uaddr1, uint32_t* uaddr2, int to_wake1, int to_wake2,
|
||||
uint32_t val3) {
|
||||
struct shim_futex* futex1 = NULL;
|
||||
struct shim_futex* futex2 = NULL;
|
||||
struct wake_queue_head queue = { .first = WAKE_QUEUE_TAIL };
|
||||
struct wake_queue_head queue = {.first = WAKE_QUEUE_TAIL};
|
||||
int ret = 0;
|
||||
bool needs_dequeue1 = false;
|
||||
bool needs_dequeue2 = false;
|
||||
@@ -582,11 +581,12 @@ out_unlock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int futex_requeue(uint32_t* uaddr1, uint32_t* uaddr2, int to_wake, int to_requeue, uint32_t* val) {
|
||||
static int futex_requeue(uint32_t* uaddr1, uint32_t* uaddr2, int to_wake, int to_requeue,
|
||||
uint32_t* val) {
|
||||
struct shim_futex* futex1 = NULL;
|
||||
struct shim_futex* futex2 = NULL;
|
||||
struct shim_futex* tmp = NULL;
|
||||
struct wake_queue_head queue = { .first = WAKE_QUEUE_TAIL };
|
||||
struct wake_queue_head queue = {.first = WAKE_QUEUE_TAIL};
|
||||
int ret = 0;
|
||||
int woken = 0;
|
||||
int requeued = 0;
|
||||
@@ -679,7 +679,7 @@ out_unlock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define FUTEX_CHECK_READ false
|
||||
#define FUTEX_CHECK_READ false
|
||||
#define FUTEX_CHECK_WRITE true
|
||||
static int is_valid_futex_ptr(uint32_t* ptr, bool check_write) {
|
||||
if (!IS_ALIGNED_PTR(ptr, alignof(*ptr))) {
|
||||
@@ -691,13 +691,14 @@ static int is_valid_futex_ptr(uint32_t* ptr, bool check_write) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _shim_do_futex(uint32_t* uaddr, int op, uint32_t val, void* utime, uint32_t* uaddr2, uint32_t val3) {
|
||||
static int _shim_do_futex(uint32_t* uaddr, int op, uint32_t val, void* utime, uint32_t* uaddr2,
|
||||
uint32_t val3) {
|
||||
int cmd = op & FUTEX_CMD_MASK;
|
||||
uint64_t timeout = NO_TIMEOUT;
|
||||
uint32_t val2 = 0;
|
||||
|
||||
if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_WAIT_BITSET ||
|
||||
cmd == FUTEX_LOCK_PI || cmd == FUTEX_WAIT_REQUEUE_PI)) {
|
||||
if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_WAIT_BITSET || cmd == FUTEX_LOCK_PI ||
|
||||
cmd == FUTEX_WAIT_REQUEUE_PI)) {
|
||||
if (test_user_memory(utime, sizeof(struct timespec), /*write=*/false)) {
|
||||
return -EFAULT;
|
||||
}
|
||||
@@ -786,7 +787,8 @@ static int _shim_do_futex(uint32_t* uaddr, int op, uint32_t val, void* utime, ui
|
||||
|
||||
int shim_do_futex(int* uaddr, int op, int val, void* utime, int* uaddr2, int val3) {
|
||||
static_assert(sizeof(int) == 4, "futexes are defined to be 32-bit");
|
||||
return _shim_do_futex((uint32_t*)uaddr, op, (uint32_t)val, utime, (uint32_t*)uaddr2, (uint32_t)val3);
|
||||
return _shim_do_futex((uint32_t*)uaddr, op, (uint32_t)val, utime, (uint32_t*)uaddr2,
|
||||
(uint32_t)val3);
|
||||
}
|
||||
|
||||
int shim_do_set_robust_list(struct robust_list_head* head, size_t len) {
|
||||
@@ -813,7 +815,8 @@ int shim_do_get_robust_list(pid_t pid, struct robust_list_head** head, size_t* l
|
||||
get_thread(thread);
|
||||
}
|
||||
|
||||
if (test_user_memory(head, sizeof(*head), /*write=*/true) || test_user_memory(len, sizeof(*len), /*write=*/true)) {
|
||||
if (test_user_memory(head, sizeof(*head), /*write=*/true) ||
|
||||
test_user_memory(len, sizeof(*len), /*write=*/true)) {
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -8,14 +8,15 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_utils.h>
|
||||
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
#ifndef ERANGE
|
||||
#define ERANGE 34
|
||||
|
||||
@@ -11,16 +11,17 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_checkpoint.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_ipc.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_thread.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_checkpoint.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_ipc.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_thread.h"
|
||||
|
||||
pid_t shim_do_getpid(void) {
|
||||
struct shim_thread* cur = get_cur_thread();
|
||||
return cur ? cur->tgid : 0;
|
||||
|
||||
@@ -8,11 +8,12 @@
|
||||
*/
|
||||
|
||||
#include <asm/resource.h>
|
||||
#include <shim_checkpoint.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_utils.h>
|
||||
#include <shim_vma.h>
|
||||
|
||||
#include "shim_checkpoint.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_utils.h"
|
||||
#include "shim_vma.h"
|
||||
|
||||
/*
|
||||
* TODO: implement actual limitation on each resource.
|
||||
|
||||
@@ -415,7 +415,7 @@ int shim_do_ioctl(int fd, unsigned long cmd, unsigned long arg) {
|
||||
}
|
||||
|
||||
*(int*)arg = size - offset;
|
||||
ret = 0;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
#include "shim_vma.h"
|
||||
|
||||
#ifdef MAP_32BIT /* x86_64-specific */
|
||||
#define MAP_32BIT_IF_SUPPORTED MAP_32BIT
|
||||
#define MAP_32BIT_IF_SUPPORTED MAP_32BIT
|
||||
#else
|
||||
#define MAP_32BIT_IF_SUPPORTED 0
|
||||
#define MAP_32BIT_IF_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#define LEGACY_MAP_MASK (MAP_SHARED \
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
void* shim_do_mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset) {
|
||||
struct shim_handle* hdl = NULL;
|
||||
long ret = 0;
|
||||
long ret = 0;
|
||||
|
||||
if (!(flags & MAP_FIXED) && addr)
|
||||
addr = ALLOC_ALIGN_DOWN_PTR(addr);
|
||||
@@ -203,8 +203,8 @@ out_handle:
|
||||
}
|
||||
|
||||
int shim_do_mprotect(void* addr, size_t length, int prot) {
|
||||
if (prot & ~(PROT_NONE | PROT_READ | PROT_WRITE | PROT_EXEC | PROT_GROWSDOWN | PROT_GROWSUP
|
||||
| PROT_SEM)) {
|
||||
if (prot & ~(PROT_NONE | PROT_READ | PROT_WRITE | PROT_EXEC | PROT_GROWSDOWN | PROT_GROWSUP |
|
||||
PROT_SEM)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -231,7 +231,6 @@ int shim_do_mprotect(void* addr, size_t length, int prot) {
|
||||
if (!IS_ALLOC_ALIGNED(length))
|
||||
length = ALLOC_ALIGN_UP(length);
|
||||
|
||||
|
||||
if (!access_ok(addr, length)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -245,7 +244,7 @@ int shim_do_mprotect(void* addr, size_t length, int prot) {
|
||||
}
|
||||
|
||||
if (prot & PROT_GROWSDOWN) {
|
||||
struct shim_vma_info vma_info = { 0 };
|
||||
struct shim_vma_info vma_info = {0};
|
||||
if (lookup_vma(addr, &vma_info) >= 0) {
|
||||
addr = vma_info.addr;
|
||||
if (vma_info.file) {
|
||||
@@ -324,7 +323,6 @@ int shim_do_mincore(void* addr, size_t len, unsigned char* vec) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int shim_do_mbind(void* start, unsigned long len, int mode, unsigned long* nmask,
|
||||
unsigned long maxnode, int flags) {
|
||||
/* dummy implementation, always return success */
|
||||
|
||||
@@ -12,16 +12,17 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <list.h>
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_ipc.h>
|
||||
#include <shim_sysv.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_unistd.h>
|
||||
#include <shim_utils.h>
|
||||
|
||||
#include "list.h"
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_ipc.h"
|
||||
#include "shim_sysv.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_unistd.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
#define MSGQ_HASH_LEN 8
|
||||
#define MSGQ_HASH_NUM (1 << MSGQ_HASH_LEN)
|
||||
@@ -695,9 +696,8 @@ static int __store_msg_persist(struct shim_msg_handle* msgq) {
|
||||
if (DkStreamSetLength(file, expected_size))
|
||||
goto err_file;
|
||||
|
||||
void* mem =
|
||||
(void*)DkStreamMap(file, NULL, PAL_PROT_READ | PAL_PROT_WRITE, 0,
|
||||
ALLOC_ALIGN_UP(expected_size));
|
||||
void* mem = (void*)DkStreamMap(file, NULL, PAL_PROT_READ | PAL_PROT_WRITE, 0,
|
||||
ALLOC_ALIGN_UP(expected_size));
|
||||
if (!mem) {
|
||||
ret = -EFAULT;
|
||||
goto err_file;
|
||||
@@ -743,7 +743,7 @@ static int __store_msg_persist(struct shim_msg_handle* msgq) {
|
||||
}
|
||||
|
||||
msgq->owned = false;
|
||||
ret = 0;
|
||||
ret = 0;
|
||||
goto out;
|
||||
|
||||
err_file:
|
||||
|
||||
@@ -4,33 +4,32 @@
|
||||
/*
|
||||
* shim_open.c
|
||||
*
|
||||
* Implementation of system call "read", "write", "open", "creat", "openat",
|
||||
* Implementation of system calls: "read", "write", "open", "creat", "openat",
|
||||
* "close", "lseek", "pread64", "pwrite64", "getdents", "getdents64",
|
||||
* "fsync", "truncate" and "ftruncate".
|
||||
*/
|
||||
|
||||
#include <shim_internal.h>
|
||||
#include <shim_utils.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_fs.h>
|
||||
// FIXME: Moving Linux includes first causes a bunch of "error: ‘S_IFLNK’ undeclared" errors.
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include <linux/stat.h>
|
||||
#include <linux/fcntl.h>
|
||||
|
||||
int do_handle_read (struct shim_handle * hdl, void * buf, int count)
|
||||
{
|
||||
int do_handle_read(struct shim_handle* hdl, void* buf, int count) {
|
||||
if (!(hdl->acc_mode & MAY_READ))
|
||||
return -EACCES;
|
||||
|
||||
struct shim_mount * fs = hdl->fs;
|
||||
struct shim_mount* fs = hdl->fs;
|
||||
assert(fs && fs->fs_ops);
|
||||
|
||||
if (!fs->fs_ops->read)
|
||||
@@ -42,12 +41,11 @@ int do_handle_read (struct shim_handle * hdl, void * buf, int count)
|
||||
return fs->fs_ops->read(hdl, buf, count);
|
||||
}
|
||||
|
||||
size_t shim_do_read (int fd, void * buf, size_t count)
|
||||
{
|
||||
size_t shim_do_read(int fd, void* buf, size_t count) {
|
||||
if (!buf || test_user_memory(buf, count, true))
|
||||
return -EFAULT;
|
||||
|
||||
struct shim_handle * hdl = get_fd_handle(fd, NULL, NULL);
|
||||
struct shim_handle* hdl = get_fd_handle(fd, NULL, NULL);
|
||||
if (!hdl)
|
||||
return -EBADF;
|
||||
|
||||
@@ -62,12 +60,11 @@ size_t shim_do_read (int fd, void * buf, size_t count)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int do_handle_write (struct shim_handle * hdl, const void * buf, int count)
|
||||
{
|
||||
int do_handle_write(struct shim_handle* hdl, const void* buf, int count) {
|
||||
if (!(hdl->acc_mode & MAY_WRITE))
|
||||
return -EACCES;
|
||||
|
||||
struct shim_mount * fs = hdl->fs;
|
||||
struct shim_mount* fs = hdl->fs;
|
||||
assert(fs && fs->fs_ops);
|
||||
|
||||
if (!fs->fs_ops->write)
|
||||
@@ -79,12 +76,11 @@ int do_handle_write (struct shim_handle * hdl, const void * buf, int count)
|
||||
return fs->fs_ops->write(hdl, buf, count);
|
||||
}
|
||||
|
||||
size_t shim_do_write (int fd, const void * buf, size_t count)
|
||||
{
|
||||
if (!buf || test_user_memory((void *) buf, count, false))
|
||||
size_t shim_do_write(int fd, const void* buf, size_t count) {
|
||||
if (!buf || test_user_memory((void*)buf, count, false))
|
||||
return -EFAULT;
|
||||
|
||||
struct shim_handle * hdl = get_fd_handle(fd, NULL, NULL);
|
||||
struct shim_handle* hdl = get_fd_handle(fd, NULL, NULL);
|
||||
if (!hdl)
|
||||
return -EBADF;
|
||||
|
||||
@@ -93,8 +89,7 @@ size_t shim_do_write (int fd, const void * buf, size_t count)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int shim_do_open (const char * file, int flags, mode_t mode)
|
||||
{
|
||||
int shim_do_open(const char* file, int flags, mode_t mode) {
|
||||
if (!file || test_user_string(file))
|
||||
return -EFAULT;
|
||||
|
||||
@@ -106,7 +101,7 @@ int shim_do_open (const char * file, int flags, mode_t mode)
|
||||
mode &= 07777;
|
||||
}
|
||||
|
||||
struct shim_handle * hdl = get_new_handle();
|
||||
struct shim_handle* hdl = get_new_handle();
|
||||
if (!hdl)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -121,13 +116,11 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int shim_do_creat (const char * path, mode_t mode)
|
||||
{
|
||||
return shim_do_open(path, O_CREAT|O_TRUNC|O_WRONLY, mode);
|
||||
int shim_do_creat(const char* path, mode_t mode) {
|
||||
return shim_do_open(path, O_CREAT | O_TRUNC | O_WRONLY, mode);
|
||||
}
|
||||
|
||||
int shim_do_openat (int dfd, const char * filename, int flags, int mode)
|
||||
{
|
||||
int shim_do_openat(int dfd, const char* filename, int flags, int mode) {
|
||||
if (!filename || test_user_string(filename))
|
||||
return -EFAULT;
|
||||
|
||||
@@ -139,13 +132,13 @@ int shim_do_openat (int dfd, const char * filename, int flags, int mode)
|
||||
mode &= 07777;
|
||||
}
|
||||
|
||||
struct shim_dentry * dir = NULL;
|
||||
struct shim_dentry* dir = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if ((ret = get_dirfd_dentry(dfd, &dir)) < 0)
|
||||
return ret;
|
||||
|
||||
struct shim_handle * hdl = get_new_handle();
|
||||
struct shim_handle* hdl = get_new_handle();
|
||||
if (!hdl) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
@@ -164,9 +157,8 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int shim_do_close (int fd)
|
||||
{
|
||||
struct shim_handle * handle = detach_fd_handle(fd, NULL, NULL);
|
||||
int shim_do_close(int fd) {
|
||||
struct shim_handle* handle = detach_fd_handle(fd, NULL, NULL);
|
||||
if (!handle)
|
||||
return -EBADF;
|
||||
|
||||
@@ -175,17 +167,16 @@ int shim_do_close (int fd)
|
||||
}
|
||||
|
||||
/* lseek is simply doing arithmetic on the offset, no PAL call here */
|
||||
off_t shim_do_lseek (int fd, off_t offset, int origin)
|
||||
{
|
||||
off_t shim_do_lseek(int fd, off_t offset, int origin) {
|
||||
if (origin != SEEK_SET && origin != SEEK_CUR && origin != SEEK_END)
|
||||
return -EINVAL;
|
||||
|
||||
struct shim_handle * hdl = get_fd_handle(fd, NULL, NULL);
|
||||
struct shim_handle* hdl = get_fd_handle(fd, NULL, NULL);
|
||||
if (!hdl)
|
||||
return -EBADF;
|
||||
|
||||
int ret = 0;
|
||||
struct shim_mount * fs = hdl->fs;
|
||||
struct shim_mount* fs = hdl->fs;
|
||||
assert(fs && fs->fs_ops);
|
||||
|
||||
if (!fs->fs_ops->seek) {
|
||||
@@ -205,19 +196,18 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t shim_do_pread64 (int fd, char * buf, size_t count, loff_t pos)
|
||||
{
|
||||
ssize_t shim_do_pread64(int fd, char* buf, size_t count, loff_t pos) {
|
||||
if (!buf || test_user_memory(buf, count, true))
|
||||
return -EFAULT;
|
||||
|
||||
if (pos < 0)
|
||||
return -EINVAL;
|
||||
|
||||
struct shim_handle * hdl = get_fd_handle(fd, NULL, NULL);
|
||||
struct shim_handle* hdl = get_fd_handle(fd, NULL, NULL);
|
||||
if (!hdl)
|
||||
return -EBADF;
|
||||
|
||||
struct shim_mount * fs = hdl->fs;
|
||||
struct shim_mount* fs = hdl->fs;
|
||||
ssize_t ret = -EACCES;
|
||||
|
||||
if (!fs || !fs->fs_ops)
|
||||
@@ -256,19 +246,18 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t shim_do_pwrite64 (int fd, char * buf, size_t count, loff_t pos)
|
||||
{
|
||||
ssize_t shim_do_pwrite64(int fd, char* buf, size_t count, loff_t pos) {
|
||||
if (!buf || test_user_memory(buf, count, false))
|
||||
return -EFAULT;
|
||||
|
||||
if (pos < 0)
|
||||
return -EINVAL;
|
||||
|
||||
struct shim_handle * hdl = get_fd_handle(fd, NULL, NULL);
|
||||
struct shim_handle* hdl = get_fd_handle(fd, NULL, NULL);
|
||||
if (!hdl)
|
||||
return -EBADF;
|
||||
|
||||
struct shim_mount * fs = hdl->fs;
|
||||
struct shim_mount* fs = hdl->fs;
|
||||
ssize_t ret = -EACCES;
|
||||
|
||||
if (!fs || !fs->fs_ops)
|
||||
@@ -307,8 +296,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int get_dirent_type (mode_t type)
|
||||
{
|
||||
static inline int get_dirent_type(mode_t type) {
|
||||
switch (type) {
|
||||
case S_IFLNK:
|
||||
return LINUX_DT_LNK;
|
||||
@@ -329,12 +317,11 @@ static inline int get_dirent_type (mode_t type)
|
||||
}
|
||||
}
|
||||
|
||||
size_t shim_do_getdents (int fd, struct linux_dirent * buf, size_t count)
|
||||
{
|
||||
size_t shim_do_getdents(int fd, struct linux_dirent* buf, size_t count) {
|
||||
if (!buf || test_user_memory(buf, count, true))
|
||||
return -EFAULT;
|
||||
|
||||
struct shim_handle * hdl = get_fd_handle(fd, NULL, NULL);
|
||||
struct shim_handle* hdl = get_fd_handle(fd, NULL, NULL);
|
||||
if (!hdl)
|
||||
return -EBADF;
|
||||
|
||||
@@ -355,9 +342,9 @@ size_t shim_do_getdents (int fd, struct linux_dirent * buf, size_t count)
|
||||
updated */
|
||||
lock(&hdl->lock);
|
||||
|
||||
struct shim_dir_handle * dirhdl = &hdl->dir_info;
|
||||
struct shim_dentry * dent = hdl->dentry;
|
||||
struct linux_dirent * b = buf;
|
||||
struct shim_dir_handle* dirhdl = &hdl->dir_info;
|
||||
struct shim_dentry* dent = hdl->dentry;
|
||||
struct linux_dirent* b = buf;
|
||||
int bytes = 0;
|
||||
|
||||
/* If we haven't listed the directory, do this first */
|
||||
@@ -367,31 +354,29 @@ size_t shim_do_getdents (int fd, struct linux_dirent * buf, size_t count)
|
||||
goto out;
|
||||
}
|
||||
|
||||
#define DIRENT_SIZE(len) (sizeof(struct linux_dirent) + \
|
||||
sizeof(struct linux_dirent_tail) + (len) + 1)
|
||||
|
||||
#define ASSIGN_DIRENT(dent, name, type) \
|
||||
do { \
|
||||
int len = strlen(name); \
|
||||
if (bytes + DIRENT_SIZE(len) > count) \
|
||||
goto done; \
|
||||
\
|
||||
struct linux_dirent_tail * bt \
|
||||
= (void *) b + sizeof(struct linux_dirent) + len + 1; \
|
||||
\
|
||||
b->d_ino = (dent)->ino; \
|
||||
b->d_off = ++dirhdl->offset; \
|
||||
b->d_reclen = DIRENT_SIZE(len); \
|
||||
\
|
||||
memcpy(b->d_name, name, len + 1); \
|
||||
\
|
||||
bt->pad = 0; \
|
||||
bt->d_type = (type); \
|
||||
\
|
||||
b = (void *) bt + sizeof(struct linux_dirent_tail); \
|
||||
bytes += DIRENT_SIZE(len); \
|
||||
} while(0)
|
||||
#define DIRENT_SIZE(len) \
|
||||
(sizeof(struct linux_dirent) + sizeof(struct linux_dirent_tail) + (len) + 1)
|
||||
|
||||
#define ASSIGN_DIRENT(dent, name, type) \
|
||||
do { \
|
||||
int len = strlen(name); \
|
||||
if (bytes + DIRENT_SIZE(len) > count) \
|
||||
goto done; \
|
||||
\
|
||||
struct linux_dirent_tail* bt = (void*)b + sizeof(struct linux_dirent) + len + 1; \
|
||||
\
|
||||
b->d_ino = (dent)->ino; \
|
||||
b->d_off = ++dirhdl->offset; \
|
||||
b->d_reclen = DIRENT_SIZE(len); \
|
||||
\
|
||||
memcpy(b->d_name, name, len + 1); \
|
||||
\
|
||||
bt->pad = 0; \
|
||||
bt->d_type = (type); \
|
||||
\
|
||||
b = (void*)bt + sizeof(struct linux_dirent_tail); \
|
||||
bytes += DIRENT_SIZE(len); \
|
||||
} while (0)
|
||||
|
||||
if (dirhdl->dot) {
|
||||
ASSIGN_DIRENT(dirhdl->dot, ".", LINUX_DT_DIR);
|
||||
@@ -405,7 +390,7 @@ size_t shim_do_getdents (int fd, struct linux_dirent * buf, size_t count)
|
||||
dirhdl->dotdot = NULL;
|
||||
}
|
||||
|
||||
if (dirhdl->ptr == (void *) -1) {
|
||||
if (dirhdl->ptr == (void*)-1) {
|
||||
ret = list_directory_handle(dent, hdl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
@@ -427,8 +412,7 @@ done:
|
||||
ret = bytes;
|
||||
/* DEP 3/3/17: Properly detect EINVAL case, where buffer is too small to
|
||||
* hold anything */
|
||||
if (bytes == 0 && (dirhdl->dot || dirhdl->dotdot ||
|
||||
(dirhdl->ptr && *dirhdl->ptr)))
|
||||
if (bytes == 0 && (dirhdl->dot || dirhdl->dotdot || (dirhdl->ptr && *dirhdl->ptr)))
|
||||
ret = -EINVAL;
|
||||
out:
|
||||
unlock(&hdl->lock);
|
||||
@@ -437,12 +421,11 @@ out_no_unlock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t shim_do_getdents64 (int fd, struct linux_dirent64 * buf, size_t count)
|
||||
{
|
||||
size_t shim_do_getdents64(int fd, struct linux_dirent64* buf, size_t count) {
|
||||
if (!buf || test_user_memory(buf, count, true))
|
||||
return -EFAULT;
|
||||
|
||||
struct shim_handle * hdl = get_fd_handle(fd, NULL, NULL);
|
||||
struct shim_handle* hdl = get_fd_handle(fd, NULL, NULL);
|
||||
if (!hdl)
|
||||
return -EBADF;
|
||||
|
||||
@@ -461,35 +444,36 @@ size_t shim_do_getdents64 (int fd, struct linux_dirent64 * buf, size_t count)
|
||||
|
||||
lock(&hdl->lock);
|
||||
|
||||
struct shim_dir_handle * dirhdl = &hdl->dir_info;
|
||||
struct shim_dentry * dent = hdl->dentry;
|
||||
struct linux_dirent64 * b = buf;
|
||||
struct shim_dir_handle* dirhdl = &hdl->dir_info;
|
||||
struct shim_dentry* dent = hdl->dentry;
|
||||
struct linux_dirent64* b = buf;
|
||||
int bytes = 0;
|
||||
|
||||
/* If we haven't listed the directory, do this first */
|
||||
if (!(dent->state & DENTRY_LISTED)) {
|
||||
ret = list_directory_dentry(dent);
|
||||
if (ret) goto out;
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
#define DIRENT_SIZE(len) (sizeof(struct linux_dirent64) + (len) + 1)
|
||||
#define DIRENT_SIZE(len) (sizeof(struct linux_dirent64) + (len) + 1)
|
||||
|
||||
#define ASSIGN_DIRENT(dent, name, type) \
|
||||
do { \
|
||||
int len = strlen(name); \
|
||||
if (bytes + DIRENT_SIZE(len) > count) \
|
||||
goto done; \
|
||||
\
|
||||
b->d_ino = (dent)->ino; \
|
||||
b->d_off = ++dirhdl->offset; \
|
||||
b->d_reclen = DIRENT_SIZE(len); \
|
||||
b->d_type = (type); \
|
||||
\
|
||||
memcpy(b->d_name, name, len + 1); \
|
||||
\
|
||||
b = (void *) b + DIRENT_SIZE(len); \
|
||||
bytes += DIRENT_SIZE(len); \
|
||||
} while(0)
|
||||
#define ASSIGN_DIRENT(dent, name, type) \
|
||||
do { \
|
||||
int len = strlen(name); \
|
||||
if (bytes + DIRENT_SIZE(len) > count) \
|
||||
goto done; \
|
||||
\
|
||||
b->d_ino = (dent)->ino; \
|
||||
b->d_off = ++dirhdl->offset; \
|
||||
b->d_reclen = DIRENT_SIZE(len); \
|
||||
b->d_type = (type); \
|
||||
\
|
||||
memcpy(b->d_name, name, len + 1); \
|
||||
\
|
||||
b = (void*)b + DIRENT_SIZE(len); \
|
||||
bytes += DIRENT_SIZE(len); \
|
||||
} while (0)
|
||||
|
||||
if (dirhdl->dot) {
|
||||
ASSIGN_DIRENT(dirhdl->dot, ".", LINUX_DT_DIR);
|
||||
@@ -503,9 +487,10 @@ size_t shim_do_getdents64 (int fd, struct linux_dirent64 * buf, size_t count)
|
||||
dirhdl->dotdot = NULL;
|
||||
}
|
||||
|
||||
if (dirhdl->ptr == (void *) -1) {
|
||||
if (dirhdl->ptr == (void*)-1) {
|
||||
ret = list_directory_handle(dent, hdl);
|
||||
if (ret) goto out;
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
while (dirhdl->ptr && *dirhdl->ptr) {
|
||||
@@ -524,8 +509,7 @@ done:
|
||||
ret = bytes;
|
||||
/* DEP 3/3/17: Properly detect EINVAL case, where buffer is too small to
|
||||
* hold anything */
|
||||
if (bytes == 0 && (dirhdl->dot || dirhdl->dotdot ||
|
||||
(dirhdl->ptr && *dirhdl->ptr)))
|
||||
if (bytes == 0 && (dirhdl->dot || dirhdl->dotdot || (dirhdl->ptr && *dirhdl->ptr)))
|
||||
ret = -EINVAL;
|
||||
unlock(&hdl->lock);
|
||||
out:
|
||||
@@ -533,14 +517,13 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int shim_do_fsync (int fd)
|
||||
{
|
||||
struct shim_handle * hdl = get_fd_handle(fd, NULL, NULL);
|
||||
int shim_do_fsync(int fd) {
|
||||
struct shim_handle* hdl = get_fd_handle(fd, NULL, NULL);
|
||||
if (!hdl)
|
||||
return -EBADF;
|
||||
|
||||
int ret = -EACCES;
|
||||
struct shim_mount * fs = hdl->fs;
|
||||
struct shim_mount* fs = hdl->fs;
|
||||
|
||||
if (!fs || !fs->fs_ops)
|
||||
goto out;
|
||||
@@ -559,18 +542,14 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// DEP 10/20/16: Assuming fsync >> fdatasync for now
|
||||
// and no app depends on only syncing data for correctness.
|
||||
int shim_do_fdatasync (int fd)
|
||||
{
|
||||
int shim_do_fdatasync(int fd) {
|
||||
return shim_do_fsync(fd);
|
||||
}
|
||||
|
||||
|
||||
int shim_do_truncate (const char * path, loff_t length)
|
||||
{
|
||||
struct shim_dentry * dent = NULL;
|
||||
int shim_do_truncate(const char* path, loff_t length) {
|
||||
struct shim_dentry* dent = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (!path || test_user_string(path))
|
||||
@@ -579,7 +558,7 @@ int shim_do_truncate (const char * path, loff_t length)
|
||||
if ((ret = path_lookupat(NULL, path, 0, &dent, NULL)) < 0)
|
||||
return ret;
|
||||
|
||||
struct shim_mount * fs = dent->fs;
|
||||
struct shim_mount* fs = dent->fs;
|
||||
|
||||
if (!fs || !fs->d_ops || !fs->d_ops->open) {
|
||||
ret = -EBADF;
|
||||
@@ -591,7 +570,7 @@ int shim_do_truncate (const char * path, loff_t length)
|
||||
goto out;
|
||||
}
|
||||
|
||||
struct shim_handle * hdl = get_new_handle();
|
||||
struct shim_handle* hdl = get_new_handle();
|
||||
|
||||
if (!hdl) {
|
||||
ret = -ENOMEM;
|
||||
@@ -611,20 +590,18 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int shim_do_ftruncate (int fd, loff_t length)
|
||||
{
|
||||
struct shim_handle * hdl = get_fd_handle(fd, NULL, NULL);
|
||||
int shim_do_ftruncate(int fd, loff_t length) {
|
||||
struct shim_handle* hdl = get_fd_handle(fd, NULL, NULL);
|
||||
if (!hdl)
|
||||
return -EBADF;
|
||||
|
||||
struct shim_mount * fs = hdl->fs;
|
||||
struct shim_mount* fs = hdl->fs;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (!fs || !fs->fs_ops)
|
||||
goto out;
|
||||
|
||||
if (hdl->type == TYPE_DIR ||
|
||||
!fs->fs_ops->truncate)
|
||||
if (hdl->type == TYPE_DIR || !fs->fs_ops->truncate)
|
||||
goto out;
|
||||
|
||||
ret = fs->fs_ops->truncate(hdl, length);
|
||||
|
||||
@@ -25,9 +25,9 @@ static int create_pipes(struct shim_handle* srv, struct shim_handle* cli, int fl
|
||||
int ret = 0;
|
||||
char uri[PIPE_URI_SIZE];
|
||||
|
||||
PAL_HANDLE hdl0 = NULL; /* server pipe (temporary, waits for connect from hdl2) */
|
||||
PAL_HANDLE hdl1 = NULL; /* one pipe end (accepted connect from hdl2) */
|
||||
PAL_HANDLE hdl2 = NULL; /* other pipe end (connects to hdl0 and talks to hdl1) */
|
||||
PAL_HANDLE hdl0 = NULL; /* server pipe (temporary, waits for connect from hdl2) */
|
||||
PAL_HANDLE hdl1 = NULL; /* one pipe end (accepted connect from hdl2) */
|
||||
PAL_HANDLE hdl2 = NULL; /* other pipe end (connects to hdl0 and talks to hdl1) */
|
||||
|
||||
if ((ret = create_pipe(name, uri, PIPE_URI_SIZE, &hdl0, qstr,
|
||||
/*use_vmid_for_name=*/false)) < 0) {
|
||||
@@ -241,7 +241,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int shim_do_mknodat(int dirfd, const char *pathname, mode_t mode, dev_t dev) {
|
||||
int shim_do_mknodat(int dirfd, const char* pathname, mode_t mode, dev_t dev) {
|
||||
int ret = 0;
|
||||
__UNUSED(dev);
|
||||
|
||||
@@ -251,7 +251,7 @@ int shim_do_mknodat(int dirfd, const char *pathname, mode_t mode, dev_t dev) {
|
||||
/* FIXME: Graphene assumes that file is at least readable by owner, in particular, see
|
||||
* unlink() emulation that uses DkStreamOpen(). We change empty mode to readable
|
||||
* by user here to allow a consequent unlink. Was detected on LTP mknod tests. */
|
||||
int fd = shim_do_openat(dirfd, pathname, O_CREAT | O_EXCL, mode ? : S_IRUSR);
|
||||
int fd = shim_do_openat(dirfd, pathname, O_CREAT | O_EXCL, mode ?: S_IRUSR);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
return shim_do_close(fd);
|
||||
@@ -376,6 +376,6 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int shim_do_mknod(const char *pathname, mode_t mode, dev_t dev) {
|
||||
int shim_do_mknod(const char* pathname, mode_t mode, dev_t dev) {
|
||||
return shim_do_mknodat(AT_FDCWD, pathname, mode, dev);
|
||||
}
|
||||
|
||||
@@ -9,14 +9,15 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_utils.h>
|
||||
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
typedef long int __fd_mask;
|
||||
|
||||
|
||||
@@ -10,13 +10,14 @@
|
||||
* "sched_setaffinity", "sched_getaffinity", "getcpu".
|
||||
*/
|
||||
|
||||
#include <api.h>
|
||||
#include <errno.h>
|
||||
#include <linux/resource.h>
|
||||
#include <linux/sched.h>
|
||||
#include <pal.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
|
||||
#include "api.h"
|
||||
#include "pal.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
|
||||
int shim_do_sched_yield(void) {
|
||||
DkThreadYieldExecution();
|
||||
@@ -71,18 +72,19 @@ int shim_do_sched_setscheduler(pid_t pid, int policy, struct __kernel_sched_para
|
||||
return -EINVAL;
|
||||
|
||||
/* fail on unrecognized policies */
|
||||
if (policy != SCHED_NORMAL && policy != SCHED_BATCH && policy != SCHED_IDLE && /* non-real-time */
|
||||
policy != SCHED_FIFO && policy != SCHED_RR /* real-time */)
|
||||
if (policy != SCHED_NORMAL && policy != SCHED_BATCH &&
|
||||
policy != SCHED_IDLE && /* non-real-time */
|
||||
policy != SCHED_FIFO && policy != SCHED_RR /* real-time */)
|
||||
return -EINVAL;
|
||||
|
||||
/* non-real-time policies must have priority of 0 */
|
||||
if ((policy == SCHED_NORMAL || policy == SCHED_BATCH || policy == SCHED_IDLE) &&
|
||||
(param->__sched_priority != 0))
|
||||
(param->__sched_priority != 0))
|
||||
return -EINVAL;
|
||||
|
||||
/* real-time policies must have priority in range [1, 99] */
|
||||
if ((policy == SCHED_FIFO || policy == SCHED_RR) &&
|
||||
(param->__sched_priority < 1 || param->__sched_priority > 99))
|
||||
(param->__sched_priority < 1 || param->__sched_priority > 99))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@@ -98,8 +100,9 @@ int shim_do_sched_getscheduler(pid_t pid) {
|
||||
|
||||
int shim_do_sched_get_priority_max(int policy) {
|
||||
/* fail on unrecognized policies */
|
||||
if (policy != SCHED_NORMAL && policy != SCHED_BATCH && policy != SCHED_IDLE && /* non-real-time */
|
||||
policy != SCHED_FIFO && policy != SCHED_RR /* real-time */)
|
||||
if (policy != SCHED_NORMAL && policy != SCHED_BATCH &&
|
||||
policy != SCHED_IDLE && /* non-real-time */
|
||||
policy != SCHED_FIFO && policy != SCHED_RR /* real-time */)
|
||||
return -EINVAL;
|
||||
|
||||
/* real-time policies have max priority of 99 */
|
||||
@@ -112,8 +115,9 @@ int shim_do_sched_get_priority_max(int policy) {
|
||||
|
||||
int shim_do_sched_get_priority_min(int policy) {
|
||||
/* fail on unrecognized policies */
|
||||
if (policy != SCHED_NORMAL && policy != SCHED_BATCH && policy != SCHED_IDLE && /* non-real-time */
|
||||
policy != SCHED_FIFO && policy != SCHED_RR /* real-time */)
|
||||
if (policy != SCHED_NORMAL && policy != SCHED_BATCH &&
|
||||
policy != SCHED_IDLE && /* non-real-time */
|
||||
policy != SCHED_FIFO && policy != SCHED_RR /* real-time */)
|
||||
return -EINVAL;
|
||||
|
||||
/* real-time policies have min priority of 1 */
|
||||
|
||||
@@ -8,15 +8,16 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <list.h>
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_ipc.h>
|
||||
#include <shim_sysv.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_utils.h>
|
||||
|
||||
#include "list.h"
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_ipc.h"
|
||||
#include "shim_sysv.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
#define SEM_HASH_LEN 8
|
||||
#define SEM_HASH_NUM (1 << SEM_HASH_LEN)
|
||||
|
||||
@@ -285,11 +285,11 @@ int do_kill_proc(IDTYPE sender, IDTYPE tgid, int sig, bool use_ipc) {
|
||||
/* This might be called by an internal thread (like IPC), so we cannot inspect `cur_thread` ids
|
||||
* to check whether `sig` is targetted at it, but need to do a full search. */
|
||||
struct signal_thread_arg arg = {
|
||||
.sig = sig,
|
||||
.sender = sender,
|
||||
.cmp_val = tgid,
|
||||
.sig = sig,
|
||||
.sender = sender,
|
||||
.cmp_val = tgid,
|
||||
.cmp_type = TGID,
|
||||
.sent = false,
|
||||
.sent = false,
|
||||
};
|
||||
int ret = walk_thread_list(_signal_one_thread, &arg, /*one_shot=*/true);
|
||||
if (ret < 0 && ret != -ESRCH) {
|
||||
@@ -336,11 +336,11 @@ int do_kill_pgroup(IDTYPE sender, IDTYPE pgid, int sig, bool use_ipc) {
|
||||
/* This might be called by an internal thread (like IPC), so we cannot inspect `cur_thread` ids
|
||||
* to check whether `sig` is targetted at it, but need to do a full search. */
|
||||
struct signal_thread_arg arg = {
|
||||
.sig = sig,
|
||||
.sender = sender,
|
||||
.cmp_val = pgid,
|
||||
.sig = sig,
|
||||
.sender = sender,
|
||||
.cmp_val = pgid,
|
||||
.cmp_type = PGID,
|
||||
.sent = false,
|
||||
.sent = false,
|
||||
};
|
||||
ret = walk_thread_list(_signal_one_thread, &arg, /*one_shot=*/true);
|
||||
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_utils.h>
|
||||
#include <shim_vma.h>
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_utils.h"
|
||||
#include "shim_vma.h"
|
||||
|
||||
int shim_do_pause(void) {
|
||||
/* ~0ULL micro sec ~= 805675 years */
|
||||
|
||||
@@ -192,8 +192,8 @@ static ssize_t inet_translate_addr(int domain, char* uri, size_t count, struct a
|
||||
if (domain == AF_INET6) {
|
||||
unsigned short* ad = (void*)&addr->addr.v6.s6_addr;
|
||||
return snprintf(uri, count, "[%04x:%04x:%x:%04x:%04x:%04x:%04x:%04x]:%u", __ntohs(ad[0]),
|
||||
__ntohs(ad[1]), __ntohs(ad[2]), __ntohs(ad[3]), __ntohs(ad[4]), __ntohs(ad[5]),
|
||||
__ntohs(ad[6]), __ntohs(ad[7]), addr->ext_port);
|
||||
__ntohs(ad[1]), __ntohs(ad[2]), __ntohs(ad[3]), __ntohs(ad[4]),
|
||||
__ntohs(ad[5]), __ntohs(ad[6]), __ntohs(ad[7]), addr->ext_port);
|
||||
}
|
||||
|
||||
return -EPROTONOSUPPORT;
|
||||
@@ -336,26 +336,26 @@ static size_t inet_copy_addr(int domain, struct sockaddr* saddr, size_t saddr_le
|
||||
size_t len = 0;
|
||||
|
||||
switch (domain) {
|
||||
case AF_INET:
|
||||
in = (struct sockaddr_in*)&ss;
|
||||
in->sin_family = AF_INET;
|
||||
in->sin_port = __htons(addr->port);
|
||||
in->sin_addr = addr->addr.v4;
|
||||
case AF_INET:
|
||||
in = (struct sockaddr_in*)&ss;
|
||||
in->sin_family = AF_INET;
|
||||
in->sin_port = __htons(addr->port);
|
||||
in->sin_addr = addr->addr.v4;
|
||||
|
||||
len = MIN(saddr_len, sizeof(struct sockaddr_in));
|
||||
break;
|
||||
len = MIN(saddr_len, sizeof(struct sockaddr_in));
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
in6 = (struct sockaddr_in6*)&ss;
|
||||
in6->sin6_family = AF_INET6;
|
||||
in6->sin6_port = __htons(addr->port);
|
||||
in6->sin6_addr = addr->addr.v6;
|
||||
case AF_INET6:
|
||||
in6 = (struct sockaddr_in6*)&ss;
|
||||
in6->sin6_family = AF_INET6;
|
||||
in6->sin6_port = __htons(addr->port);
|
||||
in6->sin6_addr = addr->addr.v6;
|
||||
|
||||
len = MIN(saddr_len, sizeof(struct sockaddr_in6));
|
||||
break;
|
||||
len = MIN(saddr_len, sizeof(struct sockaddr_in6));
|
||||
break;
|
||||
|
||||
default:
|
||||
__abort(); /* this function must accept only AF_INET/AF_INET6 */
|
||||
default:
|
||||
__abort(); /* this function must accept only AF_INET/AF_INET6 */
|
||||
}
|
||||
|
||||
memcpy(saddr, &ss, len);
|
||||
@@ -373,8 +373,8 @@ static void inet_save_addr(int domain, struct addr_inet* addr, const struct sock
|
||||
|
||||
if (domain == AF_INET6) {
|
||||
if (saddr->sa_family == AF_INET) {
|
||||
const struct sockaddr_in* in = (const struct sockaddr_in*)saddr;
|
||||
addr->port = __ntohs(in->sin_port);
|
||||
const struct sockaddr_in* in = (const struct sockaddr_in*)saddr;
|
||||
addr->port = __ntohs(in->sin_port);
|
||||
addr->addr.v6.s6_addr32[0] = __htonl(0);
|
||||
addr->addr.v6.s6_addr32[1] = __htonl(0);
|
||||
addr->addr.v6.s6_addr32[2] = __htonl(0x0000ffff);
|
||||
@@ -382,8 +382,8 @@ static void inet_save_addr(int domain, struct addr_inet* addr, const struct sock
|
||||
addr->addr.v6.s6_addr32[3] = in->sin_addr.s_addr;
|
||||
} else {
|
||||
const struct sockaddr_in6* in6 = (const struct sockaddr_in6*)saddr;
|
||||
addr->port = __ntohs(in6->sin6_port);
|
||||
addr->addr.v6 = in6->sin6_addr;
|
||||
addr->port = __ntohs(in6->sin6_port);
|
||||
addr->addr.v6 = in6->sin6_addr;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -458,7 +458,6 @@ static int hash_to_hex_string(HASHTYPE hash, char* buf, size_t size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int shim_do_bind(int sockfd, struct sockaddr* addr, int _addrlen) {
|
||||
if (_addrlen < 0)
|
||||
return -EINVAL;
|
||||
@@ -467,7 +466,7 @@ int shim_do_bind(int sockfd, struct sockaddr* addr, int _addrlen) {
|
||||
return -EFAULT;
|
||||
|
||||
struct shim_handle* hdl = get_fd_handle(sockfd, NULL, NULL);
|
||||
int ret = -EINVAL;
|
||||
int ret = -EINVAL;
|
||||
if (!hdl)
|
||||
return -EBADF;
|
||||
|
||||
@@ -728,7 +727,7 @@ int shim_do_connect(int sockfd, struct sockaddr* addr, int _addrlen) {
|
||||
struct shim_sock_handle* sock = &hdl->info.sock;
|
||||
lock(&hdl->lock);
|
||||
enum shim_sock_state state = sock->sock_state;
|
||||
int ret = -EINVAL;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (state == SOCK_CONNECTED) {
|
||||
if (addr->sa_family == AF_UNSPEC) {
|
||||
@@ -1106,9 +1105,7 @@ static ssize_t do_sendmsg(int fd, struct iovec* bufs, int nbufs, int flags,
|
||||
inet_rebase_port(false, sock->domain, &addr_buf, false);
|
||||
size_t prefix_len = static_strlen(URI_PREFIX_UDP);
|
||||
memcpy(uri, URI_PREFIX_UDP, prefix_len + 1);
|
||||
if ((ret = inet_translate_addr(sock->domain,
|
||||
uri + prefix_len,
|
||||
SOCK_URI_SIZE - prefix_len,
|
||||
if ((ret = inet_translate_addr(sock->domain, uri + prefix_len, SOCK_URI_SIZE - prefix_len,
|
||||
&addr_buf)) < 0) {
|
||||
lock(&hdl->lock);
|
||||
goto out_locked;
|
||||
@@ -1118,7 +1115,7 @@ static ssize_t do_sendmsg(int fd, struct iovec* bufs, int nbufs, int flags,
|
||||
}
|
||||
|
||||
int bytes = 0;
|
||||
ret = 0;
|
||||
ret = 0;
|
||||
|
||||
for (int i = 0; i < nbufs; i++) {
|
||||
PAL_NUM pal_ret = DkStreamWrite(pal_hdl, 0, bufs[i].iov_len, bufs[i].iov_base, uri);
|
||||
@@ -1340,10 +1337,12 @@ static ssize_t do_recvmsg(int fd, struct iovec* bufs, size_t nbufs, int flags,
|
||||
/* some data left to read from peek buffer */
|
||||
assert(total_bytes < peek_buffer->end - peek_buffer->start);
|
||||
iov_bytes = MIN(bufs[i].iov_len, peek_buffer->end - peek_buffer->start - total_bytes);
|
||||
memcpy(bufs[i].iov_base, &peek_buffer->buf[peek_buffer->start + total_bytes], iov_bytes);
|
||||
memcpy(bufs[i].iov_base, &peek_buffer->buf[peek_buffer->start + total_bytes],
|
||||
iov_bytes);
|
||||
uri = peek_buffer->uri;
|
||||
} else {
|
||||
PAL_NUM pal_ret = DkStreamRead(pal_hdl, 0, bufs[i].iov_len, bufs[i].iov_base, uri, uri ? SOCK_URI_SIZE : 0);
|
||||
PAL_NUM pal_ret = DkStreamRead(pal_hdl, 0, bufs[i].iov_len, bufs[i].iov_base, uri,
|
||||
uri ? SOCK_URI_SIZE : 0);
|
||||
if (pal_ret == PAL_STREAM_ERROR) {
|
||||
ret = PAL_NATIVE_ERRNO() == PAL_ERROR_STREAMNOTEXIST
|
||||
? -ECONNABORTED
|
||||
@@ -1365,7 +1364,8 @@ static ssize_t do_recvmsg(int fd, struct iovec* bufs, size_t nbufs, int flags,
|
||||
if (uri) {
|
||||
struct addr_inet conn;
|
||||
|
||||
if ((ret = inet_parse_addr(sock->domain, sock->sock_type, uri, &conn, NULL)) < 0) {
|
||||
if ((ret = inet_parse_addr(sock->domain, sock->sock_type, uri, &conn, NULL))
|
||||
< 0) {
|
||||
lock(&hdl->lock);
|
||||
goto out_locked;
|
||||
}
|
||||
@@ -1623,8 +1623,8 @@ struct __kernel_linger {
|
||||
|
||||
static void __populate_addr_with_defaults(PAL_STREAM_ATTR* attr) {
|
||||
/* Linux default recv/send buffer sizes for new sockets */
|
||||
attr->socket.receivebuf = 212992;
|
||||
attr->socket.sendbuf = 212992;
|
||||
attr->socket.receivebuf = 212992;
|
||||
attr->socket.sendbuf = 212992;
|
||||
|
||||
attr->socket.linger = 0;
|
||||
attr->socket.receivetimeout = 0;
|
||||
@@ -2000,8 +2000,8 @@ out:
|
||||
return ret;
|
||||
|
||||
unknown_level:
|
||||
ret = -EOPNOTSUPP; /* Kernel seems to return this value despite `man` saying that it can
|
||||
* return only ENOPROTOOPT. */
|
||||
ret = -EOPNOTSUPP; /* Kernel seems to return this value despite `man` saying that it can
|
||||
* return only ENOPROTOOPT. */
|
||||
goto out;
|
||||
unknown_opt:
|
||||
ret = -ENOPROTOOPT;
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
#include <errno.h>
|
||||
#include <linux/fcntl.h>
|
||||
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_thread.h>
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_thread.h"
|
||||
|
||||
int shim_do_stat(const char* file, struct stat* stat) {
|
||||
if (!file || test_user_string(file))
|
||||
|
||||
@@ -8,12 +8,13 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
|
||||
int shim_do_gettimeofday(struct __kernel_timeval* tv, struct __kernel_timezone* tz) {
|
||||
if (!tv)
|
||||
|
||||
@@ -15,20 +15,19 @@
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
|
||||
|
||||
/* This structure is *not* shared between Graphene processes, despite it should. As a result,
|
||||
* effects of set{host,domain}name in process A will not be visible in process B.
|
||||
* These syscalls are rarely used and are implemented in Graphene mainly to enable LTP to test
|
||||
* our `uname` implementation. */
|
||||
static struct new_utsname g_current_uname = {
|
||||
.sysname = "Linux",
|
||||
.nodename = "localhost",
|
||||
.release = "3.10.0",
|
||||
.version = "1",
|
||||
.sysname = "Linux",
|
||||
.nodename = "localhost",
|
||||
.release = "3.10.0",
|
||||
.version = "1",
|
||||
#ifdef __x86_64__
|
||||
.machine = "x86_64",
|
||||
.machine = "x86_64",
|
||||
#else
|
||||
#error "Not implemented"
|
||||
#error "Not implemented"
|
||||
#endif
|
||||
.domainname = "(none)", /* this seems to be the default on Linux */
|
||||
};
|
||||
|
||||
@@ -9,19 +9,20 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <linux/wait.h>
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_utils.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
pid_t shim_do_wait4(pid_t pid, int* status, int option, struct __kernel_rusage* ru) {
|
||||
struct shim_thread* cur = get_cur_thread();
|
||||
struct shim_thread* thread = NULL;
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
__UNUSED(ru);
|
||||
|
||||
if (option & ~(WNOHANG | WUNTRACED | WCONTINUED | __WNOTHREAD | __WCLONE | __WALL)) {
|
||||
|
||||
@@ -8,13 +8,14 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_utils.h>
|
||||
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
ssize_t shim_do_readv(int fd, const struct iovec* vec, int vlen) {
|
||||
if (!vec || test_user_memory((void*)vec, sizeof(*vec) * vlen, false))
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
* This file contains the entry point of system call table in library OS.
|
||||
*/
|
||||
|
||||
#include "shim_defs.h"
|
||||
#include "asm-offsets.h"
|
||||
#include "shim_defs.h"
|
||||
|
||||
.global syscalldb
|
||||
.type syscalldb, @function
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include <shim_internal.h>
|
||||
#include <shim_utils.h>
|
||||
#include "shim_internal.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
/* forward declaration */
|
||||
static void __transform(UINT4* buf, UINT4* in);
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
/* SPDX-License-Identifier: LGPL-3.0-or-later */
|
||||
/* Copyright (C) 2014 Stony Brook University */
|
||||
|
||||
#include <api.h>
|
||||
#include <pal.h>
|
||||
#include <shim_defs.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_ipc.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "api.h"
|
||||
#include "pal.h"
|
||||
#include "shim_defs.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_ipc.h"
|
||||
|
||||
PAL_HANDLE debug_handle = NULL;
|
||||
|
||||
static inline int debug_fputs(const char* buf, int len) {
|
||||
@@ -24,7 +25,7 @@ static int debug_fputch(void* f, int ch, void* b) {
|
||||
buf->buf[buf->end++] = ch;
|
||||
|
||||
if (ch == '\n') {
|
||||
int ret = debug_fputs(buf->buf, buf->end);
|
||||
int ret = debug_fputs(buf->buf, buf->end);
|
||||
buf->end = buf->start;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
* This file contain functions to allocate / free a fixed-size string object.
|
||||
*/
|
||||
|
||||
#include <shim_internal.h>
|
||||
#include <shim_utils.h>
|
||||
#include "shim_internal.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
static struct shim_lock str_mgr_lock;
|
||||
|
||||
|
||||
@@ -158,7 +158,8 @@ int main(int argc, char** argv) {
|
||||
|
||||
close(pipes[0]);
|
||||
|
||||
if (write(pipes[5], timevals, sizeof(struct timeval) * 2) != sizeof(struct timeval) * 2) {
|
||||
if (write(pipes[5], timevals, sizeof(struct timeval) * 2) !=
|
||||
sizeof(struct timeval) * 2) {
|
||||
perror("write error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ off_t tell_fd(const char* path, int fd) {
|
||||
}
|
||||
|
||||
int open_output_fd(const char* path, bool rdwr) {
|
||||
int fd = open(path, rdwr ? O_RDWR|O_CREAT : O_WRONLY|O_CREAT, 0664);
|
||||
int fd = open(path, rdwr ? O_RDWR | O_CREAT : O_WRONLY | O_CREAT, 0664);
|
||||
if (fd < 0)
|
||||
fatal_error("Failed to open output file %s: %s\n", path, strerror(errno));
|
||||
return fd;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user