populate ELF header information on the initial stack so that glibc can set up TLS properly
This commit is contained in:
@ -254,7 +254,7 @@ static void process_msg_prepare_process(unsigned long rphys)
|
||||
dkprintf("env OK\n");
|
||||
|
||||
p->rprocess = (unsigned long)proc;
|
||||
init_process_stack(proc, argc, argv, envc, env);
|
||||
init_process_stack(proc, pn, argc, argv, envc, env);
|
||||
|
||||
dkprintf("new process : %p [%d] / table : %p\n", proc, proc->pid,
|
||||
proc->vm->page_table);
|
||||
|
||||
33
kernel/include/auxvec.h
Normal file
33
kernel/include/auxvec.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef _LINUX_AUXVEC_H
|
||||
#define _LINUX_AUXVEC_H
|
||||
|
||||
/* Symbolic values for the entries in the auxiliary table
|
||||
put on the initial stack */
|
||||
#define AT_NULL 0 /* end of vector */
|
||||
#define AT_IGNORE 1 /* entry should be ignored */
|
||||
#define AT_EXECFD 2 /* file descriptor of program */
|
||||
#define AT_PHDR 3 /* program headers for program */
|
||||
#define AT_PHENT 4 /* size of program header entry */
|
||||
#define AT_PHNUM 5 /* number of program headers */
|
||||
#define AT_PAGESZ 6 /* system page size */
|
||||
#define AT_BASE 7 /* base address of interpreter */
|
||||
#define AT_FLAGS 8 /* flags */
|
||||
#define AT_ENTRY 9 /* entry point of program */
|
||||
#define AT_NOTELF 10 /* program is not ELF */
|
||||
#define AT_UID 11 /* real uid */
|
||||
#define AT_EUID 12 /* effective uid */
|
||||
#define AT_GID 13 /* real gid */
|
||||
#define AT_EGID 14 /* effective gid */
|
||||
#define AT_PLATFORM 15 /* string identifying CPU for optimizations */
|
||||
#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */
|
||||
#define AT_CLKTCK 17 /* frequency at which times() increments */
|
||||
/* AT_* values 18 through 22 are reserved */
|
||||
#define AT_SECURE 23 /* secure mode boolean */
|
||||
#define AT_BASE_PLATFORM 24 /* string identifying real platform, may
|
||||
* differ from AT_PLATFORM. */
|
||||
#define AT_RANDOM 25 /* address of 16 random bytes */
|
||||
|
||||
#define AT_EXECFN 31 /* filename of program */
|
||||
|
||||
|
||||
#endif /* _LINUX_AUXVEC_H */
|
||||
@ -86,7 +86,9 @@ int add_process_large_range(struct process *process,
|
||||
unsigned long flag, unsigned long *phys);
|
||||
int remove_process_region(struct process *proc,
|
||||
unsigned long start, unsigned long end);
|
||||
void init_process_stack(struct process *process, int argc, char **argv,
|
||||
struct program_load_desc;
|
||||
void init_process_stack(struct process *process, struct program_load_desc *pn,
|
||||
int argc, char **argv,
|
||||
int envc, char **env);
|
||||
unsigned long extend_process_region(struct process *proc,
|
||||
unsigned long start, unsigned long end,
|
||||
|
||||
@ -90,6 +90,9 @@ struct program_load_desc {
|
||||
int pid;
|
||||
unsigned long entry;
|
||||
unsigned long rprocess;
|
||||
unsigned long at_phdr;
|
||||
unsigned long at_phent;
|
||||
unsigned long at_phnum;
|
||||
char *args;
|
||||
unsigned long args_len;
|
||||
char *envs;
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include <aal/debug.h>
|
||||
#include <page.h>
|
||||
#include <cpulocal.h>
|
||||
#include <auxvec.h>
|
||||
|
||||
#define DEBUG_PRINT_PROCESS
|
||||
|
||||
@ -199,7 +200,8 @@ int add_process_memory_range(struct process *process,
|
||||
|
||||
|
||||
|
||||
void init_process_stack(struct process *process, int argc, char **argv,
|
||||
void init_process_stack(struct process *process, struct program_load_desc *pn,
|
||||
int argc, char **argv,
|
||||
int envc, char **env)
|
||||
{
|
||||
int s_ind = 0;
|
||||
@ -215,11 +217,16 @@ void init_process_stack(struct process *process, int argc, char **argv,
|
||||
USER_END,
|
||||
virt_to_phys(stack), VR_STACK);
|
||||
|
||||
p[-1] = 0; /* AT_NULL */
|
||||
p[-2] = 0;
|
||||
p[-3] = USER_END - sizeof(unsigned long) * 2;
|
||||
p[-4] = 0; /* envp terminating NULL */
|
||||
s_ind = -5;
|
||||
s_ind = -1;
|
||||
p[s_ind--] = 0; /* AT_NULL */
|
||||
p[s_ind--] = 0;
|
||||
p[s_ind--] = pn->at_phnum; /* AT_PHNUM */
|
||||
p[s_ind--] = AT_PHNUM;
|
||||
p[s_ind--] = pn->at_phent; /* AT_PHENT */
|
||||
p[s_ind--] = AT_PHENT;
|
||||
p[s_ind--] = pn->at_phdr; /* AT_PHDR */
|
||||
p[s_ind--] = AT_PHDR;
|
||||
p[s_ind--] = 0; /* envp terminating NULL */
|
||||
/* envp */
|
||||
for (arg_ind = envc - 1; arg_ind > -1; --arg_ind) {
|
||||
p[s_ind--] = (unsigned long)env[arg_ind];
|
||||
|
||||
@ -60,6 +60,8 @@ struct program_load_desc *load_elf(FILE *fp)
|
||||
Elf64_Phdr phdr;
|
||||
int i, j, nhdrs = 0;
|
||||
struct program_load_desc *desc;
|
||||
unsigned long load_addr = 0;
|
||||
int load_addr_set = 0;
|
||||
|
||||
if (fread(&hdr, sizeof(hdr), 1, fp) < 1) {
|
||||
__eprint("Cannot read Ehdr.\n");
|
||||
@ -103,11 +105,20 @@ struct program_load_desc *load_elf(FILE *fp)
|
||||
desc->sections[j].offset,
|
||||
desc->sections[j].len);
|
||||
j++;
|
||||
|
||||
if (!load_addr_set) {
|
||||
load_addr_set = 1;
|
||||
load_addr = phdr.p_vaddr - phdr.p_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
desc->pid = getpid();
|
||||
desc->entry = hdr.e_entry;
|
||||
|
||||
desc->at_phdr = load_addr + hdr.e_phoff;
|
||||
desc->at_phent = sizeof(phdr);
|
||||
desc->at_phnum = hdr.e_phnum;
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
|
||||
@ -31,6 +31,9 @@ struct program_load_desc {
|
||||
int pid;
|
||||
unsigned long entry;
|
||||
unsigned long rprocess;
|
||||
unsigned long at_phdr;
|
||||
unsigned long at_phent;
|
||||
unsigned long at_phnum;
|
||||
char *args;
|
||||
unsigned long args_len;
|
||||
char *envs;
|
||||
|
||||
Reference in New Issue
Block a user