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:
parent
97d7450571
commit
1dab5ca5fd
2 changed files with 20 additions and 10 deletions
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue