mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-21 10:40:00 +00:00
动态链接库+修复神秘光标问题
This commit is contained in:
48
cleonos/c/apps/dltest_main.c
Normal file
48
cleonos/c/apps/dltest_main.c
Normal file
@@ -0,0 +1,48 @@
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef unsigned long long u64;
|
||||
typedef u64 (*dl_math2_fn)(u64, u64);
|
||||
typedef u64 (*dl_void_fn)(void);
|
||||
|
||||
int cleonos_app_main(int argc, char **argv, char **envp) {
|
||||
const char *lib_path = "/shell/libdemo.elf";
|
||||
void *handle;
|
||||
dl_math2_fn add_fn;
|
||||
dl_math2_fn mul_fn;
|
||||
dl_void_fn hello_fn;
|
||||
|
||||
(void)envp;
|
||||
|
||||
if (argc > 1 && argv != (char **)0 && argv[1] != (char *)0 && argv[1][0] != '\0') {
|
||||
lib_path = argv[1];
|
||||
}
|
||||
|
||||
handle = dlopen(lib_path, 0);
|
||||
if (handle == (void *)0) {
|
||||
(void)printf("[dltest] dlopen failed: %s\n", lib_path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
add_fn = (dl_math2_fn)dlsym(handle, "cleonos_libdemo_add");
|
||||
mul_fn = (dl_math2_fn)dlsym(handle, "cleonos_libdemo_mul");
|
||||
hello_fn = (dl_void_fn)dlsym(handle, "cleonos_libdemo_hello");
|
||||
|
||||
if (add_fn == (dl_math2_fn)0 || mul_fn == (dl_math2_fn)0 || hello_fn == (dl_void_fn)0) {
|
||||
(void)puts("[dltest] dlsym failed");
|
||||
(void)dlclose(handle);
|
||||
return 2;
|
||||
}
|
||||
|
||||
(void)hello_fn();
|
||||
(void)printf("[dltest] add(7, 35) = %llu\n", add_fn(7ULL, 35ULL));
|
||||
(void)printf("[dltest] mul(6, 9) = %llu\n", mul_fn(6ULL, 9ULL));
|
||||
|
||||
if (dlclose(handle) != 0) {
|
||||
(void)puts("[dltest] dlclose failed");
|
||||
return 3;
|
||||
}
|
||||
|
||||
(void)puts("[dltest] PASS");
|
||||
return 0;
|
||||
}
|
||||
24
cleonos/c/apps/libdemo_main.c
Normal file
24
cleonos/c/apps/libdemo_main.c
Normal file
@@ -0,0 +1,24 @@
|
||||
#include <stdio.h>
|
||||
|
||||
typedef unsigned long long u64;
|
||||
|
||||
u64 cleonos_libdemo_add(u64 left, u64 right) {
|
||||
return left + right;
|
||||
}
|
||||
|
||||
u64 cleonos_libdemo_mul(u64 left, u64 right) {
|
||||
return left * right;
|
||||
}
|
||||
|
||||
u64 cleonos_libdemo_hello(void) {
|
||||
(void)puts("[libdemo] hello from libdemo.elf");
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
int cleonos_app_main(int argc, char **argv, char **envp) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
(void)envp;
|
||||
(void)puts("[libdemo] dynamic library image ready");
|
||||
return 0;
|
||||
}
|
||||
@@ -119,6 +119,9 @@ typedef struct cleonos_proc_snapshot {
|
||||
#define CLEONOS_SYSCALL_FD_WRITE 74ULL
|
||||
#define CLEONOS_SYSCALL_FD_CLOSE 75ULL
|
||||
#define CLEONOS_SYSCALL_FD_DUP 76ULL
|
||||
#define CLEONOS_SYSCALL_DL_OPEN 77ULL
|
||||
#define CLEONOS_SYSCALL_DL_CLOSE 78ULL
|
||||
#define CLEONOS_SYSCALL_DL_SYM 79ULL
|
||||
|
||||
u64 cleonos_syscall(u64 id, u64 arg0, u64 arg1, u64 arg2);
|
||||
u64 cleonos_sys_log_write(const char *message, u64 length);
|
||||
@@ -197,5 +200,8 @@ u64 cleonos_sys_fd_read(u64 fd, void *out_buffer, u64 size);
|
||||
u64 cleonos_sys_fd_write(u64 fd, const void *buffer, u64 size);
|
||||
u64 cleonos_sys_fd_close(u64 fd);
|
||||
u64 cleonos_sys_fd_dup(u64 fd);
|
||||
u64 cleonos_sys_dl_open(const char *path);
|
||||
u64 cleonos_sys_dl_close(u64 handle);
|
||||
u64 cleonos_sys_dl_sym(u64 handle, const char *symbol);
|
||||
|
||||
#endif
|
||||
|
||||
8
cleonos/c/include/dlfcn.h
Normal file
8
cleonos/c/include/dlfcn.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef CLEONOS_LIBC_DLFCN_H
|
||||
#define CLEONOS_LIBC_DLFCN_H
|
||||
|
||||
void *dlopen(const char *path, int flags);
|
||||
void *dlsym(void *handle, const char *symbol);
|
||||
int dlclose(void *handle);
|
||||
|
||||
#endif
|
||||
48
cleonos/c/src/dlfcn.c
Normal file
48
cleonos/c/src/dlfcn.c
Normal file
@@ -0,0 +1,48 @@
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <cleonos_syscall.h>
|
||||
|
||||
void *dlopen(const char *path, int flags) {
|
||||
u64 handle;
|
||||
|
||||
(void)flags;
|
||||
|
||||
if (path == (const char *)0 || path[0] == '\0') {
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
handle = cleonos_sys_dl_open(path);
|
||||
|
||||
if (handle == 0ULL || handle == (u64)-1) {
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
return (void *)handle;
|
||||
}
|
||||
|
||||
void *dlsym(void *handle, const char *symbol) {
|
||||
u64 addr;
|
||||
|
||||
if (handle == (void *)0 || symbol == (const char *)0 || symbol[0] == '\0') {
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
addr = cleonos_sys_dl_sym((u64)handle, symbol);
|
||||
|
||||
if (addr == 0ULL || addr == (u64)-1) {
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
return (void *)addr;
|
||||
}
|
||||
|
||||
int dlclose(void *handle) {
|
||||
u64 rc;
|
||||
|
||||
if (handle == (void *)0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = cleonos_sys_dl_close((u64)handle);
|
||||
return (rc == (u64)-1) ? -1 : 0;
|
||||
}
|
||||
@@ -330,3 +330,15 @@ u64 cleonos_sys_fd_close(u64 fd) {
|
||||
u64 cleonos_sys_fd_dup(u64 fd) {
|
||||
return cleonos_syscall(CLEONOS_SYSCALL_FD_DUP, fd, 0ULL, 0ULL);
|
||||
}
|
||||
|
||||
u64 cleonos_sys_dl_open(const char *path) {
|
||||
return cleonos_syscall(CLEONOS_SYSCALL_DL_OPEN, (u64)path, 0ULL, 0ULL);
|
||||
}
|
||||
|
||||
u64 cleonos_sys_dl_close(u64 handle) {
|
||||
return cleonos_syscall(CLEONOS_SYSCALL_DL_CLOSE, handle, 0ULL, 0ULL);
|
||||
}
|
||||
|
||||
u64 cleonos_sys_dl_sym(u64 handle, const char *symbol) {
|
||||
return cleonos_syscall(CLEONOS_SYSCALL_DL_SYM, handle, (u64)symbol, 0ULL);
|
||||
}
|
||||
|
||||
@@ -45,6 +45,9 @@ u64 clks_exec_fd_read(u64 fd, void *out_buffer, u64 size);
|
||||
u64 clks_exec_fd_write(u64 fd, const void *buffer, u64 size);
|
||||
u64 clks_exec_fd_close(u64 fd);
|
||||
u64 clks_exec_fd_dup(u64 fd);
|
||||
u64 clks_exec_dl_open(const char *path);
|
||||
u64 clks_exec_dl_close(u64 handle);
|
||||
u64 clks_exec_dl_sym(u64 handle, const char *symbol);
|
||||
u64 clks_exec_current_pid(void);
|
||||
u32 clks_exec_current_tty(void);
|
||||
u64 clks_exec_current_argc(void);
|
||||
|
||||
@@ -80,6 +80,9 @@
|
||||
#define CLKS_SYSCALL_FD_WRITE 74ULL
|
||||
#define CLKS_SYSCALL_FD_CLOSE 75ULL
|
||||
#define CLKS_SYSCALL_FD_DUP 76ULL
|
||||
#define CLKS_SYSCALL_DL_OPEN 77ULL
|
||||
#define CLKS_SYSCALL_DL_CLOSE 78ULL
|
||||
#define CLKS_SYSCALL_DL_SYM 79ULL
|
||||
|
||||
void clks_syscall_init(void);
|
||||
u64 clks_syscall_dispatch(void *frame_ptr);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
void clks_tty_init(void);
|
||||
void clks_tty_write(const char *text);
|
||||
void clks_tty_write_n(const char *text, usize len);
|
||||
void clks_tty_write_char(char ch);
|
||||
void clks_tty_switch(u32 tty_index);
|
||||
void clks_tty_tick(u64 tick);
|
||||
|
||||
@@ -34,6 +34,21 @@ typedef u64 (*clks_exec_entry_fn)(void);
|
||||
#define CLKS_EXEC_O_CREAT 0x0040ULL
|
||||
#define CLKS_EXEC_O_TRUNC 0x0200ULL
|
||||
#define CLKS_EXEC_O_APPEND 0x0400ULL
|
||||
#define CLKS_EXEC_DYNLIB_MAX 32U
|
||||
|
||||
#define CLKS_EXEC_ELF64_MAGIC_0 0x7FU
|
||||
#define CLKS_EXEC_ELF64_MAGIC_1 'E'
|
||||
#define CLKS_EXEC_ELF64_MAGIC_2 'L'
|
||||
#define CLKS_EXEC_ELF64_MAGIC_3 'F'
|
||||
#define CLKS_EXEC_ELF64_CLASS_64 2U
|
||||
#define CLKS_EXEC_ELF64_DATA_LSB 1U
|
||||
#define CLKS_EXEC_ELF64_VERSION 1U
|
||||
|
||||
#define CLKS_EXEC_ELF64_SHT_SYMTAB 2U
|
||||
#define CLKS_EXEC_ELF64_SHT_DYNSYM 11U
|
||||
#define CLKS_EXEC_ELF64_SHN_UNDEF 0U
|
||||
#define CLKS_EXEC_ELF64_STT_NOTYPE 0U
|
||||
#define CLKS_EXEC_ELF64_STT_FUNC 2U
|
||||
|
||||
enum clks_exec_fd_kind {
|
||||
CLKS_EXEC_FD_KIND_NONE = 0,
|
||||
@@ -84,6 +99,56 @@ struct clks_exec_proc_record {
|
||||
struct clks_exec_fd_entry fds[CLKS_EXEC_FD_MAX];
|
||||
};
|
||||
|
||||
struct clks_exec_elf64_ehdr {
|
||||
u8 e_ident[16];
|
||||
u16 e_type;
|
||||
u16 e_machine;
|
||||
u32 e_version;
|
||||
u64 e_entry;
|
||||
u64 e_phoff;
|
||||
u64 e_shoff;
|
||||
u32 e_flags;
|
||||
u16 e_ehsize;
|
||||
u16 e_phentsize;
|
||||
u16 e_phnum;
|
||||
u16 e_shentsize;
|
||||
u16 e_shnum;
|
||||
u16 e_shstrndx;
|
||||
};
|
||||
|
||||
struct clks_exec_elf64_shdr {
|
||||
u32 sh_name;
|
||||
u32 sh_type;
|
||||
u64 sh_flags;
|
||||
u64 sh_addr;
|
||||
u64 sh_offset;
|
||||
u64 sh_size;
|
||||
u32 sh_link;
|
||||
u32 sh_info;
|
||||
u64 sh_addralign;
|
||||
u64 sh_entsize;
|
||||
};
|
||||
|
||||
struct clks_exec_elf64_sym {
|
||||
u32 st_name;
|
||||
u8 st_info;
|
||||
u8 st_other;
|
||||
u16 st_shndx;
|
||||
u64 st_value;
|
||||
u64 st_size;
|
||||
};
|
||||
|
||||
struct clks_exec_dynlib_slot {
|
||||
clks_bool used;
|
||||
u64 handle;
|
||||
u64 owner_pid;
|
||||
u64 ref_count;
|
||||
char path[CLKS_EXEC_PATH_MAX];
|
||||
const void *file_image;
|
||||
u64 file_size;
|
||||
struct clks_elf64_loaded_image loaded;
|
||||
};
|
||||
|
||||
#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);
|
||||
@@ -105,6 +170,8 @@ static clks_bool clks_exec_unwind_slot_valid_stack[CLKS_EXEC_MAX_DEPTH];
|
||||
static u64 clks_exec_image_begin_stack[CLKS_EXEC_MAX_DEPTH];
|
||||
static u64 clks_exec_image_end_stack[CLKS_EXEC_MAX_DEPTH];
|
||||
static u32 clks_exec_pid_stack_depth = 0U;
|
||||
static struct clks_exec_dynlib_slot clks_exec_dynlib_table[CLKS_EXEC_DYNLIB_MAX];
|
||||
static u64 clks_exec_next_dynlib_handle = 1ULL;
|
||||
|
||||
static struct clks_exec_proc_record *clks_exec_current_proc(void);
|
||||
|
||||
@@ -263,6 +330,267 @@ static void clks_exec_copy_line(char *dst, usize dst_size, const char *src) {
|
||||
dst[i] = '\0';
|
||||
}
|
||||
|
||||
static clks_bool clks_exec_range_ok(u64 off, u64 len, u64 total) {
|
||||
if (off > total) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (len > (total - off)) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
static i32 clks_exec_dynlib_alloc_slot(void) {
|
||||
u32 i;
|
||||
|
||||
for (i = 0U; i < CLKS_EXEC_DYNLIB_MAX; i++) {
|
||||
if (clks_exec_dynlib_table[i].used == CLKS_FALSE) {
|
||||
return (i32)i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static i32 clks_exec_dynlib_find_by_handle(u64 handle) {
|
||||
u32 i;
|
||||
|
||||
for (i = 0U; i < CLKS_EXEC_DYNLIB_MAX; i++) {
|
||||
if (clks_exec_dynlib_table[i].used == CLKS_TRUE && clks_exec_dynlib_table[i].handle == handle) {
|
||||
return (i32)i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static i32 clks_exec_dynlib_find_by_owner_path(u64 owner_pid, const char *path) {
|
||||
u32 i;
|
||||
|
||||
if (path == CLKS_NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0U; i < CLKS_EXEC_DYNLIB_MAX; i++) {
|
||||
if (clks_exec_dynlib_table[i].used != CLKS_TRUE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (clks_exec_dynlib_table[i].owner_pid == owner_pid &&
|
||||
clks_strcmp(clks_exec_dynlib_table[i].path, path) == 0) {
|
||||
return (i32)i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static u64 clks_exec_dynlib_alloc_handle(void) {
|
||||
u64 handle = clks_exec_next_dynlib_handle;
|
||||
|
||||
clks_exec_next_dynlib_handle++;
|
||||
if (clks_exec_next_dynlib_handle == 0ULL) {
|
||||
clks_exec_next_dynlib_handle = 1ULL;
|
||||
}
|
||||
|
||||
if (handle == 0ULL) {
|
||||
handle = clks_exec_next_dynlib_handle;
|
||||
clks_exec_next_dynlib_handle++;
|
||||
if (clks_exec_next_dynlib_handle == 0ULL) {
|
||||
clks_exec_next_dynlib_handle = 1ULL;
|
||||
}
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
static void clks_exec_dynlib_slot_reset(struct clks_exec_dynlib_slot *slot) {
|
||||
if (slot == CLKS_NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (slot->used == CLKS_TRUE && slot->loaded.image_base != CLKS_NULL) {
|
||||
clks_elf64_unload(&slot->loaded);
|
||||
}
|
||||
|
||||
clks_memset(slot, 0, sizeof(*slot));
|
||||
}
|
||||
|
||||
static void clks_exec_dynlib_release_owner(u64 owner_pid) {
|
||||
u32 i;
|
||||
|
||||
if (owner_pid == 0ULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0U; i < CLKS_EXEC_DYNLIB_MAX; i++) {
|
||||
if (clks_exec_dynlib_table[i].used == CLKS_TRUE &&
|
||||
clks_exec_dynlib_table[i].owner_pid == owner_pid) {
|
||||
clks_exec_dynlib_slot_reset(&clks_exec_dynlib_table[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static clks_bool clks_exec_dynlib_elf_header_ok(const struct clks_exec_elf64_ehdr *eh) {
|
||||
if (eh == CLKS_NULL) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (eh->e_ident[0] != CLKS_EXEC_ELF64_MAGIC_0 ||
|
||||
eh->e_ident[1] != CLKS_EXEC_ELF64_MAGIC_1 ||
|
||||
eh->e_ident[2] != CLKS_EXEC_ELF64_MAGIC_2 ||
|
||||
eh->e_ident[3] != CLKS_EXEC_ELF64_MAGIC_3) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (eh->e_ident[4] != CLKS_EXEC_ELF64_CLASS_64 || eh->e_ident[5] != CLKS_EXEC_ELF64_DATA_LSB) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (eh->e_ident[6] != CLKS_EXEC_ELF64_VERSION || eh->e_version != CLKS_EXEC_ELF64_VERSION) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
if (eh->e_shentsize != sizeof(struct clks_exec_elf64_shdr)) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
|
||||
static clks_bool clks_exec_dynlib_symbol_name_ptr(const char *strtab,
|
||||
u64 strtab_size,
|
||||
u32 st_name,
|
||||
const char **out_name) {
|
||||
u64 i;
|
||||
|
||||
if (out_name != CLKS_NULL) {
|
||||
*out_name = CLKS_NULL;
|
||||
}
|
||||
|
||||
if (strtab == CLKS_NULL || out_name == CLKS_NULL || st_name >= strtab_size) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
for (i = (u64)st_name; i < strtab_size; i++) {
|
||||
if (strtab[i] == '\0') {
|
||||
*out_name = &strtab[st_name];
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
static clks_bool clks_exec_dynlib_resolve_symbol(const struct clks_exec_dynlib_slot *slot,
|
||||
const char *symbol,
|
||||
u64 *out_addr) {
|
||||
const struct clks_exec_elf64_ehdr *eh;
|
||||
const struct clks_exec_elf64_shdr *shdrs;
|
||||
const u8 *image;
|
||||
u64 i;
|
||||
u64 sh_table_size;
|
||||
|
||||
if (out_addr != CLKS_NULL) {
|
||||
*out_addr = 0ULL;
|
||||
}
|
||||
|
||||
if (slot == CLKS_NULL || slot->used != CLKS_TRUE || symbol == CLKS_NULL || symbol[0] == '\0' ||
|
||||
out_addr == CLKS_NULL) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
image = (const u8 *)slot->file_image;
|
||||
|
||||
if (image == CLKS_NULL || slot->file_size < sizeof(struct clks_exec_elf64_ehdr)) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
eh = (const struct clks_exec_elf64_ehdr *)image;
|
||||
|
||||
if (clks_exec_dynlib_elf_header_ok(eh) == CLKS_FALSE || eh->e_shnum == 0U || eh->e_shoff == 0ULL) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
sh_table_size = (u64)eh->e_shnum * (u64)eh->e_shentsize;
|
||||
if (clks_exec_range_ok(eh->e_shoff, sh_table_size, slot->file_size) == CLKS_FALSE) {
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
shdrs = (const struct clks_exec_elf64_shdr *)(image + (usize)eh->e_shoff);
|
||||
|
||||
for (i = 0ULL; i < (u64)eh->e_shnum; i++) {
|
||||
const struct clks_exec_elf64_shdr *symtab = &shdrs[i];
|
||||
const struct clks_exec_elf64_shdr *strtab;
|
||||
const struct clks_exec_elf64_sym *symbols;
|
||||
const char *strings;
|
||||
u64 sym_count;
|
||||
u64 j;
|
||||
|
||||
if (symtab->sh_type != CLKS_EXEC_ELF64_SHT_SYMTAB && symtab->sh_type != CLKS_EXEC_ELF64_SHT_DYNSYM) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (symtab->sh_entsize != sizeof(struct clks_exec_elf64_sym) || symtab->sh_link >= eh->e_shnum ||
|
||||
symtab->sh_size < symtab->sh_entsize) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (clks_exec_range_ok(symtab->sh_offset, symtab->sh_size, slot->file_size) == CLKS_FALSE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
strtab = &shdrs[symtab->sh_link];
|
||||
if (clks_exec_range_ok(strtab->sh_offset, strtab->sh_size, slot->file_size) == CLKS_FALSE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
symbols = (const struct clks_exec_elf64_sym *)(image + (usize)symtab->sh_offset);
|
||||
strings = (const char *)(image + (usize)strtab->sh_offset);
|
||||
sym_count = symtab->sh_size / symtab->sh_entsize;
|
||||
|
||||
for (j = 0ULL; j < sym_count; j++) {
|
||||
const struct clks_exec_elf64_sym *sym = &symbols[j];
|
||||
const char *name_ptr;
|
||||
u8 symbol_type;
|
||||
u64 offset;
|
||||
|
||||
if (sym->st_name == 0U || sym->st_shndx == CLKS_EXEC_ELF64_SHN_UNDEF || sym->st_value == 0ULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
symbol_type = (u8)(sym->st_info & 0x0FU);
|
||||
if (symbol_type != CLKS_EXEC_ELF64_STT_FUNC && symbol_type != CLKS_EXEC_ELF64_STT_NOTYPE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (clks_exec_dynlib_symbol_name_ptr(strings, strtab->sh_size, sym->st_name, &name_ptr) == CLKS_FALSE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (clks_strcmp(name_ptr, symbol) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sym->st_value < slot->loaded.image_vaddr_base) {
|
||||
continue;
|
||||
}
|
||||
|
||||
offset = sym->st_value - slot->loaded.image_vaddr_base;
|
||||
if (offset >= slot->loaded.image_size) {
|
||||
continue;
|
||||
}
|
||||
|
||||
*out_addr = (u64)((u8 *)slot->loaded.image_base + (usize)offset);
|
||||
return CLKS_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return CLKS_FALSE;
|
||||
}
|
||||
|
||||
static void clks_exec_clear_items(char items[][CLKS_EXEC_ITEM_MAX], u32 max_count) {
|
||||
u32 i;
|
||||
|
||||
@@ -931,6 +1259,8 @@ static clks_bool clks_exec_run_proc_slot(i32 slot, u64 *out_status) {
|
||||
clks_exec_proc_mark_exited(proc, clks_interrupts_timer_ticks(), run_ret);
|
||||
}
|
||||
|
||||
clks_exec_dynlib_release_owner(proc->pid);
|
||||
|
||||
if (depth_pushed == CLKS_TRUE && clks_exec_pid_stack_depth > 0U) {
|
||||
clks_exec_stop_requested_stack[(u32)depth_index] = CLKS_FALSE;
|
||||
clks_exec_image_begin_stack[(u32)depth_index] = 0ULL;
|
||||
@@ -955,6 +1285,7 @@ fail:
|
||||
}
|
||||
|
||||
clks_exec_proc_mark_exited(proc, clks_interrupts_timer_ticks(), (u64)-1);
|
||||
clks_exec_dynlib_release_owner(proc->pid);
|
||||
|
||||
if (depth_pushed == CLKS_TRUE && clks_exec_pid_stack_depth > 0U) {
|
||||
clks_exec_stop_requested_stack[(u32)depth_index] = CLKS_FALSE;
|
||||
@@ -1066,6 +1397,8 @@ void clks_exec_init(void) {
|
||||
clks_memset(clks_exec_image_begin_stack, 0, sizeof(clks_exec_image_begin_stack));
|
||||
clks_memset(clks_exec_image_end_stack, 0, sizeof(clks_exec_image_end_stack));
|
||||
clks_memset(clks_exec_proc_table, 0, sizeof(clks_exec_proc_table));
|
||||
clks_memset(clks_exec_dynlib_table, 0, sizeof(clks_exec_dynlib_table));
|
||||
clks_exec_next_dynlib_handle = 1ULL;
|
||||
clks_exec_log_info_serial("PATH EXEC FRAMEWORK ONLINE");
|
||||
}
|
||||
|
||||
@@ -1324,13 +1657,7 @@ u64 clks_exec_fd_write(u64 fd, const void *buffer, u64 size) {
|
||||
}
|
||||
|
||||
if (entry->kind == CLKS_EXEC_FD_KIND_TTY) {
|
||||
u64 i;
|
||||
const char *src = (const char *)buffer;
|
||||
|
||||
for (i = 0ULL; i < size; i++) {
|
||||
clks_tty_write_char(src[i]);
|
||||
}
|
||||
|
||||
clks_tty_write_n((const char *)buffer, (usize)size);
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -1384,6 +1711,119 @@ u64 clks_exec_fd_dup(u64 fd) {
|
||||
return (u64)fd_slot;
|
||||
}
|
||||
|
||||
u64 clks_exec_dl_open(const char *path) {
|
||||
struct clks_exec_proc_record *proc = clks_exec_current_proc();
|
||||
const void *image;
|
||||
u64 image_size = 0ULL;
|
||||
i32 existing_slot;
|
||||
i32 slot;
|
||||
u64 owner_pid;
|
||||
struct clks_exec_dynlib_slot *dyn;
|
||||
|
||||
if (proc == CLKS_NULL || path == CLKS_NULL || path[0] != '/') {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (clks_strlen(path) >= CLKS_EXEC_PATH_MAX) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
owner_pid = proc->pid;
|
||||
existing_slot = clks_exec_dynlib_find_by_owner_path(owner_pid, path);
|
||||
|
||||
if (existing_slot >= 0) {
|
||||
dyn = &clks_exec_dynlib_table[(u32)existing_slot];
|
||||
dyn->ref_count++;
|
||||
return dyn->handle;
|
||||
}
|
||||
|
||||
slot = clks_exec_dynlib_alloc_slot();
|
||||
if (slot < 0) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
image = clks_fs_read_all(path, &image_size);
|
||||
if (image == CLKS_NULL || image_size == 0ULL) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
dyn = &clks_exec_dynlib_table[(u32)slot];
|
||||
clks_memset(dyn, 0, sizeof(*dyn));
|
||||
|
||||
if (clks_elf64_load(image, image_size, &dyn->loaded) == CLKS_FALSE) {
|
||||
clks_memset(dyn, 0, sizeof(*dyn));
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
dyn->used = CLKS_TRUE;
|
||||
dyn->handle = clks_exec_dynlib_alloc_handle();
|
||||
dyn->owner_pid = owner_pid;
|
||||
dyn->ref_count = 1ULL;
|
||||
dyn->file_image = image;
|
||||
dyn->file_size = image_size;
|
||||
clks_exec_copy_path(dyn->path, sizeof(dyn->path), path);
|
||||
|
||||
clks_exec_log_info_serial("DLOPEN OK");
|
||||
clks_exec_log_info_serial(path);
|
||||
clks_exec_log_hex_serial("DL_HANDLE", dyn->handle);
|
||||
return dyn->handle;
|
||||
}
|
||||
|
||||
u64 clks_exec_dl_close(u64 handle) {
|
||||
struct clks_exec_proc_record *proc = clks_exec_current_proc();
|
||||
i32 slot;
|
||||
struct clks_exec_dynlib_slot *dyn;
|
||||
|
||||
if (proc == CLKS_NULL || handle == 0ULL) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
slot = clks_exec_dynlib_find_by_handle(handle);
|
||||
if (slot < 0) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
dyn = &clks_exec_dynlib_table[(u32)slot];
|
||||
if (dyn->owner_pid != proc->pid) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
if (dyn->ref_count > 1ULL) {
|
||||
dyn->ref_count--;
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
clks_exec_dynlib_slot_reset(dyn);
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
u64 clks_exec_dl_sym(u64 handle, const char *symbol) {
|
||||
struct clks_exec_proc_record *proc = clks_exec_current_proc();
|
||||
i32 slot;
|
||||
struct clks_exec_dynlib_slot *dyn;
|
||||
u64 addr = 0ULL;
|
||||
|
||||
if (proc == CLKS_NULL || handle == 0ULL || symbol == CLKS_NULL || symbol[0] == '\0') {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
slot = clks_exec_dynlib_find_by_handle(handle);
|
||||
if (slot < 0) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
dyn = &clks_exec_dynlib_table[(u32)slot];
|
||||
if (dyn->owner_pid != proc->pid) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (clks_exec_dynlib_resolve_symbol(dyn, symbol, &addr) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
u64 clks_exec_current_pid(void) {
|
||||
i32 depth_index = clks_exec_current_depth_index();
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#define CLKS_SYSCALL_KDBG_STACK_WINDOW_BYTES (128ULL * 1024ULL)
|
||||
#define CLKS_SYSCALL_KERNEL_SYMBOL_FILE "/system/kernel.sym"
|
||||
#define CLKS_SYSCALL_KERNEL_ADDR_BASE 0xFFFF800000000000ULL
|
||||
#define CLKS_SYSCALL_STATS_MAX_ID CLKS_SYSCALL_FD_DUP
|
||||
#define CLKS_SYSCALL_STATS_MAX_ID CLKS_SYSCALL_DL_SYM
|
||||
#define CLKS_SYSCALL_STATS_RING_SIZE 256U
|
||||
|
||||
struct clks_syscall_frame {
|
||||
@@ -244,6 +244,30 @@ static u64 clks_syscall_fd_dup(u64 arg0) {
|
||||
return clks_exec_fd_dup(arg0);
|
||||
}
|
||||
|
||||
static u64 clks_syscall_dl_open(u64 arg0) {
|
||||
char path[CLKS_SYSCALL_PATH_MAX];
|
||||
|
||||
if (clks_syscall_copy_user_string(arg0, path, sizeof(path)) == CLKS_FALSE) {
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
return clks_exec_dl_open(path);
|
||||
}
|
||||
|
||||
static u64 clks_syscall_dl_close(u64 arg0) {
|
||||
return clks_exec_dl_close(arg0);
|
||||
}
|
||||
|
||||
static u64 clks_syscall_dl_sym(u64 arg0, u64 arg1) {
|
||||
char symbol[CLKS_SYSCALL_NAME_MAX];
|
||||
|
||||
if (clks_syscall_copy_user_string(arg1, symbol, sizeof(symbol)) == CLKS_FALSE) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
return clks_exec_dl_sym(arg0, symbol);
|
||||
}
|
||||
|
||||
static clks_bool clks_syscall_procfs_is_root(const char *path) {
|
||||
return (path != CLKS_NULL && clks_strcmp(path, "/proc") == 0) ? CLKS_TRUE : CLKS_FALSE;
|
||||
}
|
||||
@@ -1830,6 +1854,12 @@ u64 clks_syscall_dispatch(void *frame_ptr) {
|
||||
return clks_syscall_fd_close(frame->rbx);
|
||||
case CLKS_SYSCALL_FD_DUP:
|
||||
return clks_syscall_fd_dup(frame->rbx);
|
||||
case CLKS_SYSCALL_DL_OPEN:
|
||||
return clks_syscall_dl_open(frame->rbx);
|
||||
case CLKS_SYSCALL_DL_CLOSE:
|
||||
return clks_syscall_dl_close(frame->rbx);
|
||||
case CLKS_SYSCALL_DL_SYM:
|
||||
return clks_syscall_dl_sym(frame->rbx, frame->rcx);
|
||||
default:
|
||||
return (u64)-1;
|
||||
}
|
||||
|
||||
@@ -1215,11 +1215,11 @@ void clks_tty_write_char(char ch) {
|
||||
clks_tty_reset_blink_timer();
|
||||
}
|
||||
|
||||
void clks_tty_write(const char *text) {
|
||||
void clks_tty_write_n(const char *text, usize len) {
|
||||
usize i = 0U;
|
||||
u32 tty_index;
|
||||
|
||||
if (clks_tty_is_ready == CLKS_FALSE || text == CLKS_NULL) {
|
||||
if (clks_tty_is_ready == CLKS_FALSE || text == CLKS_NULL || len == 0U) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1231,7 +1231,7 @@ void clks_tty_write(const char *text) {
|
||||
clks_tty_redraw_active();
|
||||
}
|
||||
|
||||
while (text[i] != '\0') {
|
||||
while (i < len) {
|
||||
if (clks_tty_ansi_process_byte(tty_index, text[i]) == CLKS_FALSE) {
|
||||
clks_tty_put_char_raw(tty_index, text[i]);
|
||||
}
|
||||
@@ -1244,6 +1244,14 @@ void clks_tty_write(const char *text) {
|
||||
clks_tty_reset_blink_timer();
|
||||
}
|
||||
|
||||
void clks_tty_write(const char *text) {
|
||||
if (text == CLKS_NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
clks_tty_write_n(text, clks_strlen(text));
|
||||
}
|
||||
|
||||
void clks_tty_switch(u32 tty_index) {
|
||||
if (clks_tty_is_ready == CLKS_FALSE) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user