mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-31 00:24:51 +00:00
os: remove startup lib from dynamic programs
All the pre- and post-processing of the startup lib around the main function of a dynamic program is now done by LDSO. Hence LDSO directly calls the main function of the program. Issue #1042
This commit is contained in:
parent
8d21064b5e
commit
bd52e49698
@ -80,15 +80,6 @@ LIBS += ldso-startup
|
||||
|
||||
ifneq ($(LIB),$(DYNAMIC_LINKER))
|
||||
LIBS += $(DYNAMIC_LINKER)
|
||||
|
||||
#
|
||||
# Ensure that startup_dyn is build for the dynamic programs that depend on a
|
||||
# shared library. They add it to their dependencies as replacement for the
|
||||
# static-case startup as soon as they recognize that they are dynamic.
|
||||
# The current library in contrast filters-out startup_dyn from its
|
||||
# dependencies before they get merged.
|
||||
#
|
||||
LIBS += startup_dyn
|
||||
endif
|
||||
|
||||
#
|
||||
|
@ -126,17 +126,11 @@ $(LIB_A): $(OBJECTS)
|
||||
$(MSG_MERGE)$(LIB_A)
|
||||
$(VERBOSE)$(AR) -rc $@ $(OBJECTS)
|
||||
|
||||
#
|
||||
# Prevent linkage of startup_dyn as we added it only in order that it gets
|
||||
# build for the dynamic programs.
|
||||
#
|
||||
ifdef SHARED_LIB
|
||||
override DEPS := $(filter-out startup_dyn.lib,$(DEPS))
|
||||
|
||||
#
|
||||
# Prevent linkage of startup code and base libs against shared libraries except
|
||||
# for ld.lib.so
|
||||
#
|
||||
ifdef SHARED_LIB
|
||||
ifneq ($(LIB),ld)
|
||||
override DEPS := $(filter-out $(BASE_LIBS:=.lib) startup.lib,$(DEPS))
|
||||
endif
|
||||
|
@ -126,13 +126,9 @@ LD_CMD += -Wl,--dynamic-linker=$(DYNAMIC_LINKER).lib.so \
|
||||
-Wl,--eh-frame-hdr
|
||||
|
||||
#
|
||||
# Filter out the base libraries since they will be provided by the LDSO
|
||||
# library and the startup library as the CRT0 part of program startup is
|
||||
# done by LDSO already. As replacement for the startup library startup_dyn
|
||||
# is used. The startup_dyn build is triggered by any shared library without
|
||||
# merging it to the library.
|
||||
# Filter out the base libraries since they will be provided by the LDSO library
|
||||
#
|
||||
FILTER_DEPS := $(filter-out $(BASE_LIBS) startup,$(DEPS:.lib=)) startup_dyn
|
||||
FILTER_DEPS := $(filter-out $(BASE_LIBS) startup,$(DEPS:.lib=))
|
||||
SHARED_LIBS += $(LIB_CACHE_DIR)/$(DYNAMIC_LINKER)/$(DYNAMIC_LINKER).lib.so
|
||||
|
||||
#
|
||||
|
@ -56,7 +56,6 @@
|
||||
/* stack of the temporary initial environment */
|
||||
.p2align 4
|
||||
.space 32 * 1024
|
||||
.global _stack_high
|
||||
_stack_high:
|
||||
|
||||
/* initial value of the SP register */
|
||||
|
@ -59,7 +59,6 @@
|
||||
/* stack of the temporary initial environment */
|
||||
.p2align 4
|
||||
.space 32 * 1024
|
||||
.global _stack_high
|
||||
_stack_high:
|
||||
|
||||
/* initial value of the ESP, EAX and EDI register */
|
||||
|
@ -70,16 +70,15 @@
|
||||
/* stack of the temporary initial environment */
|
||||
.p2align 8
|
||||
.space 32 * 1024
|
||||
.global _stack_high
|
||||
_stack_high:
|
||||
|
||||
/* initial value of the RSP, RAX and RDI register */
|
||||
.globl __initial_sp
|
||||
.globl __initial_sp
|
||||
__initial_sp:
|
||||
.space 8
|
||||
.globl __initial_ax
|
||||
.globl __initial_ax
|
||||
__initial_ax:
|
||||
.space 8
|
||||
.globl __initial_di
|
||||
.globl __initial_di
|
||||
__initial_di:
|
||||
.space 8
|
||||
|
@ -1,5 +0,0 @@
|
||||
SRC_CC += _main.cc
|
||||
|
||||
REP_INC_DIR += src/platform
|
||||
|
||||
vpath _main.cc $(BASE_DIR)/src/platform
|
58
os/src/lib/ldso/call_program_main.cc
Normal file
58
os/src/lib/ldso/call_program_main.cc
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* \brief Call the main function of the dynamic program
|
||||
* \author Martin Stein
|
||||
* \date 2013-12-14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 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.
|
||||
*/
|
||||
|
||||
typedef void (*Func)(void);
|
||||
|
||||
int genode_atexit(Func);
|
||||
|
||||
extern "C" { void const ** get_program_var_addr(char const * name); }
|
||||
|
||||
extern char ** genode_argv;
|
||||
extern int genode_argc;
|
||||
extern char ** genode_envp;
|
||||
|
||||
/**
|
||||
* Cast a given function pointer into a 'void (*)()' function pointer
|
||||
*
|
||||
* \param ptr source function pointer
|
||||
*/
|
||||
template <typename Func_ptr>
|
||||
static Func * func(Func_ptr ptr)
|
||||
{
|
||||
return reinterpret_cast<Func *>(const_cast<void **>(ptr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the main function of the dynamic program
|
||||
*
|
||||
* \param main_ptr raw pointer of program main-function
|
||||
*
|
||||
* \return return value of the program main-function
|
||||
*/
|
||||
extern "C" int call_program_main(Func main_func)
|
||||
{
|
||||
/* call constructors of global objects of the program */
|
||||
Func * const _ctors_end = func(get_program_var_addr("_ctors_end"));
|
||||
Func * const _ctors_start = func(get_program_var_addr("_ctors_start"));
|
||||
for (Func * ctor = _ctors_end; ctor != _ctors_start; (*--ctor)());
|
||||
|
||||
/* register global-object destructors of program at LDSO atexit-array */
|
||||
Func * const _dtors_end = func(get_program_var_addr("_dtors_end"));
|
||||
Func * const _dtors_start = func(get_program_var_addr("_dtors_start"));
|
||||
for (Func * dtor = _dtors_start; dtor != _dtors_end; genode_atexit(*dtor++));
|
||||
|
||||
/* call main function of the program */
|
||||
typedef int (*Main)(int, char **, char **);
|
||||
Main const main = reinterpret_cast<Main>(main_func);
|
||||
return main(genode_argc, genode_argv, genode_envp);
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* \brief Call main function (ARM specific)
|
||||
* \author Sebastian Sumpf <Sebastian.Sumpf@genode-labs.com>
|
||||
* \author Martin Stein
|
||||
* \date 2011-05-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-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.
|
||||
*/
|
||||
#ifndef _ARM__CALL_MAIN_H_
|
||||
#define _ARM__CALL_MAIN_H_
|
||||
|
||||
void * my_stack_top();
|
||||
void set_program_var(const char *, const void *);
|
||||
|
||||
extern void * __initial_sp;
|
||||
|
||||
/**
|
||||
* Call program _main with the environment that its CRT0 would have created
|
||||
*
|
||||
* \param _main_fp pointer to _main function of dynamic program
|
||||
*/
|
||||
void call_main(void (*_main_fp)(void))
|
||||
{
|
||||
/* make initial value of some registers available to dynamic program */
|
||||
set_program_var("__initial_sp", __initial_sp);
|
||||
|
||||
/*
|
||||
* We could also do a call but that would enable the the program main to
|
||||
* return to LDSO wich isn't desired. This means also that not resetting
|
||||
* the SP to stack top as we do would waste stack memory for dead LDSO
|
||||
* frames.
|
||||
*/
|
||||
asm volatile ("mov sp, %[sp];"
|
||||
"bx %[ip];"
|
||||
:: [sp] "r" (my_stack_top()),
|
||||
[ip] "r" (_main_fp)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#endif /* _ARM__CALL_MAIN_H_ */
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* \brief Call main function (X86 specific)
|
||||
* \author Sebastian Sumpf <Sebastian.Sumpf@genode-labs.com>
|
||||
* \author Martin Stein
|
||||
* \date 2011-05-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-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.
|
||||
*/
|
||||
#ifndef _X86_32__CALL_MAIN_H_
|
||||
#define _X86_32__CALL_MAIN_H_
|
||||
|
||||
void * my_stack_top();
|
||||
void set_program_var(const char *, const void *);
|
||||
|
||||
extern void * __initial_sp;
|
||||
extern void * __initial_ax;
|
||||
extern void * __initial_di;
|
||||
|
||||
/**
|
||||
* Call program _main with the environment that its CRT0 would have created
|
||||
*
|
||||
* \param _main_fp pointer to _main function of dynamic program
|
||||
*/
|
||||
void call_main(void (*_main_fp)(void))
|
||||
{
|
||||
/* make initial value of some registers available to dynamic program */
|
||||
set_program_var("__initial_sp", __initial_sp);
|
||||
set_program_var("__initial_ax", __initial_ax);
|
||||
set_program_var("__initial_di", __initial_di);
|
||||
|
||||
/*
|
||||
* We could also do a call but that would enable the the program main to
|
||||
* return to LDSO wich isn't desired. This means also that not resetting
|
||||
* the SP to stack top as we do would waste stack memory for dead LDSO
|
||||
* frames.
|
||||
*/
|
||||
asm volatile ("mov %[sp], %%esp;"
|
||||
"xor %%ebp, %%ebp;"
|
||||
"jmp *%[ip];"
|
||||
:: [sp] "r" (my_stack_top()),
|
||||
[ip] "r" (_main_fp)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#endif /* _X86_32__CALL_MAIN_H_ */
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* \brief Call main function (X86 64 bit specific)
|
||||
* \author Sebastian Sumpf <Sebastian.Sumpf@genode-labs.com>
|
||||
* \author Martin Stein
|
||||
* \date 2011-05-011
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-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.
|
||||
*/
|
||||
#ifndef _X86_64__CALL_MAIN_H_
|
||||
#define _X86_64__CALL_MAIN_H_
|
||||
|
||||
void * my_stack_top();
|
||||
void set_program_var(const char *, const void *);
|
||||
|
||||
extern void * __initial_sp;
|
||||
extern void * __initial_ax;
|
||||
extern void * __initial_di;
|
||||
|
||||
/**
|
||||
* Call program _main with the environment that its CRT0 would have created
|
||||
*
|
||||
* \param _main_fp pointer to _main function of dynamic program
|
||||
*/
|
||||
void call_main(void (*_main_fp)(void))
|
||||
{
|
||||
/* make initial value of some registers available to dynamic program */
|
||||
set_program_var("__initial_sp", __initial_sp);
|
||||
set_program_var("__initial_ax", __initial_ax);
|
||||
set_program_var("__initial_di", __initial_di);
|
||||
|
||||
/*
|
||||
* We could also do a call but that would enable the the program main to
|
||||
* return to LDSO wich isn't desired. This means also that not resetting
|
||||
* the SP to stack top as we do would waste stack memory for dead LDSO
|
||||
* frames.
|
||||
*/
|
||||
asm volatile ("movq %[sp], %%rsp;"
|
||||
"xorq %%rbp, %%rbp;"
|
||||
"jmpq *%[ip];"
|
||||
:: [sp] "r" (my_stack_top()),
|
||||
[ip] "r" (_main_fp)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#endif /* _X86_64__CALL_MAIN_H_ */
|
@ -19,8 +19,6 @@
|
||||
#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)();
|
||||
@ -30,6 +28,9 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp);
|
||||
|
||||
extern char **lx_environ;
|
||||
|
||||
int call_program_main(void (*main_func)(void));
|
||||
|
||||
|
||||
static void *setup_stack(const char *name, long fd)
|
||||
{
|
||||
char **p;
|
||||
@ -86,27 +87,8 @@ int main(int argc, char **argv)
|
||||
|
||||
/* build dummy stack */
|
||||
void *sp = setup_stack(binary, (long)fd);
|
||||
func_ptr_type const program_main = _rtld(sp, &exit_proc, &objp);
|
||||
|
||||
/* DEBUGGING
|
||||
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);
|
||||
|
||||
printf("Starting application ... environ: %p\n", lx_environ);
|
||||
*/
|
||||
|
||||
/* start loaded application */
|
||||
call_main(main_func);
|
||||
|
||||
exit_proc();
|
||||
|
||||
printf("Exiting ldso\n");
|
||||
return 0;
|
||||
/* call main function of dynamic program */
|
||||
return call_program_main(program_main);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ SRC_S = rtld_start.S
|
||||
SRC_C = reloc.c rtld.c map_object.c xmalloc.c debug.c main.c \
|
||||
ldso_types.c rtld_dummies.c platform.c
|
||||
SRC_CC = stdio.cc stdlib.cc file.cc err.cc string.cc lock.cc \
|
||||
test.cc environ.cc thread.cc
|
||||
test.cc environ.cc call_program_main.cc
|
||||
|
||||
INC_DIR += $(DIR)/ \
|
||||
$(DIR)/contrib \
|
||||
|
@ -1,24 +0,0 @@
|
||||
/*
|
||||
* \brief Thread related C helpers
|
||||
* \author Martin Stein
|
||||
* \date 2013-12-13
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
|
||||
|
||||
/**
|
||||
* Return top end of the stack of the calling thread
|
||||
*/
|
||||
extern "C" void * my_stack_top()
|
||||
{
|
||||
return Genode::Thread_base::myself()->stack_top();
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
* Program doesn't need to startup with CRT0 as LDSO has done this
|
||||
* initialization during its own CRT0 already.
|
||||
*/
|
||||
ENTRY(_main)
|
||||
ENTRY(main)
|
||||
|
||||
PHDRS
|
||||
{
|
||||
@ -171,6 +171,7 @@ SECTIONS
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
@ -181,17 +182,20 @@ SECTIONS
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
KEEP (*(.init_array)) /* list of constructors specific for ARM eabi */
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
_ctors_end = .;
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
_dtors_start = .;
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
_dtors_start = .;
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
_dtors_end = .;
|
||||
}
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
@ -217,6 +221,9 @@ SECTIONS
|
||||
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
|
||||
__dso_handle = .;
|
||||
LONG(0x0);
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
_edata = .; PROVIDE (edata = .);
|
||||
|
Loading…
x
Reference in New Issue
Block a user