From bd52e49698b18e578313bb28db9fd951c961ba1a Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Wed, 5 Feb 2014 15:18:21 +0100 Subject: [PATCH] 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 --- base/mk/dep_lib.mk | 9 ---- base/mk/lib.mk | 8 +-- base/mk/prg.mk | 8 +-- base/src/platform/arm/crt0.s | 1 - base/src/platform/x86_32/crt0.s | 1 - base/src/platform/x86_64/crt0.s | 7 ++- os/lib/mk/startup_dyn.mk | 5 -- os/src/lib/ldso/call_program_main.cc | 58 ++++++++++++++++++++++ os/src/lib/ldso/include/arm/call_main.h | 45 ----------------- os/src/lib/ldso/include/x86_32/call_main.h | 50 ------------------- os/src/lib/ldso/include/x86_64/call_main.h | 50 ------------------- os/src/lib/ldso/main.c | 30 +++-------- os/src/lib/ldso/target.inc | 2 +- os/src/lib/ldso/thread.cc | 24 --------- os/src/platform/genode_dyn.ld | 13 +++-- 15 files changed, 81 insertions(+), 230 deletions(-) delete mode 100644 os/lib/mk/startup_dyn.mk create mode 100644 os/src/lib/ldso/call_program_main.cc delete mode 100644 os/src/lib/ldso/include/arm/call_main.h delete mode 100644 os/src/lib/ldso/include/x86_32/call_main.h delete mode 100644 os/src/lib/ldso/include/x86_64/call_main.h delete mode 100644 os/src/lib/ldso/thread.cc diff --git a/base/mk/dep_lib.mk b/base/mk/dep_lib.mk index c0afbfe73..b6684ea59 100644 --- a/base/mk/dep_lib.mk +++ b/base/mk/dep_lib.mk @@ -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 # diff --git a/base/mk/lib.mk b/base/mk/lib.mk index 4ae589084..bdbb6540d 100644 --- a/base/mk/lib.mk +++ b/base/mk/lib.mk @@ -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 diff --git a/base/mk/prg.mk b/base/mk/prg.mk index eec62acdd..937fec869 100644 --- a/base/mk/prg.mk +++ b/base/mk/prg.mk @@ -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 # diff --git a/base/src/platform/arm/crt0.s b/base/src/platform/arm/crt0.s index 0c211993c..704980ade 100644 --- a/base/src/platform/arm/crt0.s +++ b/base/src/platform/arm/crt0.s @@ -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 */ diff --git a/base/src/platform/x86_32/crt0.s b/base/src/platform/x86_32/crt0.s index 35986d9a8..776b4c54c 100644 --- a/base/src/platform/x86_32/crt0.s +++ b/base/src/platform/x86_32/crt0.s @@ -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 */ diff --git a/base/src/platform/x86_64/crt0.s b/base/src/platform/x86_64/crt0.s index c193df226..d797f2a22 100644 --- a/base/src/platform/x86_64/crt0.s +++ b/base/src/platform/x86_64/crt0.s @@ -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 diff --git a/os/lib/mk/startup_dyn.mk b/os/lib/mk/startup_dyn.mk deleted file mode 100644 index 071947c57..000000000 --- a/os/lib/mk/startup_dyn.mk +++ /dev/null @@ -1,5 +0,0 @@ -SRC_CC += _main.cc - -REP_INC_DIR += src/platform - -vpath _main.cc $(BASE_DIR)/src/platform diff --git a/os/src/lib/ldso/call_program_main.cc b/os/src/lib/ldso/call_program_main.cc new file mode 100644 index 000000000..5dee701f6 --- /dev/null +++ b/os/src/lib/ldso/call_program_main.cc @@ -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 +static Func * func(Func_ptr ptr) +{ + return reinterpret_cast(const_cast(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_func); + return main(genode_argc, genode_argv, genode_envp); +} diff --git a/os/src/lib/ldso/include/arm/call_main.h b/os/src/lib/ldso/include/arm/call_main.h deleted file mode 100644 index a26f731fc..000000000 --- a/os/src/lib/ldso/include/arm/call_main.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * \brief Call main function (ARM specific) - * \author Sebastian Sumpf - * \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_ */ diff --git a/os/src/lib/ldso/include/x86_32/call_main.h b/os/src/lib/ldso/include/x86_32/call_main.h deleted file mode 100644 index e122b42f6..000000000 --- a/os/src/lib/ldso/include/x86_32/call_main.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * \brief Call main function (X86 specific) - * \author Sebastian Sumpf - * \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_ */ diff --git a/os/src/lib/ldso/include/x86_64/call_main.h b/os/src/lib/ldso/include/x86_64/call_main.h deleted file mode 100644 index 0e2b07dbc..000000000 --- a/os/src/lib/ldso/include/x86_64/call_main.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * \brief Call main function (X86 64 bit specific) - * \author Sebastian Sumpf - * \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_ */ diff --git a/os/src/lib/ldso/main.c b/os/src/lib/ldso/main.c index 396958162..fe4450fe5 100644 --- a/os/src/lib/ldso/main.c +++ b/os/src/lib/ldso/main.c @@ -19,8 +19,6 @@ #include #include #include -#include -#include #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); } diff --git a/os/src/lib/ldso/target.inc b/os/src/lib/ldso/target.inc index 8aac802ff..e4fd6e138 100644 --- a/os/src/lib/ldso/target.inc +++ b/os/src/lib/ldso/target.inc @@ -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 \ diff --git a/os/src/lib/ldso/thread.cc b/os/src/lib/ldso/thread.cc deleted file mode 100644 index 88672aae7..000000000 --- a/os/src/lib/ldso/thread.cc +++ /dev/null @@ -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 - - -/** - * Return top end of the stack of the calling thread - */ -extern "C" void * my_stack_top() -{ - return Genode::Thread_base::myself()->stack_top(); -} diff --git a/os/src/platform/genode_dyn.ld b/os/src/platform/genode_dyn.ld index bd07adca3..7402b301e 100644 --- a/os/src/platform/genode_dyn.ld +++ b/os/src/platform/genode_dyn.ld @@ -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 = .);