summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibELF
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Libraries/LibELF')
-rw-r--r--Userland/Libraries/LibELF/DynamicLoader.cpp23
-rw-r--r--Userland/Libraries/LibELF/DynamicLoader.h7
2 files changed, 20 insertions, 10 deletions
diff --git a/Userland/Libraries/LibELF/DynamicLoader.cpp b/Userland/Libraries/LibELF/DynamicLoader.cpp
index 376d497e0c..a483dc7801 100644
--- a/Userland/Libraries/LibELF/DynamicLoader.cpp
+++ b/Userland/Libraries/LibELF/DynamicLoader.cpp
@@ -211,7 +211,7 @@ bool DynamicLoader::load_stage_2(unsigned flags, size_t total_tls_size)
void DynamicLoader::do_main_relocations(size_t total_tls_size)
{
auto do_single_relocation = [&](const ELF::DynamicObject::Relocation& relocation) {
- switch (do_relocation(total_tls_size, relocation)) {
+ switch (do_relocation(total_tls_size, relocation, ShouldInitializeWeak::No)) {
case RelocationResult::Failed:
dbgln("Loader.so: {} unresolved symbol '{}'", m_filename, relocation.symbol().name());
VERIFY_NOT_REACHED();
@@ -267,7 +267,7 @@ void DynamicLoader::load_stage_4()
void DynamicLoader::do_lazy_relocations(size_t total_tls_size)
{
for (const auto& relocation : m_unresolved_relocations) {
- if (auto res = do_relocation(total_tls_size, relocation); res != RelocationResult::Success) {
+ if (auto res = do_relocation(total_tls_size, relocation, ShouldInitializeWeak::Yes); res != RelocationResult::Success) {
dbgln("Loader.so: {} unresolved symbol '{}'", m_filename, relocation.symbol().name());
VERIFY_NOT_REACHED();
}
@@ -424,7 +424,7 @@ void DynamicLoader::load_program_headers()
// FIXME: Initialize the values in the TLS section. Currently, it is zeroed.
}
-DynamicLoader::RelocationResult DynamicLoader::do_relocation(size_t total_tls_size, const ELF::DynamicObject::Relocation& relocation)
+DynamicLoader::RelocationResult DynamicLoader::do_relocation(size_t total_tls_size, const ELF::DynamicObject::Relocation& relocation, ShouldInitializeWeak should_initialize_weak)
{
FlatPtr* patch_ptr = nullptr;
if (is_dynamic())
@@ -462,14 +462,19 @@ DynamicLoader::RelocationResult DynamicLoader::do_relocation(size_t total_tls_si
case R_386_GLOB_DAT: {
auto symbol = relocation.symbol();
auto res = lookup_symbol(symbol);
+ VirtualAddress symbol_location;
if (!res.has_value()) {
- if (symbol.bind() == STB_WEAK)
- return RelocationResult::ResolveLater;
+ if (symbol.bind() == STB_WEAK) {
+ if (should_initialize_weak == ShouldInitializeWeak::No)
+ return RelocationResult::ResolveLater;
+ } else {
+ // Symbol not found
+ return RelocationResult::Failed;
+ }
- // Symbol not found
- return RelocationResult::Failed;
- }
- auto symbol_location = res.value().address;
+ symbol_location = VirtualAddress { (FlatPtr)0 };
+ } else
+ symbol_location = res.value().address;
VERIFY(symbol_location != m_dynamic_object->base_address());
*patch_ptr = symbol_location.get();
break;
diff --git a/Userland/Libraries/LibELF/DynamicLoader.h b/Userland/Libraries/LibELF/DynamicLoader.h
index 25c95902a1..6bb2ec8f7e 100644
--- a/Userland/Libraries/LibELF/DynamicLoader.h
+++ b/Userland/Libraries/LibELF/DynamicLoader.h
@@ -54,6 +54,11 @@ private:
size_t m_size;
};
+enum class ShouldInitializeWeak {
+ Yes,
+ No
+};
+
class DynamicLoader : public RefCounted<DynamicLoader> {
public:
static RefPtr<DynamicLoader> try_create(int fd, String filename);
@@ -145,7 +150,7 @@ private:
Success = 1,
ResolveLater = 2,
};
- RelocationResult do_relocation(size_t total_tls_size, const DynamicObject::Relocation&);
+ RelocationResult do_relocation(size_t total_tls_size, const DynamicObject::Relocation&, ShouldInitializeWeak should_initialize_weak);
size_t calculate_tls_size() const;
String m_filename;