110 lines
2.4 KiB
C
110 lines
2.4 KiB
C
/*
|
|
* \brief libc startup code
|
|
* \author Sebastian Sumpf
|
|
* \date 2009-10-26
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2009-2013 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU General Public License version 2.
|
|
*/
|
|
|
|
#include <dlfcn.h>
|
|
#include <fcntl.h>
|
|
#include <rtld.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/param.h>
|
|
#include <base/crt0.h>
|
|
#include <call_main.h>
|
|
#include "file.h"
|
|
|
|
typedef void (*func_ptr_type)();
|
|
|
|
func_ptr_type
|
|
_rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp);
|
|
|
|
extern char **lx_environ;
|
|
|
|
static void *setup_stack(const char *name, long fd)
|
|
{
|
|
char **p;
|
|
int env_count = 0;
|
|
char *env_end = '\0';
|
|
|
|
if (!lx_environ) {
|
|
lx_environ = &env_end;
|
|
}
|
|
|
|
for (p = lx_environ; *p; p++, env_count++) ;
|
|
env_count++;
|
|
|
|
long sp_argc = 1;
|
|
const char *sp_argv[] = { name, '\0' };
|
|
char *sp_at[] = {
|
|
(char*)AT_BASE, //map base of ldso
|
|
(char*)LINK_ADDRESS,
|
|
(char*)AT_EXECFD, //file handle of program to load
|
|
(char*)fd,
|
|
(char*)AT_NULL, //AT terminator
|
|
};
|
|
|
|
void *sp = malloc(sizeof(sp_argc) + sizeof(sp_argv) + (env_count * sizeof(long))
|
|
+ sizeof(sp_at));
|
|
void *sp_tmp = sp;
|
|
|
|
//build dummy stack
|
|
memcpy(sp_tmp, &sp_argc, sizeof(sp_argc)); //argc
|
|
sp_tmp += sizeof(sp_argc);
|
|
memcpy(sp_tmp, sp_argv, sizeof(sp_argv)); //argv
|
|
sp_tmp += sizeof(sp_argv);
|
|
memcpy(sp_tmp, lx_environ, env_count * sizeof(long)); //environ
|
|
sp_tmp += env_count * sizeof(long);
|
|
memcpy(sp_tmp, sp_at, sizeof(sp_at)); //auxiliary vector
|
|
|
|
return sp;
|
|
}
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
char *binary = "binary";
|
|
char binary_buf[64];
|
|
|
|
Obj_Entry *objp;
|
|
func_ptr_type exit_proc;
|
|
|
|
int fd = open(binary, O_RDONLY);
|
|
|
|
/* find file name of file descriptor */
|
|
if (!find_binary_name(fd, binary_buf, sizeof(binary_buf)))
|
|
binary = binary_buf;
|
|
|
|
/* build dummy stack */
|
|
void *sp = setup_stack(binary, (long)fd);
|
|
|
|
printf("Starting ldso ...\n");
|
|
|
|
/* this is usually '_start' */
|
|
func_ptr_type main_func = _rtld(sp, &exit_proc, &objp);
|
|
|
|
/* DEBUGGING
|
|
char **p;
|
|
for(p = environ; *p; p++)
|
|
printf("env: %s\n", *p);
|
|
*/
|
|
/* start loaded application */
|
|
printf("Starting application ... environ: %p\n", lx_environ);
|
|
|
|
call_main(main_func);
|
|
|
|
exit_proc();
|
|
|
|
printf("Exiting ldso\n");
|
|
return 0;
|
|
}
|