From 42fddf8390c0436a09cf6fae3391f9a26098e4de Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Thu, 2 Apr 2020 08:19:34 +0200 Subject: [PATCH] Cleanup shared-object support mechanics The former ldso-startup static library (now called ldso_so_support) is used to spice each shared object/library with local support code for the dynamic linker (execution of static constructors and ARM-EABI). Therefore, the library must be statically linked to each dynamic library. As a result recipes for dynamic libraries must always depend on the "so" API, which makes ldso_so_support.mk and so_support.c available independent of "base". Additionally, ldso_so_support is also provided in the libc API to cut the dependency early for libc/posix libraries. Issue #3720 --- repos/base/lib/mk/ldso-startup.mk | 3 - repos/base/lib/mk/ldso_so_support.mk | 3 + repos/base/lib/mk/spec/arm/ldso-startup.mk | 5 -- repos/base/mk/dep_lib.mk | 2 +- repos/base/mk/lib.mk | 9 +-- repos/base/recipes/api/base/content.mk | 7 +- repos/base/recipes/api/so/content.mk | 4 +- repos/base/src/lib/ldso/so_support.c | 71 +++++++++++++++++++ repos/base/src/lib/ldso/startup/startup.cc | 38 ---------- .../base/src/lib/ldso/startup/unwind_exidx.cc | 48 ------------- repos/libports/recipes/api/libc/content.mk | 6 ++ repos/libports/recipes/api/posix/content.mk | 6 +- .../libports/recipes/src/test-ldso/used_apis | 1 + repos/os/recipes/src/vfs/used_apis | 1 + 14 files changed, 95 insertions(+), 109 deletions(-) delete mode 100644 repos/base/lib/mk/ldso-startup.mk create mode 100644 repos/base/lib/mk/ldso_so_support.mk delete mode 100644 repos/base/lib/mk/spec/arm/ldso-startup.mk create mode 100644 repos/base/src/lib/ldso/so_support.c delete mode 100644 repos/base/src/lib/ldso/startup/startup.cc delete mode 100644 repos/base/src/lib/ldso/startup/unwind_exidx.cc diff --git a/repos/base/lib/mk/ldso-startup.mk b/repos/base/lib/mk/ldso-startup.mk deleted file mode 100644 index e0968d7dc..000000000 --- a/repos/base/lib/mk/ldso-startup.mk +++ /dev/null @@ -1,3 +0,0 @@ -SRC_CC += startup.cc - -vpath startup.cc $(BASE_DIR)/src/lib/ldso/startup diff --git a/repos/base/lib/mk/ldso_so_support.mk b/repos/base/lib/mk/ldso_so_support.mk new file mode 100644 index 000000000..e7cc454a4 --- /dev/null +++ b/repos/base/lib/mk/ldso_so_support.mk @@ -0,0 +1,3 @@ +SRC_C = so_support.c + +vpath so_support.c $(call select_from_repositories,src/lib/ldso) diff --git a/repos/base/lib/mk/spec/arm/ldso-startup.mk b/repos/base/lib/mk/spec/arm/ldso-startup.mk deleted file mode 100644 index c2c0682d8..000000000 --- a/repos/base/lib/mk/spec/arm/ldso-startup.mk +++ /dev/null @@ -1,5 +0,0 @@ -SRC_CC += unwind_exidx.cc - -vpath unwind_exidx.cc $(REP_DIR)/src/lib/ldso/startup - -include $(call select_from_repositories,lib/mk/ldso-startup.mk) diff --git a/repos/base/mk/dep_lib.mk b/repos/base/mk/dep_lib.mk index b3c980c90..21fcb77e5 100644 --- a/repos/base/mk/dep_lib.mk +++ b/repos/base/mk/dep_lib.mk @@ -81,7 +81,7 @@ include $(BASE_DIR)/mk/base-libs.mk include $(LIB_MK) ifdef SHARED_LIB -LIBS += ldso-startup +LIBS += ldso_so_support endif # diff --git a/repos/base/mk/lib.mk b/repos/base/mk/lib.mk index c482457af..bfee2c742 100644 --- a/repos/base/mk/lib.mk +++ b/repos/base/mk/lib.mk @@ -181,10 +181,11 @@ $(LIB_A): $(OBJECTS) $(VERBOSE)$(AR) -rcs $@ $(OBJECTS) # -# Link ldso-startup library to each shared library +# Link ldso-support library to each shared library to provide local hook +# functions for constructors and ARM # ifdef SHARED_LIB -override ARCHIVES += ldso-startup.lib.a +override ARCHIVES += ldso_so_support.lib.a endif # @@ -208,10 +209,6 @@ STATIC_LIBS_BRIEF := $(subst $(LIB_CACHE_DIR),$$libs,$(STATIC_LIBS)) # (LIB_SO_DEPS) to the library to store the library-dependency information in # the generated shared object. # -# The 'ldso-startup/startup.o' object file, which contains the support code for -# constructing static objects must be specified as object file to prevent the -# linker from garbage-collecting it. -# # # Default entry point of shared libraries diff --git a/repos/base/recipes/api/base/content.mk b/repos/base/recipes/api/base/content.mk index 0ff64b1a9..fe34ad072 100644 --- a/repos/base/recipes/api/base/content.mk +++ b/repos/base/recipes/api/base/content.mk @@ -7,7 +7,7 @@ include: mkdir -p include cp -r $(REP_DIR)/include/* $@/ -LIB_MK_FILES := base.mk ld.mk ldso-startup.mk +LIB_MK_FILES := base.mk ld.mk ldso_so_support.mk lib: mkdir -p lib/mk lib/symbols @@ -21,6 +21,11 @@ mk/spec: mkdir -p $@ cp $(foreach spec,$(SPECS),$(REP_DIR)/mk/spec/$(spec).mk) $@ +content: lib/mk/ldso_so_support.mk src/lib/ldso/so_support.c + +lib/mk/ldso_so_support.mk src/lib/ldso/so_support.c: + $(mirror_from_rep_dir) + LICENSE: cp $(GENODE_DIR)/LICENSE $@ diff --git a/repos/base/recipes/api/so/content.mk b/repos/base/recipes/api/so/content.mk index b00adfd66..bba814c96 100644 --- a/repos/base/recipes/api/so/content.mk +++ b/repos/base/recipes/api/so/content.mk @@ -1,6 +1,6 @@ -content: lib/mk/ldso-startup.mk LICENSE +content: lib/mk/ldso_so_support.mk src/lib/ldso/so_support.c LICENSE -lib/mk/ldso-startup.mk: +lib/mk/ldso_so_support.mk src/lib/ldso/so_support.c: $(mirror_from_rep_dir) LICENSE: diff --git a/repos/base/src/lib/ldso/so_support.c b/repos/base/src/lib/ldso/so_support.c new file mode 100644 index 000000000..3f09e9e07 --- /dev/null +++ b/repos/base/src/lib/ldso/so_support.c @@ -0,0 +1,71 @@ +/** + * \brief Shared-object support code + * \author Sebastian Sumpf + * \author Christian Helmuth + * \date 2009-08-14 + * + * Support code comprises hooks for execution of static constructors and + * ARM-EABI dynamic linking. + * + * The ARM cross compiler uses the __gnu_Unwind_Find_exidx hook to locate a + * 'ARM.exidx' section within a shared object. For this to work + * 'dl_unwind_find_exidx' is excuted by 'ldso', which returns the section + * address if it finds a shared object within the range of the provieded + * program counter. + */ + +/* + * Copyright (C) 2009-2020 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#define BEG { (ld_hook) ~1U } +#define END { (ld_hook) 0 } +#define SECTION(x) __attribute__((used,section( x ))) + +typedef void (*ld_hook)(void); +static ld_hook _lctors_start[1] SECTION("_mark_ctors_start") = BEG; +static ld_hook _lctors_end[1] SECTION("_mark_ctors_end") = END; + +/* + * '__dso_handle' needs to be defined in the main program and in each shared + * object. Because ld.lib.so is both of them, '__dso_handle' is weak here. + */ +void *__dso_handle __attribute__((__visibility__("hidden"))) + __attribute__((weak)) = &__dso_handle; + +/* called by dynamic linker on library startup (ld.lib.so) */ +extern void _init(void) __attribute__((used,section(".init"))); +extern void _init(void) +{ + /* call static constructors */ + for (ld_hook *func = _lctors_end; func > _lctors_start + 1; (*--func)()); +} + + +/* + * from gcc/config/arm/unwind-arm.h + */ +typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__))); + + +/* + * Dummy for static libs, implemented in ldso for dynamic case + */ +extern _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount) __attribute__((weak)); +extern _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount) +{ + return 0; +} + + +/* + * Called from libgcc_eh.a file 'gcc/config/arm/unwind-arm.c' in function + * 'get_eit_entry' + */ +extern _Unwind_Ptr __gnu_Unwind_Find_exidx (_Unwind_Ptr pc, int *pcount) +{ + return dl_unwind_find_exidx(pc, pcount); +} diff --git a/repos/base/src/lib/ldso/startup/startup.cc b/repos/base/src/lib/ldso/startup/startup.cc deleted file mode 100644 index 5032c589e..000000000 --- a/repos/base/src/lib/ldso/startup/startup.cc +++ /dev/null @@ -1,38 +0,0 @@ -/** - * \brief Shared object startup code - * \author Sebastian Sumpf - * \date 2009-08-14 - */ - -/* - * Copyright (C) 2009-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#define BEG { (ld_hook) ~1U } -#define END { (ld_hook) 0 } -#define SECTION(x) __attribute__((used,section( x ))) - -typedef void (*ld_hook)(void); -static ld_hook _lctors_start[1] SECTION("_mark_ctors_start") = BEG; -static ld_hook _lctors_end[1] SECTION("_mark_ctors_end") = END; - -/* - * '__dso_handle' needs to be defined in the main program and in each shared - * object. Because ld.lib.so is both of them, '__dso_handle' is weak here. - */ -void *__dso_handle __attribute__((__visibility__("hidden"))) - __attribute__((weak)) = &__dso_handle; - -/* called by dynamic linker on library startup (ld-genode.so) */ -extern "C" { - void _init(void) __attribute__((used,section(".init"))); - - void _init(void) - { - /* call static constructors */ - for(ld_hook *func = _lctors_end; func > _lctors_start + 1; (*--func)()); - } -} diff --git a/repos/base/src/lib/ldso/startup/unwind_exidx.cc b/repos/base/src/lib/ldso/startup/unwind_exidx.cc deleted file mode 100644 index b5b63619e..000000000 --- a/repos/base/src/lib/ldso/startup/unwind_exidx.cc +++ /dev/null @@ -1,48 +0,0 @@ -/* - * \brief Our implementation of __gnu_Unwind_Find_exidx - * \author Sebastian Sumpf - * \date 2010-07-05 - * - * This file is used for ARM-EABI dynamic linking, only. The ARM cross-compiler - * uses this hook to locate a 'ARM.exidx' section within a shared object. For - * this to work 'dl_unwind_find_exidx' is excuted by 'ldso', which returns the - * section address if it finds a shared object within the range of the provieded - * progam counter - */ - -/* - * Copyright (C) 2010-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#include - -/* - * from gcc/config/arm/unwind-arm.h - */ -typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__))); - - -/* - * Implemented in ldso - * */ -extern "C" _Unwind_Ptr __attribute__((weak)) dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount); -extern "C" _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr /* pc */, int * /* pcount */) -{ - Genode::error("dl_unwind_find_exidx called"); - return 0; -} - - -/* - * Called from libgcc_eh.a file 'gcc/config/arm/unwind-arm.c' in function - * 'get_eit_entry' - */ -extern "C" _Unwind_Ptr __gnu_Unwind_Find_exidx (_Unwind_Ptr pc, int *pcount) -{ - return dl_unwind_find_exidx(pc, pcount); -} - - diff --git a/repos/libports/recipes/api/libc/content.mk b/repos/libports/recipes/api/libc/content.mk index b44625092..3d664a812 100644 --- a/repos/libports/recipes/api/libc/content.mk +++ b/repos/libports/recipes/api/libc/content.mk @@ -18,6 +18,12 @@ include: cp -r $(REP_DIR)/include/libc-genode $@/ cp $(REP_DIR)/src/lib/libc/internal/legacy.h $@/libc/ +content: lib/mk/ldso_so_support.mk src/lib/ldso/so_support.c + +lib/mk/ldso_so_support.mk src/lib/ldso/so_support.c: + mkdir -p $(dir $@) + cp $(GENODE_DIR)/repos/base/$@ $@ + content: LICENSE LICENSE: diff --git a/repos/libports/recipes/api/posix/content.mk b/repos/libports/recipes/api/posix/content.mk index 191129c42..2b1c71cee 100644 --- a/repos/libports/recipes/api/posix/content.mk +++ b/repos/libports/recipes/api/posix/content.mk @@ -1,14 +1,10 @@ MIRROR_FROM_REP_DIR := lib/symbols/posix lib/import/import-posix.mk -content: $(MIRROR_FROM_REP_DIR) LICENSE lib/mk/base.mk lib/mk/ldso-startup.mk +content: $(MIRROR_FROM_REP_DIR) LICENSE $(MIRROR_FROM_REP_DIR): $(mirror_from_rep_dir) -lib/mk/base.mk lib/mk/ldso-startup.mk: - mkdir -p $(dir $@) - touch $@ - LICENSE: cp $(GENODE_DIR)/LICENSE $@ diff --git a/repos/libports/recipes/src/test-ldso/used_apis b/repos/libports/recipes/src/test-ldso/used_apis index dccf4f6fb..24ad7bab4 100644 --- a/repos/libports/recipes/src/test-ldso/used_apis +++ b/repos/libports/recipes/src/test-ldso/used_apis @@ -1,2 +1,3 @@ base libc +so diff --git a/repos/os/recipes/src/vfs/used_apis b/repos/os/recipes/src/vfs/used_apis index ab1887fbe..3b02d691a 100644 --- a/repos/os/recipes/src/vfs/used_apis +++ b/repos/os/recipes/src/vfs/used_apis @@ -6,3 +6,4 @@ report_session rtc_session terminal_session vfs +so