88 pr_dinfo2(elf,
"cpu %d: setting up a new main thread %pt of process %pp",
current_cpu->id, (
void *) thread, (
void *) thread->
owner);
93 const void *stack_envp[info->
envc + 1];
94 const void *stack_argv[info->
argc + 1];
97 size_t stack_size = 0;
98 stack_size +=
sizeof(
uintn);
101 for (
int i = 0; i < info->
envc; i++)
104 for (
int i = 0; i < info->
argc; i++)
107 stack_size +=
sizeof(Elf64_auxv_t) * (info->
auxv.
count + 2);
108 stack_size +=
sizeof(stack_envp);
109 stack_size +=
sizeof(stack_argv);
110 stack_size +=
sizeof(
uintn);
113 const size_t aligned_stack_size =
ALIGN_UP(stack_size, 16);
127 for (
int i = info->
envc - 1; i >= 0; i--)
140 for (
int i = info->
argc - 1; i >= 0; i--)
175 const ptr_t map_start = map_bias + aligned_vaddr;
176 pr_dinfo2(elf,
" mapping %zu pages at " PTR_FMT " (bias at " PTR_FMT ") from offset %zu...", npages, map_start, map_bias, aligned_size);
193 if (IS_ERR(interp_file))
208 for (
size_t i = 0; i < elf.
ph.
count; i++)
245 ptrdiff_t map_bias = 0;
247 bool has_interpreter =
false;
248 ptr_t interp_entrypoint = 0;
249 ptr_t auxv_phdr_vaddr =
false;
251 for (
size_t i = 0; i < elf.
ph.
count; i++)
271 pr_dinfo2(elf,
"elf interpreter: %s", interp_name);
272 has_interpreter =
true;
274 if (!interp_entrypoint)
276 pr_dinfo2(elf,
"failed to map interpreter '%s'", interp_name);
292 auxv_phdr_vaddr = ph.
vaddr;
321 ptr_t user_argv, user_envp;
363 goto cleanup_close_file;
371 while (envp && envp[envc] !=
NULL)
375 .invocation =
strdup(path),
377 .argv = kmalloc(
sizeof(
char *) * (
argc + 1)),
379 .envp = kmalloc(
sizeof(
char *) * (envc + 1)),
383 for (
int i = 0; i <
argc; i++)
387 for (
int i = 0; i < envc; i++)
395 for (
int i = 0; i <
argc; i++)
397 for (
int i = 0; i < envc; i++)
414 mos_warn(
"failed to open '%s'", path);
423 goto cleanup_close_file;
#define MOS_ASSERT_X(cond, msg,...)
#define mos_warn(fmt,...)
#define MOS_ELF_INTERPRETER_BASE_OFFSET
static ptr_t elf_determine_loadbias(elf_header_t *elf)
static void elf_map_segment(const elf_program_hdr_t *const ph, ptr_t map_bias, mm_context_t *mm, file_t *file)
bool elf_read_and_verify_executable(file_t *file, elf_header_t *header)
static bool elf_verify_header(const elf_header_t *header)
process_t * elf_create_process(const char *path, process_t *parent, const char *const argv[], const char *const envp[], const stdio_t *ios)
static ptr_t elf_map_interpreter(const char *path, mm_context_t *mm)
static bool elf_read_file(file_t *file, void *buf, off_t offset, size_t size)
__nodiscard bool elf_do_fill_process(process_t *proc, file_t *file, elf_header_t elf, elf_startup_info_t *info)
bool elf_fill_process(process_t *proc, file_t *file, const char *path, const char *const argv[], const char *const envp[])
static void elf_setup_main_thread(thread_t *thread, elf_startup_info_t *const info, ptr_t *const out_pargv, ptr_t *const out_penvp)
static void add_auxv_entry(auxv_vec_t *var, unsigned long type, unsigned long val)
#define ELF_ENDIANNESS_MOS_DEFAULT
#define stack_push_val(stack, val)
MOSAPI void * stack_push(downwards_stack_t *stack, const void *data, size_t size)
MOSAPI char * strdup(const char *src)
MOSAPI s32 strncmp(const char *str1, const char *str2, size_t n)
__nodiscard mm_context_t * mm_switch_context(mm_context_t *new_ctx)
file_t * vfs_openat(int fd, const char *path, open_flags flags)
Open a file at a given path.
size_t io_pread(io_t *io, void *buf, size_t count, off_t offset)
io_t * io_unref(io_t *io)
ptr_t mmap_file(mm_context_t *ctx, ptr_t hint_addr, mmap_flags_t flags, vm_flags vm_flags, size_t n_pages, io_t *io, off_t offset)
Map a file into the current process's address space.
#define MOS_IN_RANGE(addr, start, end)
#define ALIGN_UP_TO_PAGE(addr)
#define ALIGN_DOWN_TO_PAGE(addr)
#define MOS_STATIC_ASSERT
#define ALIGN_UP(addr, size)
static size_t strlen(const char *s)
#define pr_emerg(fmt,...)
#define pr_dinfo2(feat, fmt,...)
void process_exit(process_t *process, u8 exit_code, signal_t signal)
process_t * process_new(process_t *parent, const char *name, const stdio_t *ios)
#define memzero(ptr, size)
void scheduler_add_thread(thread_t *thread)
Add a thread to the scheduler, so that it can be scheduled.
elf_program_header_type header_type
A wrapper type for the standard I/O streams.
downwards_stack_t u_stack
user-mode stack
thread_t * thread_complete_init(thread_t *thread)
#define dentry_name(dentry)