populate ELF header information on the initial stack so that glibc can set up TLS properly

This commit is contained in:
Balazs Gerofi bgerofi@riken.jp
2012-10-09 00:51:50 +09:00
parent f1da972bb7
commit 9a8449df2b
7 changed files with 67 additions and 8 deletions

View File

@ -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
View 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 */

View File

@ -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,

View File

@ -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;

View File

@ -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];

View File

@ -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;
} }

View File

@ -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;