mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 06:58:22 +00:00
elf: add AT_EXECFN
This commit is contained in:
@@ -28,6 +28,7 @@
|
|||||||
#define AT_PHENT 4
|
#define AT_PHENT 4
|
||||||
#define AT_PHNUM 5
|
#define AT_PHNUM 5
|
||||||
#define AT_ENTRY 9
|
#define AT_ENTRY 9
|
||||||
|
#define AT_EXECFN 31
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint64_t type;
|
uint64_t type;
|
||||||
@@ -39,6 +40,7 @@ typedef struct {
|
|||||||
auxv64_t phnum;
|
auxv64_t phnum;
|
||||||
auxv64_t phent;
|
auxv64_t phent;
|
||||||
auxv64_t entry;
|
auxv64_t entry;
|
||||||
|
auxv64_t execfn;
|
||||||
auxv64_t null;
|
auxv64_t null;
|
||||||
} auxv64list_t;
|
} auxv64list_t;
|
||||||
|
|
||||||
@@ -83,6 +85,6 @@ typedef struct{
|
|||||||
} __attribute__((packed)) elfph64_t;
|
} __attribute__((packed)) elfph64_t;
|
||||||
|
|
||||||
int elf_load(vnode_t *vnode, void *base, void **entry, char **interpreter, auxv64list_t *auxv64);
|
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
|
#endif
|
||||||
|
|||||||
+10
-3
@@ -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_SIZE (1024 * 1024 * 4)
|
||||||
#define STACK_TOP_BUFFER 8
|
#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 argc;
|
||||||
size_t envc;
|
size_t envc;
|
||||||
size_t argdatasize = 0;
|
size_t argdatasize = 0;
|
||||||
size_t envdatasize = 0;
|
size_t envdatasize = 0;
|
||||||
|
size_t pathsize = strlen(path) + 1;
|
||||||
|
|
||||||
for (argc = 0; argv[argc]; ++argc)
|
for (argc = 0; argv[argc]; ++argc)
|
||||||
argdatasize += strlen(argv[argc]) + 1;
|
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;
|
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
|
// 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);
|
size_t initialsizeround = ROUND_UP(initialsize, PAGE_SIZE);
|
||||||
void *initialpagebase = (void *)((uintptr_t)top - initialsizeround);
|
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 *argdatastart = (char *)((uintptr_t)top - argdatasize);
|
||||||
char *envdatastart = (char *)((uintptr_t)argdatastart - envdatasize);
|
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);
|
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;
|
char **argstart = (char **)envstart - argc - 1;
|
||||||
size_t *argcptr = (size_t *)argstart - 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));
|
memcpy(auxvstart, auxv64, sizeof(auxv64list_t));
|
||||||
|
|
||||||
for (int i = 0; i < argc; ++i) {
|
for (int i = 0; i < argc; ++i) {
|
||||||
|
|||||||
@@ -361,7 +361,7 @@ void proc_run_init() {
|
|||||||
char *argv[] = {"/init", cmdline_get("initarg"), NULL};
|
char *argv[] = {"/init", cmdline_get("initarg"), NULL};
|
||||||
char *envp[] = {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);
|
__assert(stack);
|
||||||
|
|
||||||
// reenter kernel context
|
// reenter kernel context
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ static syscallret_t execve(context_t *context, char *upath, char *uargv[], char
|
|||||||
VOP_RELEASE(interpnode);
|
VOP_RELEASE(interpnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
stack = elf_preparestack(STACK_TOP, &auxv64, argv, envp);
|
stack = elf_preparestack(STACK_TOP, &auxv64, argv, envp, path);
|
||||||
if (stack == NULL) {
|
if (stack == NULL) {
|
||||||
ret.errno = ENOMEM;
|
ret.errno = ENOMEM;
|
||||||
goto error;
|
goto error;
|
||||||
|
|||||||
Reference in New Issue
Block a user