summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibELF/DynamicLoader.h
AgeCommit message (Collapse)Author
2022-05-07LibELF: Name library maps with the full file pathTim Schumacher
2022-04-01Everywhere: Run clang-formatIdan Horowitz
2022-03-31LibELF: Remove unused m_program_interpreter member from DynamicLoaderBrian Gianforcaro
While profiling I realized that this member is unused, so the StringBuilder and String allocation are completely un-necessary.
2022-03-08DynamicLoader: Make the cached DynamicObject publicly accessibleTim Schumacher
2022-02-11LibELF: Implement support for DT_RELR relative relocationsDaniel Bertalan
The DT_RELR relocation is a relatively new relocation encoding designed to achieve space-efficient relative relocations in PIE programs. The description of the format is available here: https://groups.google.com/g/generic-abi/c/bX460iggiKg/m/Pi9aSwwABgAJ It works by using a bitmap to store the offsets which need to be relocated. Even entries are *address* entries: they contain an address (relative to the base of the executable) which needs to be relocated. Subsequent even entries are *bitmap* entries: "1" bits encode offsets (in word size increments) relative to the last address entry which need to be relocated. This is in contrast to the REL/RELA format, where each entry takes up 2/3 machine words. Certain kinds of relocations store useful data in that space (like the name of the referenced symbol), so not everything can be encoded in this format. But as position-independent executables and shared libraries tend to have a lot of relative relocations, a specialized encoding for them absolutely makes sense. The authors of the format suggest an overall 5-20% reduction in the file size of various programs. Due to our extensive use of dynamic linking and us not stripping debug info, relative relocations don't make up such a large portion of the binary's size, so the measurements will tend to skew to the lower side of the spectrum. The following measurements were made with the x86-64 Clang toolchain: - The kernel contains 290989 relocations. Enabling RELR decreased its size from 30 MiB to 23 MiB. - LibUnicodeData contains 190262 relocations, almost all of them relative. Its file size changed from 17 MiB to 13 MiB. - /bin/WebContent contains 1300 relocations, 66% of which are relative relocations. With RELR, its size changed from 832 KiB to 812 KiB. This change was inspired by the following blog post: https://maskray.me/blog/2021-10-31-relative-relocations-and-relr
2021-07-04LibELF: Swap the arguments for negative_offset_from_tls_block_endGunnar Beutner
Now that m_tls_offset points to the start of the TLS block the argument order makes more sense this way.
2021-07-04LibELF: Save the negative TLS offset in m_tls_offsetGunnar Beutner
This makes it unnecessary to track the symbol size which just isn't available for unexported symbols (e.g. for 'static __thread').
2021-06-28Kernel+LibELF: Add support for validating and loading ELF64 executablesGunnar Beutner
2021-05-30AK+Userland: Use akaster@serenityos.org for my copyright headersAndrew Kaster
2021-04-30LibELF: Change TLS offset calculationItamar
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.
2021-04-30Kernel+LibELF: Support initializing values of TLS dataItamar
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.
2021-04-30LibELF: Rename tls_size to tls_size_of_current_objectItamar
2021-04-30LibELF: Extract TLS offset calculation logic to separate functionItamar
2021-04-25LibC+LibELF: Implement more fully-features dlfcn functionalityGunnar Beutner
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.
2021-04-22Everything: Move to SPDX license identifiers in all files.Brian Gianforcaro
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 *
2021-04-19LibELF: Fix support for relocating weak symbolsGunnar Beutner
Having unresolved weak symbols is allowed and we should initialize them to zero.
2021-04-18LibC+LibELF: Implement support for the dl_iterate_phdr helperGunnar Beutner
This helper is used by libgcc_s to figure out where the .eh_frame sections are located for all loaded shared objects.
2021-04-14LibELF: Add support for loading objects with multiple data and text segmentsGunnar Beutner
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-
2021-02-26LibELF: Consolidate main executable loading a bitAndreas Kling
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.
2021-02-21LibELF: Move DynamicObject::lookup_symbol() to DynamicLoaderAndreas Kling
Also simplify it by removing an unreachable code path.
2021-02-21LibELF: Fix various clang-tidy warningsAndreas Kling
Remove a bunch of unused code, unnecessary const, and make some non-object-specific member functions static.
2021-02-20LibELF: Use StringView instead of "const char*" in dynamic linker codeAndreas Kling
There's no reason to use C strings more than absolutely necessary.
2021-02-20DynamicLoader: Always make .data segment read+writeAndreas Kling
Let's just ignore the program header and always go with read+write. Nothing else makes sense anyway.
2021-02-18LibELF+Userland: Enable RELRO for all userland executables :^)Andreas Kling
The dynamic loader will now mark RELRO segments read-only after performing relocations. This is pretty cool! Note that this only applies to main executables so far,. RELRO support for shared libraries will require some reorganizing of the dynamic loader.
2021-02-18DynamicLoader: Some ELF data segments were allocated too smallAndreas Kling
For a data segment that starts at a non-zero offset into a 4KB page and crosses a 4KB page boundary, we were failing to pad the VM allocation, which would cause the memcpy() to fail. Make sure we round the segment bases down, and segment ends up, and the issue goes away.
2021-01-31LibELF: Split the DynamicLoader's loading mechanism into two stepsAndreas Kling
load_from_image() becomes map() and link(). This allows us to map an object before mapping its dependencies. This solves an issue where fixed-position executables (like GCC) would clash with the ASLR placement of their own shared libraries.
2021-01-31LibELF: Call mmap() before constructing the DynamicLoader objectAndreas Kling
Refactor DynamicLoader construction with a try_create() helper so that we can call mmap() before making a loader. This way the loader doesn't need to have an "mmap failed" state. This patch also takes care of determining the ELF file size in try_create() instead of expecting callers to provide it.
2021-01-25LibELF: Cache the DynamicObject in DynamicLoaderAndreas Kling
This avoids reparsing the same dynamic library file multiple times.
2021-01-25LibELF: Use Optional<SymbolLookupResult> as a return typeAndreas Kling
Instead of storing a "found" state inside the result object.
2021-01-12Libraries: Move to Userland/Libraries/Andreas Kling