1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 05:47:35 +00:00

LibELF: Fix support for relocating weak symbols

Having unresolved weak symbols is allowed and we should initialize
them to zero.
This commit is contained in:
Gunnar Beutner 2021-04-19 11:39:31 +02:00 committed by Andreas Kling
parent 97d7450571
commit 1dab5ca5fd
2 changed files with 20 additions and 10 deletions

View file

@ -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) void DynamicLoader::do_main_relocations(size_t total_tls_size)
{ {
auto do_single_relocation = [&](const ELF::DynamicObject::Relocation& relocation) { 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: case RelocationResult::Failed:
dbgln("Loader.so: {} unresolved symbol '{}'", m_filename, relocation.symbol().name()); dbgln("Loader.so: {} unresolved symbol '{}'", m_filename, relocation.symbol().name());
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
@ -267,7 +267,7 @@ void DynamicLoader::load_stage_4()
void DynamicLoader::do_lazy_relocations(size_t total_tls_size) void DynamicLoader::do_lazy_relocations(size_t total_tls_size)
{ {
for (const auto& relocation : m_unresolved_relocations) { 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()); dbgln("Loader.so: {} unresolved symbol '{}'", m_filename, relocation.symbol().name());
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
@ -424,7 +424,7 @@ void DynamicLoader::load_program_headers()
// FIXME: Initialize the values in the TLS section. Currently, it is zeroed. // 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; FlatPtr* patch_ptr = nullptr;
if (is_dynamic()) if (is_dynamic())
@ -462,14 +462,19 @@ DynamicLoader::RelocationResult DynamicLoader::do_relocation(size_t total_tls_si
case R_386_GLOB_DAT: { case R_386_GLOB_DAT: {
auto symbol = relocation.symbol(); auto symbol = relocation.symbol();
auto res = lookup_symbol(symbol); auto res = lookup_symbol(symbol);
VirtualAddress symbol_location;
if (!res.has_value()) { if (!res.has_value()) {
if (symbol.bind() == STB_WEAK) if (symbol.bind() == STB_WEAK) {
return RelocationResult::ResolveLater; if (should_initialize_weak == ShouldInitializeWeak::No)
return RelocationResult::ResolveLater;
} else {
// Symbol not found
return RelocationResult::Failed;
}
// Symbol not found symbol_location = VirtualAddress { (FlatPtr)0 };
return RelocationResult::Failed; } else
} symbol_location = res.value().address;
auto symbol_location = res.value().address;
VERIFY(symbol_location != m_dynamic_object->base_address()); VERIFY(symbol_location != m_dynamic_object->base_address());
*patch_ptr = symbol_location.get(); *patch_ptr = symbol_location.get();
break; break;

View file

@ -54,6 +54,11 @@ private:
size_t m_size; size_t m_size;
}; };
enum class ShouldInitializeWeak {
Yes,
No
};
class DynamicLoader : public RefCounted<DynamicLoader> { class DynamicLoader : public RefCounted<DynamicLoader> {
public: public:
static RefPtr<DynamicLoader> try_create(int fd, String filename); static RefPtr<DynamicLoader> try_create(int fd, String filename);
@ -145,7 +150,7 @@ private:
Success = 1, Success = 1,
ResolveLater = 2, 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; size_t calculate_tls_size() const;
String m_filename; String m_filename;