65#define AT_SYSINFO_EHDR 33
67#define USER_STACK_PAGES 256
68#define USER_STACK_SIZE (USER_STACK_PAGES * 4096)
72 char*
const* argv,
char*
const* envp,
87 for (
int i = envc - 1; i >= 0; i--) {
91 envp_user[i] = stack_top_user - (
uintptr_t)(stack_top - sp_ptr);
97 for (
int i = argc - 1; i >= 0; i--) {
101 argv_user[i] = stack_top_user - (
uintptr_t)(stack_top - sp_ptr);
105 uint8_t random_bytes[16] = {0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE,
106 0xBA, 0xBE, 0x12, 0x34, 0x56, 0x78,
107 0x9A, 0xBC, 0xDE, 0xF0};
109 memcopy(sp_ptr, random_bytes, 16);
111 stack_top_user - (
uintptr_t)(stack_top - sp_ptr);
119 *(--sp) = random_user_addr;
134 if (interp_base_addr) {
135 *(--sp) = interp_base_addr;
145 *(--sp) = phdr_vaddr;
149 for (
int i = envc - 1; i >= 0; i--) {
150 *(--sp) = envp_user[i];
154 for (
int i = argc - 1; i >= 0; i--) {
155 *(--sp) = argv_user[i];
174int execve(
const char*
path,
char*
const* argv,
char*
const* envp) {
183 if (loaded_file_dentry) {
204 ops->read(loaded_file_dentry->
vnode, file_buffer,
size, 0);
208 link_ops->readlink(loaded_file_dentry->
vnode, link_path, 255);
211 &loaded_file_dentry, 0) !=
VFS_OK) {
224 ops->read(loaded_file_dentry->
vnode, file_buffer,
size, 0);
227 LOG2_ERROR(
"PROCESS",
"unsupported file type");
245 LOG_INFO(
"PROCESS",
"loaded size %d (%d kb)", loaded_size,
251 LOG_INFO(
"PROCESS",
"executable %s has base addr at 0x%x",
path,
289 char* interp_path = (
char*)(file_buffer + p->
p_offset);
291 auto interp_path_ =
str(interp_path);
293 interp_path_->c_str);
295 &interp_dentry, 0) !=
VFS_OK) {
297 "error: dynamic linker not found..\n");
314 for (
int i = 0; i < ehdr.
e_phnum; i++) {
315 if (mmap_table[i].
mapped) {
316 temporary_base = mmap_table[i].
vaddr;
338 serial2_printf(
"temporary_base 0x%x -> base 0x%x\n", temporary_base,
340 if (!temporary_base) {
352 if (dyn && !interp_dentry) {
353 LOG_INFO(
"VOXMO",
"dynamic section found at 0x%x", dyn);
378 auto interp_file_size = interp_dentry->
vnode->
size;
380 interp_dentry->
name->
c_str, interp_file_size);
385 char interp_link_path[255];
388 interp_ops->readlink(interp_dentry->
vnode,
389 interp_link_path, 255);
393 &interp_link_dentry, 0) !=
VFS_OK) {
399 auto ld_so_size = interp_link_dentry->
vnode->
size;
402 LOG2_ERROR(
"PROCESS",
"unable to alloc %d kb",
416 ld_so_ops->read(interp_link_dentry->
vnode, ld_so_buffer,
423 size_t ld_so_size_4k =
428 LOG_INFO(
"PROCESS",
"interp %s has base addr at 0x%x",
429 interp_dentry->
name->
c_str, interp_base_addr);
434 auto ll =
elf_load(
page, ld_so_buffer, interp_base_addr,
435 interp_base_addr, interp_mmap_table);
438 interp_entry_addr = interp_base_addr + interp_ehdr.
e_entry;
460 const char* fallback_argv[] = {
path,
NULL};
462 argv = (
char*
const*)fallback_argv;
468 envp, &ehdr,
entry_addr, phdr_vaddr, interp_base_addr);
471 if (interp_base_addr)
472 entr = interp_entry_addr;
482 procc->heap_end = procc->heap_start;
483 procc->vm_lock.next_ticket = procc->vm_lock.now_serving = 0;
486 for (
int i = 0; i < ehdr.
e_phnum; i++) {
487 auto mm = &mmap_table[i];
490 "process: added to vma aligned base 0x%x\n",
497 if (interp_base_addr && interp_mmap_table) {
499 for (
int i = 0; i < interp_ehdr.
e_phnum; i++) {
500 auto mm = &interp_mmap_table[i];
504 "aligned base 0x%x\n",
505 interp_base_addr + mm->alligned);
508 interp_base_addr + mm->alligned,
518 "done setuping executable, now ready to sended to scheduler\n");
538 (
uint8_t)__builtin_ctz((
unsigned)(~
byte & 0xFF));
541 return (
pid_t)(i * 8 + free_bit);
567 p->cache.next = &p->cache;
568 p->cache.prev = &p->cache;
570 auto bucket_idx = p->pid % 256;
571 auto h = process_bucket[bucket_idx].
first;
577 process_bucket[bucket_idx].
first = n;
599 auto tty_vnode = tty_dentry->vnode;
603 auto next_fd = p->fdtable->next_fd++;
606 fd_dentry->
vnode = tty_vnode;
609 fd0->vnode = tty_vnode;
610 fd0->ops = tty_vnode->ops;
611 p->fdtable->fds[next_fd] = fd0;
616 auto next_fd = p->fdtable->next_fd++;
619 fd_dentry->
vnode = tty_vnode;
622 fd1->vnode = tty_vnode;
623 fd1->ops = tty_vnode->ops;
624 p->fdtable->fds[next_fd] = fd1;
629 auto next_fd = p->fdtable->next_fd++;
632 fd_dentry->
vnode = tty_vnode;
635 fd2->vnode = tty_vnode;
636 fd2->ops = tty_vnode->ops;
637 p->fdtable->fds[next_fd] = fd2;
struct dentry * dentry_ptr
void print_dentry_tree(dentry_t *node, int depth)
void dentry_put(dentry_ptr dentry)
int resolve_dentry(char *path, dentry_ptr parent, dentry_ptr *out, uint8_t flag)
Resolves a path to a directory entry (dentry) with configurable start point and strictness.
int vxnamei(const char *path, dentry_ptr *out)
Resolves a file path to a directory entry (dentry).
dentry_ptr get_root_dentry()
void elf_section_map_all(uint8_t *data, elf_section_map *map)
size_t elf_load(volatile uintptr_t *page, uint8_t *data, uintptr_t temporary_base, uintptr_t base, struct elf_load_mmap_table *table)
void elf_gnu_hash_parse(GnuHashHeader *gnu_hash, Elf64_Shdr *gnu_hash_sym, uint8_t *data)
void elf_dyn_map_all(Elf64_Dyn *dyn, uint8_t *data, elf_dynamic_map *map)
Elf64_Dyn * elf_get_phdr_dynamic(uint8_t *data)
void elf_relocate_dyn(elf_dynamic_map *map, uintptr_t kernel_base, uintptr_t user_base, GnuHashHeader *gnu_hash, symbols_ptr_vector_t *external_syms, struct elf_load_mmap_table *table, int table_count)
uintptr_t elf_count_load_size(uint8_t *data)
#define ELF_PTR(type, base, off)
struct file_descriptor * alloc_fd()
struct fdtable * alloc_fdtable()
void serial_printf(const char *fmt,...)
void serial2_printf(const char *fmt,...)
void * kalloc(size_t size)
uint64_t min(uint64_t a, uint64_t b)
#define ALIGN_UP(x, align)
page_t paging_get_highest_page_map(void)
page_t paging_create_page_directory()
void paging_setup(page_t p)
void paging_unmap_page(page_t page_dir, uint64_t virt)
void vxMultipleMmap(page_t page_dir, uint64_t virt, uint64_t phys, uint64_t size, uint64_t flags)
void * phys_base_alloc(uint64_t block)
int execve(const char *path, char *const *argv, char *const *envp)
process_t * create_process(char *name, thread_t *main_thread)
static uintptr_t elf_prepare_stack(uintptr_t stack_top_kernel, uintptr_t stack_top_user, int argc, char *const *argv, char *const *envp, Elf64_Ehdr *ehdr, uintptr_t entry_addr, uintptr_t phdr_vaddr, uintptr_t interp_base_addr)
static process_t * _process_list
static dentry_ptr process_dentry
static struct slab_cache * process_cache
static uint8_t * pid_bitmap
struct thread * main_thread
void attach_to_scheduler(thread_t *new_thread)
#define LOG_ERROR(mod, fmt,...)
#define LOG2_ERROR(mod, fmt,...)
#define LOG_INFO(mod, fmt,...)
#define serial_trace(...)
#define LOG2_INFO(mod, fmt,...)
void * vxSlabAlloc(struct slab_cache *cache)
void vxCreateSlabCache(struct slab_cache **cache, const char *name, const size_t obj_size, size_t alignment, const uintptr_t virt_addr)
char * itoa(int64_t value, int base)
char * strncpy(char *dest, const char *src, size_t n)
size_t strlen(const char *s)
void memset(void *ptr, int value, size_t num)
void memcopy(void *dest, void *src, size_t size)
void str_release(kstring str)
kstring str(const char *str)
struct vector_uint64_t needed
struct process_node * first
struct process_node * prev
struct process_node * next
thread_t * create_thread(volatile uintptr_t *page, uintptr_t entry, uintptr_t stack, uint16_t core_affinity, uint8_t priority, uint16_t flags)
dentry_ptr get_tty_dentry(int tty)
struct virtual_memory_page * create_vmm_page()
uintptr_t vma_lookup_free_vaddr(struct virtual_memory_page *page, mem_vma_region region, size_t size)
void vma_register(struct virtual_memory_page *page, uintptr_t phys_address, uintptr_t virt_addr, size_t size)
void vma_unregister(struct virtual_memory_page *page, uintptr_t virt_addr)
struct virtual_memory_page * get_kernel_vmm_page()