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");
|
dkprintf("env OK\n");
|
||||||
|
|
||||||
p->rprocess = (unsigned long)proc;
|
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,
|
dkprintf("new process : %p [%d] / table : %p\n", proc, proc->pid,
|
||||||
proc->vm->page_table);
|
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);
|
unsigned long flag, unsigned long *phys);
|
||||||
int remove_process_region(struct process *proc,
|
int remove_process_region(struct process *proc,
|
||||||
unsigned long start, unsigned long end);
|
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);
|
int envc, char **env);
|
||||||
unsigned long extend_process_region(struct process *proc,
|
unsigned long extend_process_region(struct process *proc,
|
||||||
unsigned long start, unsigned long end,
|
unsigned long start, unsigned long end,
|
||||||
|
|||||||
@ -90,6 +90,9 @@ struct program_load_desc {
|
|||||||
int pid;
|
int pid;
|
||||||
unsigned long entry;
|
unsigned long entry;
|
||||||
unsigned long rprocess;
|
unsigned long rprocess;
|
||||||
|
unsigned long at_phdr;
|
||||||
|
unsigned long at_phent;
|
||||||
|
unsigned long at_phnum;
|
||||||
char *args;
|
char *args;
|
||||||
unsigned long args_len;
|
unsigned long args_len;
|
||||||
char *envs;
|
char *envs;
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#include <aal/debug.h>
|
#include <aal/debug.h>
|
||||||
#include <page.h>
|
#include <page.h>
|
||||||
#include <cpulocal.h>
|
#include <cpulocal.h>
|
||||||
|
#include <auxvec.h>
|
||||||
|
|
||||||
#define DEBUG_PRINT_PROCESS
|
#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 envc, char **env)
|
||||||
{
|
{
|
||||||
int s_ind = 0;
|
int s_ind = 0;
|
||||||
@ -215,11 +217,16 @@ void init_process_stack(struct process *process, int argc, char **argv,
|
|||||||
USER_END,
|
USER_END,
|
||||||
virt_to_phys(stack), VR_STACK);
|
virt_to_phys(stack), VR_STACK);
|
||||||
|
|
||||||
p[-1] = 0; /* AT_NULL */
|
s_ind = -1;
|
||||||
p[-2] = 0;
|
p[s_ind--] = 0; /* AT_NULL */
|
||||||
p[-3] = USER_END - sizeof(unsigned long) * 2;
|
p[s_ind--] = 0;
|
||||||
p[-4] = 0; /* envp terminating NULL */
|
p[s_ind--] = pn->at_phnum; /* AT_PHNUM */
|
||||||
s_ind = -5;
|
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 */
|
/* envp */
|
||||||
for (arg_ind = envc - 1; arg_ind > -1; --arg_ind) {
|
for (arg_ind = envc - 1; arg_ind > -1; --arg_ind) {
|
||||||
p[s_ind--] = (unsigned long)env[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;
|
Elf64_Phdr phdr;
|
||||||
int i, j, nhdrs = 0;
|
int i, j, nhdrs = 0;
|
||||||
struct program_load_desc *desc;
|
struct program_load_desc *desc;
|
||||||
|
unsigned long load_addr = 0;
|
||||||
|
int load_addr_set = 0;
|
||||||
|
|
||||||
if (fread(&hdr, sizeof(hdr), 1, fp) < 1) {
|
if (fread(&hdr, sizeof(hdr), 1, fp) < 1) {
|
||||||
__eprint("Cannot read Ehdr.\n");
|
__eprint("Cannot read Ehdr.\n");
|
||||||
@ -103,11 +105,20 @@ struct program_load_desc *load_elf(FILE *fp)
|
|||||||
desc->sections[j].offset,
|
desc->sections[j].offset,
|
||||||
desc->sections[j].len);
|
desc->sections[j].len);
|
||||||
j++;
|
j++;
|
||||||
|
|
||||||
|
if (!load_addr_set) {
|
||||||
|
load_addr_set = 1;
|
||||||
|
load_addr = phdr.p_vaddr - phdr.p_offset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
desc->pid = getpid();
|
desc->pid = getpid();
|
||||||
desc->entry = hdr.e_entry;
|
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;
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,9 @@ struct program_load_desc {
|
|||||||
int pid;
|
int pid;
|
||||||
unsigned long entry;
|
unsigned long entry;
|
||||||
unsigned long rprocess;
|
unsigned long rprocess;
|
||||||
|
unsigned long at_phdr;
|
||||||
|
unsigned long at_phent;
|
||||||
|
unsigned long at_phnum;
|
||||||
char *args;
|
char *args;
|
||||||
unsigned long args_len;
|
unsigned long args_len;
|
||||||
char *envs;
|
char *envs;
|
||||||
|
|||||||
Reference in New Issue
Block a user