mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 23:18:21 +00:00
added auxv to elf stack setup
the needed ones for rtdl; AT_NULL, AT_PHDR, AT_ENTRY, AT_PHNUM, AT_PHENT
This commit is contained in:
Binary file not shown.
@@ -28,6 +28,12 @@
|
|||||||
|
|
||||||
#define STACK_TOP 0x800000000000
|
#define STACK_TOP 0x800000000000
|
||||||
|
|
||||||
|
#define AT_NULL 0
|
||||||
|
#define AT_PHDR 3
|
||||||
|
#define AT_PHENT 4
|
||||||
|
#define AT_PHNUM 5
|
||||||
|
#define AT_ENTRY 9
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
uint8_t bits;
|
uint8_t bits;
|
||||||
|
|||||||
+59
-20
@@ -11,8 +11,8 @@ typedef struct{
|
|||||||
} auxv64_t;
|
} auxv64_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
auxv64_t phdr;
|
||||||
|
auxv64_t null;
|
||||||
} auxv64_list;
|
} auxv64_list;
|
||||||
|
|
||||||
static size_t phflagtommuflag(size_t phflags){
|
static size_t phflagtommuflag(size_t phflags){
|
||||||
@@ -51,13 +51,13 @@ static bool check_header64(elf_header64* header){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* stacksetup(char* interp, char** argv, char** env){
|
static void* stacksetup(char* interp, char** argv, char** env, elf_header64 header, elf_ph64* phs){
|
||||||
size_t argc = 0;
|
size_t argc = 0;
|
||||||
size_t envc = 0;
|
size_t envc = 0;
|
||||||
size_t initialsize = 0;
|
size_t initialsize = 0;
|
||||||
size_t argdatasize = 0;
|
size_t argdatasize = 0;
|
||||||
size_t envdatasize = 0;
|
size_t envdatasize = 0;
|
||||||
size_t auxvsize = 8;
|
size_t auxvsize = 5*8; // FIXME better way of keeping track of this
|
||||||
|
|
||||||
while(argv[argc]){
|
while(argv[argc]){
|
||||||
argdatasize += strlen(argv[argc]) + 1;
|
argdatasize += strlen(argv[argc]) + 1;
|
||||||
@@ -81,35 +81,61 @@ static void* stacksetup(char* interp, char** argv, char** env){
|
|||||||
|
|
||||||
initialsize += argc*sizeof(char*); //args
|
initialsize += argc*sizeof(char*); //args
|
||||||
initialsize += envc*sizeof(char*); //envs
|
initialsize += envc*sizeof(char*); //envs
|
||||||
initialsize += 2*sizeof(char**); //argv envp
|
|
||||||
initialsize += sizeof(size_t); //argc
|
initialsize += sizeof(size_t); //argc
|
||||||
|
|
||||||
// allocate memory for the initial section of the stack
|
// allocate memory for the initial section of the stack
|
||||||
|
|
||||||
|
// XXX demand alloc the non initialised stack pages
|
||||||
if(!vmm_allocnowat(STACK_TOP - initialsize, ARCH_MMU_MAP_READ | ARCH_MMU_MAP_WRITE | ARCH_MMU_MAP_NOEXEC | ARCH_MMU_MAP_USER, initialsize)) return NULL;
|
if(!vmm_allocnowat(STACK_TOP - initialsize - PAGE_SIZE*200, ARCH_MMU_MAP_READ | ARCH_MMU_MAP_WRITE | ARCH_MMU_MAP_NOEXEC | ARCH_MMU_MAP_USER, initialsize + PAGE_SIZE*200)) return NULL;
|
||||||
|
|
||||||
// get the addresses to copy the data to
|
// get the addresses to copy the data to
|
||||||
|
|
||||||
char* argdatastart = STACK_TOP - argdatasize;
|
elf_ph64* phdrdatastart = STACK_TOP - header.ph_count * header.ph_size;
|
||||||
|
char* argdatastart = (void*) phdrdatastart - argdatasize;
|
||||||
char* envdatastart = argdatastart - envdatasize;
|
char* envdatastart = argdatastart - envdatasize;
|
||||||
// auxvstart will be aligned
|
|
||||||
void* auxvstart = (void*)(((uintptr_t)envdatastart & (~0xF)) - auxvsize);
|
auxv64_t* auxvstart = (void*)(((uintptr_t)envdatastart & (~0xF)) - auxvsize);
|
||||||
// count + 1 because of a null entry
|
// count + 1 because of a null entry
|
||||||
char** envstart = auxvstart - (envc + 1)*sizeof(char*);
|
char** envstart = (void*)auxvstart - (envc + 1)*sizeof(char*);
|
||||||
char** argstart = (void*)envstart - (argc + 1)*sizeof(char*);
|
char** argstart = (void*)envstart - (argc + 1)*sizeof(char*);
|
||||||
if(interp)
|
if(interp)
|
||||||
--argstart;
|
--argstart;
|
||||||
char*** envpptr = (void*)argstart - sizeof(char**);
|
|
||||||
char*** argvptr = (void*)envpptr - sizeof(char**);
|
|
||||||
size_t* argcptr = (void*)argvptr - sizeof(size_t);
|
|
||||||
|
|
||||||
// XXX auxv
|
size_t* argcptr = (void*)argstart - sizeof(size_t);
|
||||||
|
|
||||||
|
// auxv
|
||||||
|
|
||||||
|
// AT_PHDR
|
||||||
|
|
||||||
|
auxvstart->a_type = AT_PHDR;
|
||||||
|
auxvstart->a_val = (uint64_t)phdrdatastart;
|
||||||
|
auxvstart++;
|
||||||
|
|
||||||
|
memcpy(phdrdatastart, phs, header.ph_count * header.ph_size);
|
||||||
|
|
||||||
|
// AT_PHENT
|
||||||
|
|
||||||
|
auxvstart->a_type = AT_PHENT;
|
||||||
|
auxvstart->a_val = header.ph_size;
|
||||||
|
auxvstart++;
|
||||||
|
|
||||||
|
// AT_PHNUM
|
||||||
|
|
||||||
|
auxvstart->a_type = AT_PHNUM;
|
||||||
|
auxvstart->a_val = header.ph_count;
|
||||||
|
|
||||||
|
// AT_ENTRY
|
||||||
|
|
||||||
|
auxvstart->a_type = AT_ENTRY;
|
||||||
|
auxvstart->a_val = header.entry;
|
||||||
|
auxvstart++;
|
||||||
|
|
||||||
|
// AT_NULL
|
||||||
|
|
||||||
|
auxvstart->a_type = AT_NULL;
|
||||||
|
|
||||||
// copy the data
|
// copy the data
|
||||||
|
|
||||||
*envpptr = envstart;
|
|
||||||
*argvptr = argstart;
|
|
||||||
|
|
||||||
if(interp){
|
if(interp){
|
||||||
strcpy(argdatastart, interp);
|
strcpy(argdatastart, interp);
|
||||||
@@ -147,7 +173,9 @@ static void* stacksetup(char* interp, char** argv, char** env){
|
|||||||
int elf_load(thread_t* thread, vnode_t* node, char** argv, char** env){
|
int elf_load(thread_t* thread, vnode_t* node, char** argv, char** env){
|
||||||
|
|
||||||
elf_header64 header;
|
elf_header64 header;
|
||||||
|
elf_header64 progheader;
|
||||||
elf_ph64 ph;
|
elf_ph64 ph;
|
||||||
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
int readc = vfs_read(&err, node, &header, sizeof(elf_header64), 0);
|
int readc = vfs_read(&err, node, &header, sizeof(elf_header64), 0);
|
||||||
char* interp = NULL;
|
char* interp = NULL;
|
||||||
@@ -159,8 +187,13 @@ int elf_load(thread_t* thread, vnode_t* node, char** argv, char** env){
|
|||||||
if(readc != sizeof(elf_header64) || (!check_header64(&header)))
|
if(readc != sizeof(elf_header64) || (!check_header64(&header)))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
|
progheader = header; // incase an interpreter exists
|
||||||
|
|
||||||
// find out if this needs an interpreter
|
// find out if this needs an interpreter
|
||||||
|
// and also save the executable's program headers
|
||||||
|
// for auxv
|
||||||
|
|
||||||
|
elf_ph64 progphs[header.ph_count];
|
||||||
|
|
||||||
for(size_t currentph = 0; currentph < header.ph_count; ++currentph){
|
for(size_t currentph = 0; currentph < header.ph_count; ++currentph){
|
||||||
readc = vfs_read(&err, node, &ph, header.ph_size, header.ph_pos + currentph*header.ph_size);
|
readc = vfs_read(&err, node, &ph, header.ph_size, header.ph_pos + currentph*header.ph_size);
|
||||||
@@ -169,10 +202,14 @@ int elf_load(thread_t* thread, vnode_t* node, char** argv, char** env){
|
|||||||
if(readc != header.ph_size)
|
if(readc != header.ph_size)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
|
memcpy(progphs+currentph, &ph, sizeof(elf_ph64));
|
||||||
|
|
||||||
if(ph.type == PH_TYPE_INTERPRETER){
|
if(ph.type == PH_TYPE_INTERPRETER){
|
||||||
|
|
||||||
// load the name and elf header of the interpreter
|
// load the name and elf header of the interpreter
|
||||||
|
|
||||||
|
progheader = header;
|
||||||
|
|
||||||
char* interp = alloc(ph.fsize + 1);
|
char* interp = alloc(ph.fsize + 1);
|
||||||
if(!interp)
|
if(!interp)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
@@ -204,8 +241,6 @@ int elf_load(thread_t* thread, vnode_t* node, char** argv, char** env){
|
|||||||
goto _fail;
|
goto _fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -265,7 +300,11 @@ int elf_load(thread_t* thread, vnode_t* node, char** argv, char** env){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void* stack = stacksetup(interp, argv, env);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void* stack = stacksetup(interp, argv, env, progheader, progphs);
|
||||||
|
|
||||||
arch_regs_setupuser(thread->regs, (void*)header.entry, stack, true);
|
arch_regs_setupuser(thread->regs, (void*)header.entry, stack, true);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user