mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-21 18:44:01 +00:00
ABI
This commit is contained in:
@@ -16,6 +16,12 @@ typedef u64 (*clks_exec_entry_fn)(void);
|
||||
#define CLKS_EXEC_MAX_PROCS 64U
|
||||
#define CLKS_EXEC_MAX_DEPTH 16U
|
||||
#define CLKS_EXEC_PATH_MAX 192U
|
||||
#define CLKS_EXEC_ARG_LINE_MAX 256U
|
||||
#define CLKS_EXEC_ENV_LINE_MAX 512U
|
||||
#define CLKS_EXEC_MAX_ARGS 24U
|
||||
#define CLKS_EXEC_MAX_ENVS 24U
|
||||
#define CLKS_EXEC_ITEM_MAX 128U
|
||||
#define CLKS_EXEC_STATUS_SIGNAL_FLAG (1ULL << 63)
|
||||
|
||||
enum clks_exec_proc_state {
|
||||
CLKS_EXEC_PROC_UNUSED = 0,
|
||||
@@ -34,10 +40,21 @@ struct clks_exec_proc_record {
|
||||
u64 exit_status;
|
||||
u32 tty_index;
|
||||
char path[CLKS_EXEC_PATH_MAX];
|
||||
char argv_line[CLKS_EXEC_ARG_LINE_MAX];
|
||||
char env_line[CLKS_EXEC_ENV_LINE_MAX];
|
||||
u32 argc;
|
||||
u32 envc;
|
||||
char argv_items[CLKS_EXEC_MAX_ARGS][CLKS_EXEC_ITEM_MAX];
|
||||
char env_items[CLKS_EXEC_MAX_ENVS][CLKS_EXEC_ITEM_MAX];
|
||||
u64 last_signal;
|
||||
u64 last_fault_vector;
|
||||
u64 last_fault_error;
|
||||
u64 last_fault_rip;
|
||||
};
|
||||
|
||||
#if defined(CLKS_ARCH_X86_64)
|
||||
extern u64 clks_exec_call_on_stack_x86_64(void *entry_ptr, void *stack_top);
|
||||
extern void clks_exec_abort_to_caller_x86_64(void);
|
||||
#endif
|
||||
|
||||
static u64 clks_exec_requests = 0ULL;
|
||||
@@ -50,6 +67,8 @@ static u64 clks_exec_next_pid = 1ULL;
|
||||
static u64 clks_exec_pid_stack[CLKS_EXEC_MAX_DEPTH];
|
||||
static clks_bool clks_exec_exit_requested_stack[CLKS_EXEC_MAX_DEPTH];
|
||||
static u64 clks_exec_exit_status_stack[CLKS_EXEC_MAX_DEPTH];
|
||||
static u64 clks_exec_unwind_slot_stack[CLKS_EXEC_MAX_DEPTH];
|
||||
static clks_bool clks_exec_unwind_slot_valid_stack[CLKS_EXEC_MAX_DEPTH];
|
||||
static u32 clks_exec_pid_stack_depth = 0U;
|
||||
|
||||
static void clks_exec_serial_write_hex64(u64 value) {
|
||||
@@ -163,6 +182,155 @@ static void clks_exec_copy_path(char *dst, usize dst_size, const char *src) {
|
||||
dst[i] = '\0';
|
||||
}
|
||||
|
||||
static void clks_exec_copy_line(char *dst, usize dst_size, const char *src) {
|
||||
usize i = 0U;
|
||||
|
||||
if (dst == CLKS_NULL || dst_size == 0U) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (src == CLKS_NULL) {
|
||||
dst[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
while (src[i] != '\0' && i + 1U < dst_size) {
|
||||
dst[i] = src[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
dst[i] = '\0';
|
||||
}
|
||||
|
||||
static void clks_exec_clear_items(char items[][CLKS_EXEC_ITEM_MAX], u32 max_count) {
|
||||
u32 i;
|
||||
|
||||
for (i = 0U; i < max_count; i++) {
|
||||
items[i][0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
static u32 clks_exec_parse_whitespace_items(const char *line,
|
||||
char items[][CLKS_EXEC_ITEM_MAX],
|
||||
u32 max_count) {
|
||||
u32 count = 0U;
|
||||
usize i = 0U;
|
||||
|
||||
if (line == CLKS_NULL || items == CLKS_NULL || max_count == 0U) {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
while (line[i] != '\0') {
|
||||
usize p = 0U;
|
||||
|
||||
while (line[i] == ' ' || line[i] == '\t' || line[i] == '\r' || line[i] == '\n') {
|
||||
i++;
|
||||
}
|
||||
|
||||
if (line[i] == '\0') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (count >= max_count) {
|
||||
break;
|
||||
}
|
||||
|
||||
while (line[i] != '\0' &&
|
||||
line[i] != ' ' &&
|
||||
line[i] != '\t' &&
|
||||
line[i] != '\r' &&
|
||||
line[i] != '\n') {
|
||||
if (p + 1U < CLKS_EXEC_ITEM_MAX) {
|
||||
items[count][p++] = line[i];
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
items[count][p] = '\0';
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static u32 clks_exec_parse_env_items(const char *line,
|
||||
char items[][CLKS_EXEC_ITEM_MAX],
|
||||
u32 max_count) {
|
||||
u32 count = 0U;
|
||||
usize i = 0U;
|
||||
|
||||
if (line == CLKS_NULL || items == CLKS_NULL || max_count == 0U) {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
while (line[i] != '\0') {
|
||||
usize p = 0U;
|
||||
usize end_trim = 0U;
|
||||
|
||||
while (line[i] == ' ' || line[i] == '\t' || line[i] == ';' || line[i] == '\r' || line[i] == '\n') {
|
||||
i++;
|
||||
}
|
||||
|
||||
if (line[i] == '\0') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (count >= max_count) {
|
||||
break;
|
||||
}
|
||||
|
||||
while (line[i] != '\0' && line[i] != ';' && line[i] != '\r' && line[i] != '\n') {
|
||||
if (p + 1U < CLKS_EXEC_ITEM_MAX) {
|
||||
items[count][p++] = line[i];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
while (p > 0U && (items[count][p - 1U] == ' ' || items[count][p - 1U] == '\t')) {
|
||||
p--;
|
||||
}
|
||||
|
||||
end_trim = p;
|
||||
items[count][end_trim] = '\0';
|
||||
|
||||
if (end_trim > 0U) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static u64 clks_exec_signal_from_vector(u64 vector) {
|
||||
switch (vector) {
|
||||
case 0ULL:
|
||||
case 16ULL:
|
||||
case 19ULL:
|
||||
return 8ULL;
|
||||
case 6ULL:
|
||||
return 4ULL;
|
||||
case 3ULL:
|
||||
return 5ULL;
|
||||
case 14ULL:
|
||||
case 13ULL:
|
||||
case 12ULL:
|
||||
case 11ULL:
|
||||
case 10ULL:
|
||||
case 17ULL:
|
||||
return 11ULL;
|
||||
default:
|
||||
return 6ULL;
|
||||
}
|
||||
}
|
||||
|
||||
static u64 clks_exec_encode_signal_status(u64 signal, u64 vector, u64 error_code) {
|
||||
return CLKS_EXEC_STATUS_SIGNAL_FLAG |
|
||||
(signal & 0xFFULL) |
|
||||
((vector & 0xFFULL) << 8) |
|
||||
((error_code & 0xFFFFULL) << 16);
|
||||
}
|
||||
|
||||
static i32 clks_exec_proc_find_slot_by_pid(u64 pid) {
|
||||
u32 i;
|
||||
|
||||
@@ -225,6 +393,8 @@ static u64 clks_exec_alloc_pid(void) {
|
||||
static struct clks_exec_proc_record *clks_exec_prepare_proc_record(i32 slot,
|
||||
u64 pid,
|
||||
const char *path,
|
||||
const char *argv_line,
|
||||
const char *env_line,
|
||||
enum clks_exec_proc_state state) {
|
||||
struct clks_exec_proc_record *proc;
|
||||
|
||||
@@ -244,10 +414,36 @@ static struct clks_exec_proc_record *clks_exec_prepare_proc_record(i32 slot,
|
||||
proc->exit_status = (u64)-1;
|
||||
proc->tty_index = clks_tty_active();
|
||||
clks_exec_copy_path(proc->path, sizeof(proc->path), path);
|
||||
clks_exec_copy_line(proc->argv_line, sizeof(proc->argv_line), argv_line);
|
||||
clks_exec_copy_line(proc->env_line, sizeof(proc->env_line), env_line);
|
||||
clks_exec_clear_items(proc->argv_items, CLKS_EXEC_MAX_ARGS);
|
||||
clks_exec_clear_items(proc->env_items, CLKS_EXEC_MAX_ENVS);
|
||||
proc->argc = 0U;
|
||||
proc->envc = 0U;
|
||||
proc->last_signal = 0ULL;
|
||||
proc->last_fault_vector = 0ULL;
|
||||
proc->last_fault_error = 0ULL;
|
||||
proc->last_fault_rip = 0ULL;
|
||||
|
||||
if (proc->argc < CLKS_EXEC_MAX_ARGS) {
|
||||
clks_exec_copy_path(proc->argv_items[proc->argc], CLKS_EXEC_ITEM_MAX, path);
|
||||
proc->argc++;
|
||||
}
|
||||
|
||||
if (proc->argv_line[0] != '\0' && proc->argc < CLKS_EXEC_MAX_ARGS) {
|
||||
proc->argc += clks_exec_parse_whitespace_items(proc->argv_line,
|
||||
&proc->argv_items[proc->argc],
|
||||
(u32)(CLKS_EXEC_MAX_ARGS - proc->argc));
|
||||
}
|
||||
|
||||
if (proc->env_line[0] != '\0') {
|
||||
proc->envc = clks_exec_parse_env_items(proc->env_line, proc->env_items, CLKS_EXEC_MAX_ENVS);
|
||||
}
|
||||
|
||||
return proc;
|
||||
}
|
||||
|
||||
static clks_bool clks_exec_invoke_entry(void *entry_ptr, u64 *out_ret) {
|
||||
static clks_bool clks_exec_invoke_entry(void *entry_ptr, u32 depth_index, u64 *out_ret) {
|
||||
if (entry_ptr == CLKS_NULL || out_ret == CLKS_NULL) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
@@ -256,6 +452,7 @@ static clks_bool clks_exec_invoke_entry(void *entry_ptr, u64 *out_ret) {
|
||||
{
|
||||
void *stack_base = clks_kmalloc((usize)CLKS_EXEC_RUN_STACK_BYTES);
|
||||
void *stack_top;
|
||||
u64 unwind_slot;
|
||||
|
||||
if (stack_base == CLKS_NULL) {
|
||||
clks_log(CLKS_LOG_WARN, "EXEC", "RUN STACK ALLOC FAILED");
|
||||
@@ -263,11 +460,17 @@ static clks_bool clks_exec_invoke_entry(void *entry_ptr, u64 *out_ret) {
|
||||
}
|
||||
|
||||
stack_top = (void *)((u8 *)stack_base + (usize)CLKS_EXEC_RUN_STACK_BYTES);
|
||||
unwind_slot = (((u64)stack_top) & ~0xFULL) - 8ULL;
|
||||
clks_exec_unwind_slot_stack[depth_index] = unwind_slot;
|
||||
clks_exec_unwind_slot_valid_stack[depth_index] = CLKS_TRUE;
|
||||
*out_ret = clks_exec_call_on_stack_x86_64(entry_ptr, stack_top);
|
||||
clks_exec_unwind_slot_valid_stack[depth_index] = CLKS_FALSE;
|
||||
clks_exec_unwind_slot_stack[depth_index] = 0ULL;
|
||||
clks_kfree(stack_base);
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
#else
|
||||
(void)depth_index;
|
||||
*out_ret = ((clks_exec_entry_fn)entry_ptr)();
|
||||
return CLKS_TRUE;
|
||||
#endif
|
||||
@@ -364,7 +567,7 @@ static clks_bool clks_exec_run_proc_slot(i32 slot, u64 *out_status) {
|
||||
clks_exec_running_depth++;
|
||||
depth_counted = CLKS_TRUE;
|
||||
|
||||
if (clks_exec_invoke_entry(entry_ptr, &run_ret) == CLKS_FALSE) {
|
||||
if (clks_exec_invoke_entry(entry_ptr, (u32)depth_index, &run_ret) == CLKS_FALSE) {
|
||||
clks_log(CLKS_LOG_WARN, "EXEC", "EXEC RUN INVOKE FAILED");
|
||||
clks_log(CLKS_LOG_WARN, "EXEC", proc->path);
|
||||
goto fail;
|
||||
@@ -450,7 +653,11 @@ static clks_bool clks_exec_dispatch_pending_once(void) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
static clks_bool clks_exec_run_path_internal(const char *path, u64 *out_status, u64 *out_pid) {
|
||||
static clks_bool clks_exec_run_path_internal(const char *path,
|
||||
const char *argv_line,
|
||||
const char *env_line,
|
||||
u64 *out_status,
|
||||
u64 *out_pid) {
|
||||
i32 slot;
|
||||
u64 pid;
|
||||
struct clks_exec_proc_record *proc;
|
||||
@@ -479,7 +686,7 @@ static clks_bool clks_exec_run_path_internal(const char *path, u64 *out_status,
|
||||
}
|
||||
|
||||
pid = clks_exec_alloc_pid();
|
||||
proc = clks_exec_prepare_proc_record(slot, pid, path, CLKS_EXEC_PROC_RUNNING);
|
||||
proc = clks_exec_prepare_proc_record(slot, pid, path, argv_line, env_line, CLKS_EXEC_PROC_RUNNING);
|
||||
|
||||
if (proc == CLKS_NULL) {
|
||||
return CLKS_FALSE;
|
||||
@@ -510,15 +717,21 @@ void clks_exec_init(void) {
|
||||
clks_memset(clks_exec_pid_stack, 0, sizeof(clks_exec_pid_stack));
|
||||
clks_memset(clks_exec_exit_requested_stack, 0, sizeof(clks_exec_exit_requested_stack));
|
||||
clks_memset(clks_exec_exit_status_stack, 0, sizeof(clks_exec_exit_status_stack));
|
||||
clks_memset(clks_exec_unwind_slot_stack, 0, sizeof(clks_exec_unwind_slot_stack));
|
||||
clks_memset(clks_exec_unwind_slot_valid_stack, 0, sizeof(clks_exec_unwind_slot_valid_stack));
|
||||
clks_memset(clks_exec_proc_table, 0, sizeof(clks_exec_proc_table));
|
||||
clks_exec_log_info_serial("PATH EXEC FRAMEWORK ONLINE");
|
||||
}
|
||||
|
||||
clks_bool clks_exec_run_path(const char *path, u64 *out_status) {
|
||||
return clks_exec_run_path_internal(path, out_status, CLKS_NULL);
|
||||
return clks_exec_run_path_internal(path, CLKS_NULL, CLKS_NULL, out_status, CLKS_NULL);
|
||||
}
|
||||
|
||||
clks_bool clks_exec_spawn_path(const char *path, u64 *out_pid) {
|
||||
clks_bool clks_exec_run_pathv(const char *path, const char *argv_line, const char *env_line, u64 *out_status) {
|
||||
return clks_exec_run_path_internal(path, argv_line, env_line, out_status, CLKS_NULL);
|
||||
}
|
||||
|
||||
clks_bool clks_exec_spawn_pathv(const char *path, const char *argv_line, const char *env_line, u64 *out_pid) {
|
||||
i32 slot;
|
||||
u64 pid;
|
||||
struct clks_exec_proc_record *proc;
|
||||
@@ -542,7 +755,7 @@ clks_bool clks_exec_spawn_path(const char *path, u64 *out_pid) {
|
||||
}
|
||||
|
||||
pid = clks_exec_alloc_pid();
|
||||
proc = clks_exec_prepare_proc_record(slot, pid, path, CLKS_EXEC_PROC_PENDING);
|
||||
proc = clks_exec_prepare_proc_record(slot, pid, path, argv_line, env_line, CLKS_EXEC_PROC_PENDING);
|
||||
|
||||
if (proc == CLKS_NULL) {
|
||||
return CLKS_FALSE;
|
||||
@@ -559,6 +772,10 @@ clks_bool clks_exec_spawn_path(const char *path, u64 *out_pid) {
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
clks_bool clks_exec_spawn_path(const char *path, u64 *out_pid) {
|
||||
return clks_exec_spawn_pathv(path, CLKS_NULL, CLKS_NULL, out_pid);
|
||||
}
|
||||
|
||||
u64 clks_exec_wait_pid(u64 pid, u64 *out_status) {
|
||||
i32 slot;
|
||||
struct clks_exec_proc_record *proc;
|
||||
@@ -650,6 +867,159 @@ u32 clks_exec_current_tty(void) {
|
||||
return proc->tty_index;
|
||||
}
|
||||
|
||||
static struct clks_exec_proc_record *clks_exec_current_proc(void) {
|
||||
i32 depth_index = clks_exec_current_depth_index();
|
||||
i32 slot;
|
||||
|
||||
if (depth_index < 0) {
|
||||
return CLKS_NULL;
|
||||
}
|
||||
|
||||
slot = clks_exec_proc_find_slot_by_pid(clks_exec_pid_stack[(u32)depth_index]);
|
||||
|
||||
if (slot < 0) {
|
||||
return CLKS_NULL;
|
||||
}
|
||||
|
||||
if (clks_exec_proc_table[(u32)slot].used == CLKS_FALSE) {
|
||||
return CLKS_NULL;
|
||||
}
|
||||
|
||||
return &clks_exec_proc_table[(u32)slot];
|
||||
}
|
||||
|
||||
u64 clks_exec_current_argc(void) {
|
||||
const struct clks_exec_proc_record *proc = clks_exec_current_proc();
|
||||
|
||||
if (proc == CLKS_NULL) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
return (u64)proc->argc;
|
||||
}
|
||||
|
||||
clks_bool clks_exec_copy_current_argv(u64 index, char *out_value, usize out_size) {
|
||||
const struct clks_exec_proc_record *proc = clks_exec_current_proc();
|
||||
|
||||
if (proc == CLKS_NULL || out_value == CLKS_NULL || out_size == 0U) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (index >= (u64)proc->argc || index >= CLKS_EXEC_MAX_ARGS) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
clks_exec_copy_line(out_value, out_size, proc->argv_items[(u32)index]);
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
u64 clks_exec_current_envc(void) {
|
||||
const struct clks_exec_proc_record *proc = clks_exec_current_proc();
|
||||
|
||||
if (proc == CLKS_NULL) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
return (u64)proc->envc;
|
||||
}
|
||||
|
||||
clks_bool clks_exec_copy_current_env(u64 index, char *out_value, usize out_size) {
|
||||
const struct clks_exec_proc_record *proc = clks_exec_current_proc();
|
||||
|
||||
if (proc == CLKS_NULL || out_value == CLKS_NULL || out_size == 0U) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (index >= (u64)proc->envc || index >= CLKS_EXEC_MAX_ENVS) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
clks_exec_copy_line(out_value, out_size, proc->env_items[(u32)index]);
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
u64 clks_exec_current_signal(void) {
|
||||
const struct clks_exec_proc_record *proc = clks_exec_current_proc();
|
||||
return (proc != CLKS_NULL) ? proc->last_signal : 0ULL;
|
||||
}
|
||||
|
||||
u64 clks_exec_current_fault_vector(void) {
|
||||
const struct clks_exec_proc_record *proc = clks_exec_current_proc();
|
||||
return (proc != CLKS_NULL) ? proc->last_fault_vector : 0ULL;
|
||||
}
|
||||
|
||||
u64 clks_exec_current_fault_error(void) {
|
||||
const struct clks_exec_proc_record *proc = clks_exec_current_proc();
|
||||
return (proc != CLKS_NULL) ? proc->last_fault_error : 0ULL;
|
||||
}
|
||||
|
||||
u64 clks_exec_current_fault_rip(void) {
|
||||
const struct clks_exec_proc_record *proc = clks_exec_current_proc();
|
||||
return (proc != CLKS_NULL) ? proc->last_fault_rip : 0ULL;
|
||||
}
|
||||
|
||||
clks_bool clks_exec_handle_exception(u64 vector,
|
||||
u64 error_code,
|
||||
u64 rip,
|
||||
u64 *io_rip,
|
||||
u64 *io_rdi,
|
||||
u64 *io_rsi) {
|
||||
i32 depth_index;
|
||||
struct clks_exec_proc_record *proc;
|
||||
u64 signal;
|
||||
u64 status;
|
||||
|
||||
if (clks_exec_is_running() == CLKS_FALSE || clks_exec_current_path_is_user() == CLKS_FALSE) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
depth_index = clks_exec_current_depth_index();
|
||||
proc = clks_exec_current_proc();
|
||||
|
||||
if (depth_index < 0 || proc == CLKS_NULL) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
signal = clks_exec_signal_from_vector(vector);
|
||||
status = clks_exec_encode_signal_status(signal, vector, error_code);
|
||||
|
||||
proc->last_signal = signal;
|
||||
proc->last_fault_vector = vector;
|
||||
proc->last_fault_error = error_code;
|
||||
proc->last_fault_rip = rip;
|
||||
|
||||
clks_exec_exit_requested_stack[(u32)depth_index] = CLKS_TRUE;
|
||||
clks_exec_exit_status_stack[(u32)depth_index] = status;
|
||||
|
||||
clks_exec_log_info_serial("USER EXCEPTION CAPTURED");
|
||||
clks_exec_log_info_serial(proc->path);
|
||||
clks_exec_log_hex_serial("PID", proc->pid);
|
||||
clks_exec_log_hex_serial("SIGNAL", signal);
|
||||
clks_exec_log_hex_serial("VECTOR", vector);
|
||||
clks_exec_log_hex_serial("ERROR", error_code);
|
||||
clks_exec_log_hex_serial("RIP", rip);
|
||||
|
||||
#if defined(CLKS_ARCH_X86_64)
|
||||
if (io_rip == CLKS_NULL || io_rdi == CLKS_NULL || io_rsi == CLKS_NULL) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (clks_exec_unwind_slot_valid_stack[(u32)depth_index] == CLKS_FALSE) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
*io_rip = (u64)clks_exec_abort_to_caller_x86_64;
|
||||
*io_rdi = clks_exec_unwind_slot_stack[(u32)depth_index];
|
||||
*io_rsi = status;
|
||||
return CLKS_TRUE;
|
||||
#else
|
||||
(void)io_rip;
|
||||
(void)io_rdi;
|
||||
(void)io_rsi;
|
||||
return CLKS_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
u64 clks_exec_sleep_ticks(u64 ticks) {
|
||||
u64 start = clks_interrupts_timer_ticks();
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <clks/compiler.h>
|
||||
#include <clks/cpu.h>
|
||||
#include <clks/exec.h>
|
||||
#include <clks/interrupts.h>
|
||||
#include <clks/log.h>
|
||||
#include <clks/keyboard.h>
|
||||
@@ -250,6 +251,15 @@ void clks_interrupt_dispatch(struct clks_interrupt_frame *frame) {
|
||||
}
|
||||
|
||||
if (vector < 32U) {
|
||||
if (clks_exec_handle_exception(vector,
|
||||
frame->error_code,
|
||||
frame->rip,
|
||||
&frame->rip,
|
||||
&frame->rdi,
|
||||
&frame->rsi) == CLKS_TRUE) {
|
||||
return;
|
||||
}
|
||||
|
||||
clks_panic_exception(clks_exception_names[vector], vector, frame->error_code, frame->rip);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
#define CLKS_SYSCALL_TTY_MAX_LEN 512U
|
||||
#define CLKS_SYSCALL_FS_IO_MAX_LEN 65536U
|
||||
#define CLKS_SYSCALL_JOURNAL_MAX_LEN 256U
|
||||
#define CLKS_SYSCALL_ARG_LINE_MAX 256U
|
||||
#define CLKS_SYSCALL_ENV_LINE_MAX 512U
|
||||
#define CLKS_SYSCALL_ITEM_MAX 128U
|
||||
#define CLKS_SYSCALL_USER_TRACE_BUDGET 128ULL
|
||||
|
||||
struct clks_syscall_frame {
|
||||
@@ -87,6 +90,19 @@ static clks_bool clks_syscall_copy_user_string(u64 src_addr, char *dst, usize ds
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
static clks_bool clks_syscall_copy_user_optional_string(u64 src_addr, char *dst, usize dst_size) {
|
||||
if (dst == CLKS_NULL || dst_size == 0U) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (src_addr == 0ULL) {
|
||||
dst[0] = '\0';
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
return clks_syscall_copy_user_string(src_addr, dst, dst_size);
|
||||
}
|
||||
|
||||
static u64 clks_syscall_log_write(u64 arg0, u64 arg1) {
|
||||
const char *src = (const char *)arg0;
|
||||
u64 len = arg1;
|
||||
@@ -218,6 +234,31 @@ static u64 clks_syscall_exec_path(u64 arg0) {
|
||||
return status;
|
||||
}
|
||||
|
||||
static u64 clks_syscall_exec_pathv(u64 arg0, u64 arg1, u64 arg2) {
|
||||
char path[CLKS_SYSCALL_PATH_MAX];
|
||||
char argv_line[CLKS_SYSCALL_ARG_LINE_MAX];
|
||||
char env_line[CLKS_SYSCALL_ENV_LINE_MAX];
|
||||
u64 status = (u64)-1;
|
||||
|
||||
if (clks_syscall_copy_user_string(arg0, path, sizeof(path)) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (clks_syscall_copy_user_optional_string(arg1, argv_line, sizeof(argv_line)) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (clks_syscall_copy_user_optional_string(arg2, env_line, sizeof(env_line)) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (clks_exec_run_pathv(path, argv_line, env_line, &status) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static u64 clks_syscall_getpid(void) {
|
||||
return clks_exec_current_pid();
|
||||
}
|
||||
@@ -237,6 +278,31 @@ static u64 clks_syscall_spawn_path(u64 arg0) {
|
||||
return pid;
|
||||
}
|
||||
|
||||
static u64 clks_syscall_spawn_pathv(u64 arg0, u64 arg1, u64 arg2) {
|
||||
char path[CLKS_SYSCALL_PATH_MAX];
|
||||
char argv_line[CLKS_SYSCALL_ARG_LINE_MAX];
|
||||
char env_line[CLKS_SYSCALL_ENV_LINE_MAX];
|
||||
u64 pid = (u64)-1;
|
||||
|
||||
if (clks_syscall_copy_user_string(arg0, path, sizeof(path)) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (clks_syscall_copy_user_optional_string(arg1, argv_line, sizeof(argv_line)) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (clks_syscall_copy_user_optional_string(arg2, env_line, sizeof(env_line)) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (clks_exec_spawn_pathv(path, argv_line, env_line, &pid) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
static u64 clks_syscall_waitpid(u64 arg0, u64 arg1) {
|
||||
u64 status = (u64)-1;
|
||||
u64 wait_ret = clks_exec_wait_pid(arg0, &status);
|
||||
@@ -248,6 +314,54 @@ static u64 clks_syscall_waitpid(u64 arg0, u64 arg1) {
|
||||
return wait_ret;
|
||||
}
|
||||
|
||||
static u64 clks_syscall_proc_argc(void) {
|
||||
return clks_exec_current_argc();
|
||||
}
|
||||
|
||||
static u64 clks_syscall_proc_argv(u64 arg0, u64 arg1, u64 arg2) {
|
||||
if (arg1 == 0ULL || arg2 == 0ULL) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (arg2 > CLKS_SYSCALL_ITEM_MAX) {
|
||||
arg2 = CLKS_SYSCALL_ITEM_MAX;
|
||||
}
|
||||
|
||||
return (clks_exec_copy_current_argv(arg0, (char *)arg1, (usize)arg2) == CLKS_TRUE) ? 1ULL : 0ULL;
|
||||
}
|
||||
|
||||
static u64 clks_syscall_proc_envc(void) {
|
||||
return clks_exec_current_envc();
|
||||
}
|
||||
|
||||
static u64 clks_syscall_proc_env(u64 arg0, u64 arg1, u64 arg2) {
|
||||
if (arg1 == 0ULL || arg2 == 0ULL) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (arg2 > CLKS_SYSCALL_ITEM_MAX) {
|
||||
arg2 = CLKS_SYSCALL_ITEM_MAX;
|
||||
}
|
||||
|
||||
return (clks_exec_copy_current_env(arg0, (char *)arg1, (usize)arg2) == CLKS_TRUE) ? 1ULL : 0ULL;
|
||||
}
|
||||
|
||||
static u64 clks_syscall_proc_last_signal(void) {
|
||||
return clks_exec_current_signal();
|
||||
}
|
||||
|
||||
static u64 clks_syscall_proc_fault_vector(void) {
|
||||
return clks_exec_current_fault_vector();
|
||||
}
|
||||
|
||||
static u64 clks_syscall_proc_fault_error(void) {
|
||||
return clks_exec_current_fault_error();
|
||||
}
|
||||
|
||||
static u64 clks_syscall_proc_fault_rip(void) {
|
||||
return clks_exec_current_fault_rip();
|
||||
}
|
||||
|
||||
static u64 clks_syscall_exit(u64 arg0) {
|
||||
return (clks_exec_request_exit(arg0) == CLKS_TRUE) ? 1ULL : 0ULL;
|
||||
}
|
||||
@@ -530,6 +644,8 @@ u64 clks_syscall_dispatch(void *frame_ptr) {
|
||||
return clks_syscall_fs_read(frame->rbx, frame->rcx, frame->rdx);
|
||||
case CLKS_SYSCALL_EXEC_PATH:
|
||||
return clks_syscall_exec_path(frame->rbx);
|
||||
case CLKS_SYSCALL_EXEC_PATHV:
|
||||
return clks_syscall_exec_pathv(frame->rbx, frame->rcx, frame->rdx);
|
||||
case CLKS_SYSCALL_EXEC_REQUESTS:
|
||||
return clks_exec_request_count();
|
||||
case CLKS_SYSCALL_EXEC_SUCCESS:
|
||||
@@ -587,8 +703,26 @@ u64 clks_syscall_dispatch(void *frame_ptr) {
|
||||
return clks_syscall_getpid();
|
||||
case CLKS_SYSCALL_SPAWN_PATH:
|
||||
return clks_syscall_spawn_path(frame->rbx);
|
||||
case CLKS_SYSCALL_SPAWN_PATHV:
|
||||
return clks_syscall_spawn_pathv(frame->rbx, frame->rcx, frame->rdx);
|
||||
case CLKS_SYSCALL_WAITPID:
|
||||
return clks_syscall_waitpid(frame->rbx, frame->rcx);
|
||||
case CLKS_SYSCALL_PROC_ARGC:
|
||||
return clks_syscall_proc_argc();
|
||||
case CLKS_SYSCALL_PROC_ARGV:
|
||||
return clks_syscall_proc_argv(frame->rbx, frame->rcx, frame->rdx);
|
||||
case CLKS_SYSCALL_PROC_ENVC:
|
||||
return clks_syscall_proc_envc();
|
||||
case CLKS_SYSCALL_PROC_ENV:
|
||||
return clks_syscall_proc_env(frame->rbx, frame->rcx, frame->rdx);
|
||||
case CLKS_SYSCALL_PROC_LAST_SIGNAL:
|
||||
return clks_syscall_proc_last_signal();
|
||||
case CLKS_SYSCALL_PROC_FAULT_VECTOR:
|
||||
return clks_syscall_proc_fault_vector();
|
||||
case CLKS_SYSCALL_PROC_FAULT_ERROR:
|
||||
return clks_syscall_proc_fault_error();
|
||||
case CLKS_SYSCALL_PROC_FAULT_RIP:
|
||||
return clks_syscall_proc_fault_rip();
|
||||
case CLKS_SYSCALL_EXIT:
|
||||
return clks_syscall_exit(frame->rbx);
|
||||
case CLKS_SYSCALL_SLEEP_TICKS:
|
||||
|
||||
Reference in New Issue
Block a user