We want the init of the elf object to use the tls defined when the new thread is started.
Delay this initialization. Signed-off-by: Benoît Canet <[email protected]> --- core/app.cc | 4 +++- core/elf.cc | 49 ++++++++++++++++++++++++++++++++++++++++++++----- include/osv/elf.hh | 6 +++++- 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/core/app.cc b/core/app.cc index 773d80e..0bfcedd 100644 --- a/core/app.cc +++ b/core/app.cc @@ -174,7 +174,8 @@ application::application(const std::string& command, merge_in_environ(new_program, env); prepare_argv(); - _lib = current_program->get_library(_command); + std::vector<std::string> extra_path; + _lib = current_program->get_library(_command, extra_path, true); } catch(const std::exception &e) { throw launch_error(e.what()); } @@ -278,6 +279,7 @@ void application::main() { __libc_stack_end = __builtin_frame_address(0); + elf::get_program()->init_library(); sched::thread::current()->set_name(_command); if (_main) { diff --git a/core/elf.cc b/core/elf.cc index efa574e..bf2137c 100644 --- a/core/elf.cc +++ b/core/elf.cc @@ -1164,25 +1164,64 @@ program::load_object(std::string name, std::vector<std::string> extra_path, } std::shared_ptr<object> -program::get_library(std::string name, std::vector<std::string> extra_path) +program::get_library(std::string name, std::vector<std::string> extra_path, bool no_init) { SCOPE_LOCK(_mutex); std::vector<std::shared_ptr<object>> loaded_objects; auto ret = load_object(name, extra_path, loaded_objects); + + // Push the loaded object on a stack + // init_library is to be called later at an arbitraty time + // and operate on the list of loaded_objects. Since a library + // can load another one like java.so does in OSv we want a stack + // structure so each init_library call get it's corresponding + // list of objects to operate on. + + // Build a vector of weak pointer so it will not prevent anyone + // from unloading a .so properly while giving init_library some + // safety. + std::vector<std::weak_ptr<object>> weak_objects; + for (auto obj: loaded_objects) { + weak_objects.push_back(obj); + } + // push the weak pointer on the stack + _loaded_objects_stack.push(weak_objects); + if (ret) { ret->init_static_tls(); } + + if (no_init) { + return ret; + } + + init_library(); + + return ret; +} + +void program::init_library() +{ + // get the list of weak pointers before iterating on them + std::vector<std::weak_ptr<object>> weak_objects = + _loaded_objects_stack.top(); + // After loading the object and all its needed objects, run these objects' // init functions in reverse order (so those of deepest needed object runs // first) and finally make the loaded objects visible in search order. - auto size = loaded_objects.size(); + auto size = weak_objects.size(); for (int i = size - 1; i >= 0; i--) { - loaded_objects[i]->run_init_funcs(); + if (auto obj = weak_objects[i].lock()) { + obj->run_init_funcs(); + } } for (unsigned i = 0; i < size; i++) { - loaded_objects[i]->setprivate(false); + if (auto obj = weak_objects[i].lock()) { + obj->setprivate(false); + } } - return ret; + + _loaded_objects_stack.pop(); } void program::remove_object(object *ef) diff --git a/include/osv/elf.hh b/include/osv/elf.hh index fabc6e6..d26b22c 100644 --- a/include/osv/elf.hh +++ b/include/osv/elf.hh @@ -11,6 +11,7 @@ #include "fs/fs.hh" #include <vector> #include <map> +#include <stack> #include <memory> #include <unordered_set> #include <osv/types.h> @@ -525,7 +526,9 @@ public: * set_search_path(). */ std::shared_ptr<elf::object> - get_library(std::string lib, std::vector<std::string> extra_path = {}); + get_library(std::string lib, std::vector<std::string> extra_path = {}, bool no_init = false); + + void init_library(); /** * Set the default search path for get_library(). @@ -596,6 +599,7 @@ private: friend elf::file::~file(); friend class object; + std::stack<std::vector<std::weak_ptr<object>>> _loaded_objects_stack; }; void create_main_program(); -- 2.7.4 -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
