95 const void *stack_envp[info->
envc + 1];
96 const void *stack_argv[info->
argc + 1];
99 size_t stack_size = 0;
100 stack_size +=
sizeof(
uintn);
103 for (
int i = 0; i < info->
envc; i++)
106 for (
int i = 0; i < info->
argc; i++)
109 stack_size +=
sizeof(Elf64_auxv_t) * (info->
auxv.
count + 2);
110 stack_size +=
sizeof(stack_envp);
111 stack_size +=
sizeof(stack_argv);
112 stack_size +=
sizeof(
uintn);
115 const size_t aligned_stack_size =
ALIGN_UP(stack_size, 16);
129 for (
int i = info->
envc - 1; i >= 0; i--)
142 for (
int i = info->
argc - 1; i >= 0; i--)
188 const ptr_t map_start = map_bias + aligned_vaddr;
189 pr_dinfo2(elf,
" mapping %zu pages at " PTR_FMT " (bias at " PTR_FMT ") from offset %zu...", npages, map_start, map_bias, aligned_size);
206 if (interp_file.isErr())
221 for (
size_t i = 0; i < elf.
ph.
count; i++)
258 ptrdiff_t map_bias = 0;
260 bool has_interpreter =
false;
261 ptr_t interp_entrypoint = 0;
262 ptr_t auxv_phdr_vaddr =
false;
264 for (
size_t i = 0; i < elf.
ph.
count; i++)
288 pr_dinfo2(elf,
"elf interpreter: %s", interp_name);
289 has_interpreter =
true;
291 if (!interp_entrypoint)
293 pr_dinfo2(elf,
"failed to map interpreter '%s'", interp_name);
311 auxv_phdr_vaddr = ph.
vaddr;
340 ptr_t user_argv, user_envp;
385 while (envp && envp[envc] !=
NULL)
389 .invocation =
strdup(path),
392 .argv = kcalloc<const char *>(
argc + 1),
394 .envp = kcalloc<const char *>(envc + 1),
397 for (
int i = 0; i <
argc; i++)
401 for (
int i = 0; i < envc; i++)
409 for (
int i = 0; i <
argc; i++)
411 for (
int i = 0; i < envc; i++)
425 mos_warn(
"failed to open '%s'", path);
#define MOS_ASSERT_X(cond, msg,...)
#define mos_warn(fmt,...)
#define MOS_ELF_INTERPRETER_BASE_OFFSET
const Char * c_str() const
bool elf_fill_process(Process *proc, file_t *file, const char *path, const char *const argv[], const char *const envp[])
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, MMContext *mm, file_t *file)
Process * elf_create_process(const char *path, Process *parent, const char *const argv[], const char *const envp[], const stdio_t *ios)
bool elf_read_and_verify_executable(file_t *file, elf_header_t *header)
static ptr_t elf_map_interpreter(const char *path, MMContext *mm)
static bool elf_verify_header(const elf_header_t *header)
static void elf_setup_main_thread(Thread *thread, elf_startup_info_t *const info, ptr_t *const out_pargv, ptr_t *const out_penvp)
static bool elf_read_file(file_t *file, void *buf, off_t offset, size_t size)
__nodiscard bool elf_do_fill_process(Process *proc, file_t *file, elf_header_t elf, elf_startup_info_t *info)
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)
MOSAPI void(1, 2) fatal_abort(const char *fmt
__nodiscard MMContext * mm_switch_context(MMContext *new_ctx)
PtrResult< 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(MMContext *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 *&&proc, u8 exit_code, signal_t signal)
Process * process_new(Process *parent, mos::string_view name, const stdio_t *ios)
#define memzero(ptr, size)
void scheduler_add_thread(Thread *thread)
Add a thread to the scheduler, so that it can be scheduled.
downwards_stack_t u_stack
user-mode stack
elf_program_header_type header_type
A wrapper type for the standard I/O streams.
Thread * thread_complete_init(Thread *thread)
mos::string dentry_name(const dentry_t *dentry)