When loading libraries, it is required that each library uses the same
instance of each symbol, and that they use the one from the executable
if any. This is barely noticeable if done incorrectly; except that it
completely breaks RTTI on Clang. This switches the hash map to be
ordered; tested to work for Clang by @Bertaland
The System V ABI for both x86 and x86_64 requires that the stack pointer
is 16-byte aligned on entry. Previously we did not align the stack
pointer properly.
As far as "main" was concerned the stack alignment was correct even
without this patch due to how the C++ _start function and the kernel
interacted, i.e. the kernel misaligned the stack as far as the ABI
was concerned but that misalignment (read: it was properly aligned for
a regular function call - but misaligned in terms of what the ABI
dictates) was actually expected by our _start function.
Previously, we assumed that the `.text` segment was loaded at vaddr 0 in
all dynamic libraries, so we used the dynamic object's base address with
`msyscall`. This did not work with the LLVM toolchain, as it likes to
shuffle these segments around.
This now also handles the case when there are multiple text segments for
some reason correctly.
It's perfectly acceptable for the segment's vaddr to not be page aligned
as long as the segment itself is page-aligned. We'll just map a few more
bytes at the start of the segment that will be unused by the library.
We didn't notice this problem because because GCC either always uses
0 for the .text segment's vaddr or at least aligns the vaddr to the
page size.
LibELF would also fail to load really small libraries (i.e. smaller than
4096 bytes).
My previous patch (1f93ffcd) broke loading objects whose first PT_LOAD
entry had a non-zero vaddr.
On top of that the calculations for the relro and dynamic section were
also incorrect.
This implements StringUtils::find_any_of() and uses it in
String::find_any_of() and StringView::find_any_of(). All uses of
find_{first,last}_of have been replaced with find_any_of(), find() or
find_last(). find_{first,last}_of have subsequently been removed.
The LexicalPath instance methods dirname(), basename(), title() and
extension() will be changed to return StringView const& in a further
commit. Due to this, users creating temporary LexicalPath objects just
to call one of those getters will recieve a StringView const& pointing
to a possible freed buffer.
To avoid this, static methods for those APIs have been added, which will
return a String by value to avoid those problems. All cases where
temporary LexicalPath objects have been used as described above haven
been changed to use the static APIs.
This was causing CrashDaemon to choke on our coredumps. Note that we
didn't care about the validation failures before this change either,
this patch simply reorders the checks to avoid divide-by-zero when
validating an ET_CORE file.
This implements the dladdr() function which lets the caller look up
the symbol name, symbol address as well as library name and library
base address for an arbitrary address.
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
Avoid promotion of static strings to AK::String, instead use
AK::StringView and operator ""sv, to force string view's instead
which avoids allocation of String. This code path isn't hot enough
that it makes a huge difference, but every bit counts.
We had two functions for doing mostly the same thing. Combine both
of them into String::find() and use that everywhere.
Also add some tests to cover basic behavior.
The expression address - candidate.address can yield a value that
cannot safely be converted to an i32 which would result in
binary_search failing to find some symbols.
By constraining two implementations, the compiler will select the best
fitting one. All this will require is duplicating the implementation and
simplifying for the `void` case.
This constraining also informs both the caller and compiler by passing
the callback parameter types as part of the constraint
(e.g.: `IterationFunction<int>`).
Some `for_each` functions in LibELF only take functions which return
`void`. This is a minimal correctness check, as it removes one way for a
function to incompletely do something.
There seems to be a possible idiom where inside a lambda, a `return;` is
the same as `continue;` in a for-loop.
For whatever reason, symbolication was doing an O(n) walk of all the
symbols, despite having sorted them beforehand.
Changing this to a binary_search() makes symbolication noticeably
faster and improves Profiler startup time.
We were using ELF::Image::section(0) to indicate the "undefined"
section, when what we really wanted was just Optional<Section>.
So let's use Optional instead. :^)
With this fixed dlopen() no longer crashes when given an invalid
ELF image and instead returns an error code that can be retrieved
with dlerror().
Fixes#6995.
This enables us to use keys of type NonnullRefPtr in HashMaps and
HashTables.
This commit also includes fixes in various places that used
HashMap<T, NonnullRefPtr<U>>::get() and expected to get an
Optional<NonnullRefPtr<U>> and now get an Optional<U*>.
When loading a library at runtime with dlopen(), we now check that:
1. The library's TLS size does not overflow the size of the allocated
TLS block.
2. The Library's TLS data is all zeroed.
We check for both of these cases because we currently do not support
them correctly. When we do add support for them, we can remove these
checks.