diff options
author | Gunnar Beutner <gbeutner@serenityos.org> | 2021-05-31 11:39:00 +0200 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-05-31 11:49:32 +0100 |
commit | 73b9cfac1b4fddd5e8105427ffd8e22d5c2eee51 (patch) | |
tree | 11c0e224662613b72931d05d764951e9222b6afb /Userland | |
parent | 26cb64573c75bab5f9d049fc6bd841d24670624b (diff) | |
download | serenity-73b9cfac1b4fddd5e8105427ffd8e22d5c2eee51.zip |
LibELF: Support weak symbols when using BIND_NOW
When using BIND_NOW (e.g. via -Wl,-z,now) we would fail to load ELF
images while doing relocations when we encounter a weak symbol. Instead
we should just patch the PLT entry with a null pointer.
This can be reproduced with:
$ cat test.cpp
int main()
{
std::cout << "Hello World!" << std::endl;
}
$ g++ -o test -Wl,-z,now test.cpp
$ ./test
did not find symbol while doing relocations for library test: _ITM_RU1
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibELF/DynamicObject.cpp | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/Userland/Libraries/LibELF/DynamicObject.cpp b/Userland/Libraries/LibELF/DynamicObject.cpp index dfb8660483..21acbe77f5 100644 --- a/Userland/Libraries/LibELF/DynamicObject.cpp +++ b/Userland/Libraries/LibELF/DynamicObject.cpp @@ -454,13 +454,15 @@ VirtualAddress DynamicObject::patch_plt_entry(u32 relocation_offset) auto symbol = relocation.symbol(); u8* relocation_address = relocation.address().as_ptr(); + VirtualAddress symbol_location; auto result = DynamicLoader::lookup_symbol(symbol); - if (!result.has_value()) { + if (result.has_value()) { + symbol_location = result.value().address; + } else if (symbol.bind() != STB_WEAK) { dbgln("did not find symbol while doing relocations for library {}: {}", m_filename, symbol.name()); VERIFY_NOT_REACHED(); } - auto symbol_location = result.value().address; dbgln_if(DYNAMIC_LOAD_DEBUG, "DynamicLoader: Jump slot relocation: putting {} ({}) into PLT at {}", symbol.name(), symbol_location, (void*)relocation_address); *(FlatPtr*)relocation_address = symbol_location.get(); |