From 1a26f334695ec20bae758ddb29be2004c8e24f90 Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Thu, 8 Jan 2015 12:31:36 +0100 Subject: [PATCH] ldso: shared-object lock and ctor test This has to be used during shared object creation and destruction because global lists are manipulated. We cannot use the 'Elf_object::lock' here because there may be jump-slot relocations during object initialization. Fixes #1350 --- repos/base/src/lib/ldso/main.cc | 15 +++++++++-- repos/libports/run/ldso.run | 4 +++ repos/libports/src/test/ldso/lib_dl.cc | 37 ++++++++++++++++++++++++++ repos/libports/src/test/ldso/main.cc | 23 ++++++++++++++++ 4 files changed, 77 insertions(+), 2 deletions(-) diff --git a/repos/base/src/lib/ldso/main.cc b/repos/base/src/lib/ldso/main.cc index f2876f89b..3780423a9 100644 --- a/repos/base/src/lib/ldso/main.cc +++ b/repos/base/src/lib/ldso/main.cc @@ -1100,6 +1100,17 @@ static Root_object *to_root(void *h) } +/** + * Needed during shared object creation and destruction, since global lists are + * manipulated + */ +static Genode::Lock & shared_object_lock() +{ + static Genode::Lock _lock; + return _lock; +} + + Genode::Shared_object::Shared_object(char const *file, unsigned flags) { using namespace Linker; @@ -1108,7 +1119,7 @@ Genode::Shared_object::Shared_object(char const *file, unsigned flags) PDBG("open '%s'", file ? file : "binary"); try { - Genode::Lock::Guard guard(Elf_object::lock()); + Genode::Lock::Guard guard(shared_object_lock()); /* update bind now variable */ bind_now = (flags & Shared_object::NOW) ? true : false; @@ -1150,7 +1161,7 @@ Genode::Shared_object::~Shared_object() if (verbose_shared) PDBG("close"); - Genode::Lock::Guard guard(Elf_object::lock()); + Genode::Lock::Guard guard(shared_object_lock()); destroy(Genode::env()->heap(), to_root(_handle)); } diff --git a/repos/libports/run/ldso.run b/repos/libports/run/ldso.run index eabba888f..bfd763f98 100644 --- a/repos/libports/run/ldso.run +++ b/repos/libports/run/ldso.run @@ -120,6 +120,10 @@ compare_output_to { [init -> test-ldso] ------------ [init -> test-ldso] 'Object' called: good [init -> test-ldso] +[init -> test-ldso] Shared-object API +[init -> test-ldso] ----------------- +[init -> test-ldso] Global object constructed +[init -> test-ldso] [init -> test-ldso] Destruction [init -> test-ldso] ----------- [init -> test-ldso] ~Lib_2_local 55667785 diff --git a/repos/libports/src/test/ldso/lib_dl.cc b/repos/libports/src/test/ldso/lib_dl.cc index 04fbbced2..4ff2d8620 100644 --- a/repos/libports/src/test/ldso/lib_dl.cc +++ b/repos/libports/src/test/ldso/lib_dl.cc @@ -1,6 +1,43 @@ +/* + * \brief Test for the use of 'Shared_object' API + * \author Sebastian Sumpf + * \author Norman Feske + * \date 2014-05-20 + */ + +/* + * Copyright (C) 2014-2015 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 + +/* test-local includes */ #include "test-ldso.h" +using namespace Genode; + +struct Global_object +{ + Global_object() + { + Genode::printf("Global object constructed\n"); + } +}; + +/* + * The 'global_object' is expected to be construced at the load time of the + * shared object. + */ +Global_object global_object; + + +/* + * XXX currently untested + */ extern "C" void lib_dl_symbol() { Genode::printf("called (from '%s')\n", __func__); diff --git a/repos/libports/src/test/ldso/main.cc b/repos/libports/src/test/ldso/main.cc index 8d8b4f28d..1cf6e4a7f 100644 --- a/repos/libports/src/test/ldso/main.cc +++ b/repos/libports/src/test/ldso/main.cc @@ -14,6 +14,8 @@ #include #include #include +#include + using namespace Genode; /* shared-lib includes */ @@ -160,6 +162,23 @@ static void test_dynamic_cast() } +/*********************** + ** Shared-object API ** + ***********************/ + +static void test_shared_object_api() +{ + /* + * When loading the shared object, we expect the global constructor + * that is present in the library to print a message. + * + * 'lib_dl_so' is a local variable such that its destructor is called + * when leaving the scope of the function. + */ + Shared_object lib_dl_so("test-ldso_lib_dl.lib.so"); +} + + /** * Main function of LDSO test */ @@ -229,6 +248,10 @@ int main(int argc, char **argv) test_dynamic_cast(); printf("\n"); + printf("Shared-object API\n"); + printf("-----------------\n"); + test_shared_object_api(); + printf("\n"); printf("Destruction\n"); printf("-----------\n");