Reformat repository to our C formatting rules (final iteration)

This commit is contained in:
Michał Kowalczyk
2020-09-07 20:51:48 +02:00
parent 04cd942485
commit ad477ec7bf
284 changed files with 5302 additions and 5741 deletions

View File

@@ -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

View File

@@ -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:

View File

@@ -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__

View File

@@ -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) {

View File

@@ -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_ */

View File

@@ -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_ */

View File

@@ -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) \

View File

@@ -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);

View File

@@ -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_ */

View File

@@ -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"

View File

@@ -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) */
};

View File

@@ -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,

View 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);

View File

@@ -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);

View File

@@ -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_ */

View File

@@ -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 */

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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_ */

View File

@@ -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) */

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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"

View File

@@ -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);

View File

@@ -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,
};

View File

@@ -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, &quote_size);
bool ok = DkAttestationQuote(&g_user_report_data, g_user_report_data_size, quote, &quote_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},
}};

View File

@@ -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},
},
};

View File

@@ -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;

View File

@@ -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,
};

View File

@@ -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))

View File

@@ -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)

View File

@@ -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,

View File

@@ -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");
}

View File

@@ -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},
}
};

View File

@@ -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},
}};

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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();

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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++) = '/';
}

View File

@@ -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);

View File

@@ -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()));

View File

@@ -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"

View File

@@ -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)

View File

@@ -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);

View File

@@ -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)

View 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();

View File

@@ -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;
}

View File

@@ -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(&regs), my_thread->tid);
debug("child swapping stack to %p return 0x%lx: %d\n", stack, shim_regs_get_ip(&regs),
my_thread->tid);
tcb->context.regs = &regs;
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);

View File

@@ -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);

View File

@@ -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)

View File

@@ -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) {

View File

@@ -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));

View File

@@ -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) {

View File

@@ -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)

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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.

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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:

View 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);

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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)

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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))

View 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)

View File

@@ -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 */
};

View File

@@ -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)) {

View File

@@ -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))

View File

@@ -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

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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