elf: add AT_EXECFN

This commit is contained in:
Qwinci
2025-01-13 16:15:08 +02:00
parent 75a24d3026
commit ae2f69d3b8
4 changed files with 15 additions and 6 deletions
+3 -1
View File
@@ -28,6 +28,7 @@
#define AT_PHENT 4
#define AT_PHNUM 5
#define AT_ENTRY 9
#define AT_EXECFN 31
typedef struct {
uint64_t type;
@@ -39,6 +40,7 @@ typedef struct {
auxv64_t phnum;
auxv64_t phent;
auxv64_t entry;
auxv64_t execfn;
auxv64_t null;
} auxv64list_t;
@@ -83,6 +85,6 @@ typedef struct{
} __attribute__((packed)) elfph64_t;
int elf_load(vnode_t *vnode, void *base, void **entry, char **interpreter, auxv64list_t *auxv64);
void *elf_preparestack(void *top, auxv64list_t *auxv64, char **argv, char **envp);
void *elf_preparestack(void *top, auxv64list_t *auxv64, char **argv, char **envp, char *path);
#endif
+10 -3
View File
@@ -215,11 +215,12 @@ int elf_load(vnode_t *vnode, void *base, void **entry, char **interpreter, auxv6
#define STACK_SIZE (1024 * 1024 * 4)
#define STACK_TOP_BUFFER 8
void *elf_preparestack(void *top, auxv64list_t *auxv64, char **argv, char **envp) {
void *elf_preparestack(void *top, auxv64list_t *auxv64, char **argv, char **envp, char *path) {
size_t argc;
size_t envc;
size_t argdatasize = 0;
size_t envdatasize = 0;
size_t pathsize = strlen(path) + 1;
for (argc = 0; argv[argc]; ++argc)
argdatasize += strlen(argv[argc]) + 1;
@@ -231,7 +232,7 @@ void *elf_preparestack(void *top, auxv64list_t *auxv64, char **argv, char **envp
int alignment = ((argc + 1) + (envc + 1) + 1) & 1 ? 8 : 0;
// env data + arg data + pointers to arg and env data + argc + buffer at the top
size_t initialsize = argdatasize + envdatasize + (argc + envc) * sizeof(char *) + sizeof(size_t) + sizeof(auxv64list_t) + alignment + STACK_TOP_BUFFER;
size_t initialsize = argdatasize + envdatasize + pathsize + (argc + envc) * sizeof(char *) + sizeof(size_t) + sizeof(auxv64list_t) + alignment + STACK_TOP_BUFFER;
size_t initialsizeround = ROUND_UP(initialsize, PAGE_SIZE);
void *initialpagebase = (void *)((uintptr_t)top - initialsizeround);
@@ -247,7 +248,8 @@ void *elf_preparestack(void *top, auxv64list_t *auxv64, char **argv, char **envp
char *argdatastart = (char *)((uintptr_t)top - argdatasize);
char *envdatastart = (char *)((uintptr_t)argdatastart - envdatasize);
auxv64list_t *auxvstart = (auxv64list_t *)envdatastart - 1;
char *pathdatastart = (char *)((uintptr_t)envdatastart - pathsize);
auxv64list_t *auxvstart = (auxv64list_t *)pathdatastart - 1;
auxvstart = (auxv64list_t *)(((uintptr_t)auxvstart & ~(uintptr_t)0xf) - alignment);
@@ -256,6 +258,11 @@ void *elf_preparestack(void *top, auxv64list_t *auxv64, char **argv, char **envp
char **argstart = (char **)envstart - argc - 1;
size_t *argcptr = (size_t *)argstart - 1;
auxv64->execfn.type = AT_EXECFN;
auxv64->execfn.val = (uint64_t)pathdatastart;
memcpy(pathdatastart, path, pathsize);
memcpy(auxvstart, auxv64, sizeof(auxv64list_t));
for (int i = 0; i < argc; ++i) {
+1 -1
View File
@@ -361,7 +361,7 @@ void proc_run_init() {
char *argv[] = {"/init", cmdline_get("initarg"), NULL};
char *envp[] = {NULL};
void *stack = elf_preparestack(STACK_TOP, &auxv64, argv, envp);
void *stack = elf_preparestack(STACK_TOP, &auxv64, argv, envp, "/init");
__assert(stack);
// reenter kernel context
+1 -1
View File
@@ -258,7 +258,7 @@ static syscallret_t execve(context_t *context, char *upath, char *uargv[], char
VOP_RELEASE(interpnode);
}
stack = elf_preparestack(STACK_TOP, &auxv64, argv, envp);
stack = elf_preparestack(STACK_TOP, &auxv64, argv, envp, path);
if (stack == NULL) {
ret.errno = ENOMEM;
goto error;