mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:07:35 +00:00
LibELF: Check if initializers ran instead of trusting s_global_objects
The original heuristic of "a library being in `s_global_objects` means that it was fully initialized already" doesn't hold up anymore since we changed the loading order. This was causing us to skip parts of the initialization of dependency libraries when running dlopen (since it was the only user of that setting). Instead, set a flag after we run stage 4 (which is the "run the global initializers" stage) and check that flag when determining unfinished dependencies. This entirely replaces the `skip_global_objects` logic.
This commit is contained in:
parent
ef1c97e3d8
commit
082a7baa3b
3 changed files with 18 additions and 10 deletions
|
@ -292,12 +292,14 @@ static void initialize_libc(DynamicObject& libc)
|
|||
}
|
||||
|
||||
template<typename Callback>
|
||||
static void for_each_unfinished_dependency_of(String const& name, HashTable<String>& seen_names, bool first, bool skip_global_objects, Callback callback)
|
||||
static void for_each_unfinished_dependency_of(String const& name, HashTable<String>& seen_names, Callback callback)
|
||||
{
|
||||
if (!s_loaders.contains(name))
|
||||
auto loader = s_loaders.get(name);
|
||||
|
||||
if (!loader.has_value())
|
||||
return;
|
||||
|
||||
if (!first && skip_global_objects && s_global_objects.contains(name))
|
||||
if (loader.value()->is_fully_initialized())
|
||||
return;
|
||||
|
||||
if (seen_names.contains(name))
|
||||
|
@ -305,24 +307,24 @@ static void for_each_unfinished_dependency_of(String const& name, HashTable<Stri
|
|||
seen_names.set(name);
|
||||
|
||||
for (auto const& needed_name : get_dependencies(name))
|
||||
for_each_unfinished_dependency_of(get_library_name(needed_name), seen_names, false, skip_global_objects, callback);
|
||||
for_each_unfinished_dependency_of(get_library_name(needed_name), seen_names, callback);
|
||||
|
||||
callback(*s_loaders.get(name).value());
|
||||
}
|
||||
|
||||
static NonnullRefPtrVector<DynamicLoader> collect_loaders_for_library(String const& name, bool skip_global_objects)
|
||||
static NonnullRefPtrVector<DynamicLoader> collect_loaders_for_library(String const& name)
|
||||
{
|
||||
HashTable<String> seen_names;
|
||||
NonnullRefPtrVector<DynamicLoader> loaders;
|
||||
for_each_unfinished_dependency_of(name, seen_names, true, skip_global_objects, [&](auto& loader) {
|
||||
for_each_unfinished_dependency_of(name, seen_names, [&](auto& loader) {
|
||||
loaders.append(loader);
|
||||
});
|
||||
return loaders;
|
||||
}
|
||||
|
||||
static Result<void, DlErrorMessage> link_main_library(String const& name, int flags, bool skip_global_objects)
|
||||
static Result<void, DlErrorMessage> link_main_library(String const& name, int flags)
|
||||
{
|
||||
auto loaders = collect_loaders_for_library(name, skip_global_objects);
|
||||
auto loaders = collect_loaders_for_library(name);
|
||||
|
||||
for (auto& loader : loaders) {
|
||||
auto dynamic_object = loader.map();
|
||||
|
@ -447,7 +449,7 @@ static Result<void*, DlErrorMessage> __dlopen(char const* filename, int flags)
|
|||
return result2.error();
|
||||
}
|
||||
|
||||
auto result = link_main_library(library_name, flags, true);
|
||||
auto result = link_main_library(library_name, flags);
|
||||
if (result.is_error())
|
||||
return result.error();
|
||||
|
||||
|
@ -583,7 +585,7 @@ void ELF::DynamicLinker::linker_main(String&& main_program_name, int main_progra
|
|||
|
||||
auto entry_point_function = [&main_program_name] {
|
||||
auto library_name = get_library_name(main_program_name);
|
||||
auto result = link_main_library(library_name, RTLD_GLOBAL | RTLD_LAZY, false);
|
||||
auto result = link_main_library(library_name, RTLD_GLOBAL | RTLD_LAZY);
|
||||
if (result.is_error()) {
|
||||
warnln("{}", result.error().text);
|
||||
_exit(1);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue