Age | Commit message (Collapse) | Author |
|
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. :^)
|
|
POSIX mandates that it is placed there.
|
|
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.
|
|
Sure, this saves a couple of characters, but it's probably not
the best style.
|
|
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*>.
|
|
|
|
There are definitely some relocations missing and this is untested
for now.
|
|
|
|
|
|
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.
|
|
This changes the TLS offset calculation logic to be based on the
symbol's size instead of the total size of the TLS.
Because of this change, we no longer need to pipe "m_tls_size" to so
many functions.
Also, After this patch, the TLS data of the main program exists at the
"end" of the TLS block (Highest addresses).
This fixes a part of #6609.
|
|
Previously, TLS data was always zero-initialized.
To support initializing the values of TLS data, sys$allocate_tls now
receives a buffer with the desired initial data, and copies it to the
master TLS region of the process.
The DynamicLinker gathers the initial TLS image and passes it to
sys$allocate_tls.
We also now require the size passed to sys$allocate_tls to be
page-aligned, to make things easier. Note that this doesn't waste memory
as the TLS data has to be allocated in separate pages anyway.
|
|
|
|
|
|
This fixes a regression that was introduced in f40ee1b and caused the
tls_offset of all objects other than the main program to be 0.
After this fix map_library's is_program argument is no longer used, so
it was removed.
|
|
|
|
We had some inconsistencies before:
- Sometimes "The", sometimes "the"
- Sometimes trailing ".", sometimes no trailing "."
I picked the most common one (lowecase "the", trailing ".") and applied
it to all copyright headers.
By using the exact same string everywhere we can ensure nothing gets
missed during a global search (and replace), and that these
inconsistencies are not spread any further (as copyright headers are
commonly copied to new files).
|
|
This implements more of the dlfcn functionality. Most notably:
* It's now possible to dlopen() libraries which were already
loaded at program startup time. This does not cause those
libraries to be loaded twice.
* Errors are reported via dlerror() rather than by crashing
the program.
* Calls to the dl*() functions are thread-safe.
|
|
|
|
This makes it more symmetrical with adopt_own() (which is used to
create a NonnullOwnPtr from the result of a naked new.)
|
|
SPDX License Identifiers are a more compact / standardized
way of representing file license information.
See: https://spdx.dev/resources/use/#identifiers
This was done with the `ambr` search and replace tool.
ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *
|
|
|
|
The shared library libicudata.so has a DT_SYMBOLIC entry:
Dynamic Section:
NEEDED libgcc_s.so
SONAME libicudata.so.69
SYMBOLIC 0x00000000
HASH 0x00000094
STRTAB 0x000000c8
SYMTAB 0x000000a8
STRSZ 0x0000002a
SYMENT 0x00000010
According to the ELF spec DT_SYMBOLIC has no special meaning
for the dynamic loader.
|
|
Shared objects without a text segment are perfectly OK. For
example libicudata.so has only data segments:
Sections:
Idx Name Size VMA LMA File off Algn
0 .hash 00000014 00000094 00000094 00000094 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .dynsym 00000020 000000a8 000000a8 000000a8 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .dynstr 0000002a 000000c8 000000c8 000000c8 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .rodata 01b562d0 00000100 00000100 00000100 2**4
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .eh_frame 00000000 01b563d0 01b563d0 01b563d0 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .dynamic 00000070 01b573d0 01b573d0 01b563d0 2**2
|
|
The calculation for TLS relocations was incorrect which would
result in overlapping TLS variables when more than one shared
object used TLS variables.
This bug can be reproduced with a shared library and a program
like this:
$ cat tlstest.c
#include <string.h>
__thread char tls_val[1024];
void set_val() { memset(tls_val, 0, sizeof(tls_val)); }
$ gcc -g -shared -o usr/lib/libtlstest.so tlstest.c
$ cat test.c
void set_val();
int main() { set_val(); }
$ gcc -g -o tls test.c -ltlstest
Due to the way the TLS relocations are done this program would
clobber libc's TLS variables (e.g. errno).
|
|
|
|
Having unresolved weak symbols is allowed and we should initialize
them to zero.
|
|
This way we get better error messages for unresolved symbols because
the caller logs the file and symbol names.
|
|
|
|
This helper is used by libgcc_s to figure out where the .eh_frame sections
are located for all loaded shared objects.
|
|
These are built when compiling an executable with exception support.
|
|
|
|
|
|
|
|
This enables loading executables with multiple data and text segments. Also
it fixes loading executables where the text segment has a non-zero offset.
Example:
$ echo "main () {}" > test.c
$ gcc -Wl,-z,separate-code -o test test.c
$ objdump -p test
test: file format elf32-i386
Program Header:
PHDR off 0x00000034 vaddr 0x00000034 paddr 0x00000034 align 2**2
filesz 0x000000e0 memsz 0x000000e0 flags r--
INTERP off 0x00000114 vaddr 0x00000114 paddr 0x00000114 align 2**0
filesz 0x00000013 memsz 0x00000013 flags r--
LOAD off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**12
filesz 0x000003c4 memsz 0x000003c4 flags r--
LOAD off 0x00001000 vaddr 0x00001000 paddr 0x00001000 align 2**12
filesz 0x00000279 memsz 0x00000279 flags r-x
LOAD off 0x00002000 vaddr 0x00002000 paddr 0x00002000 align 2**12
filesz 0x00000004 memsz 0x00000004 flags r--
LOAD off 0x00002004 vaddr 0x00003004 paddr 0x00003004 align 2**12
filesz 0x00000100 memsz 0x00000124 flags rw-
DYNAMIC off 0x00002014 vaddr 0x00003014 paddr 0x00003014 align 2**2
filesz 0x000000c8 memsz 0x000000c8 flags rw-
|
|
This simply fixes a check which assumed the program header count was
always non zero.
|
|
|
|
|
|
Currently we end up with the following:
serenity/
AK/
...
Kernel/
...
Libraries/
LibELF/
LibTest/
Userland/
Libraries/
<all other libs>
...
|
|
Good-bye LogStream. Long live AK::Format!
|
|
Mostly due to the fact that clang-format allows aligned comments via
AlignTrailingComments.
We could also use raw string literals in inline asm, which clang-format
deals with properly (and would be nicer in a lot of places).
|
|
Merge the load_elf() and commit_elf() functions into a single
load_main_executable() function that takes care of both things.
Also split "stage 3" into two separate stages, keeping the lazy
relocations in stage 3, and adding a stage 4 for calling library
initialization functions.
We also make sure to map the main executable before dealing with
any of its dependencies, to ensure that non-PIE executables get
loaded at their desired address.
|
|
Instead of having a special case in the dynamic loader where we ignore
TM-related GCC symbols, just stub them out in LibC like we already do
for various other things we don't support.
|
|
Most of these won't have perf impact, but the optimization is
practically free, so no harm in fixing these up.
|
|
|
|
(...and ASSERT_NOT_REACHED => VERIFY_NOT_REACHED)
Since all of these checks are done in release builds as well,
let's rename them to VERIFY to prevent confusion, as everyone is
used to assertions being compiled out in release.
We can introduce a new ASSERT macro that is specifically for debug
checks, but I'm doing this wholesale conversion first since we've
accumulated thousands of these already, and it's not immediately
obvious which ones are suitable for ASSERT.
|
|
This was high up in profiles and gets almost entirely optimized out
when inlined, so let's do that.
|