summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibELF
AgeCommit message (Collapse)Author
2022-09-05LibC: Move `dlfcn_integration.h` to the `bits` directoryTim Schumacher
2022-09-05Everywhere: Refer to `dlfcn*.h` by its non-prefixed nameTim Schumacher
2022-07-21Utilities+LibELF: Temporary promises for dynamic linker in "pledge"Itamar
This adds a "temporary promises for the dynamic-linker" flag ('-d') to the "pledge" utility. Example usage: pledge -d -p "stdio rpath" id Without the '-d' flag, id would crash because the dynamic linker requires 'prot_exec'. When this flag is used and the program to be run is dynamically linked, "pledge" adds promises that are required by the dynamic linker to the promise set provided by the user. The dynamic linker will later "give up" the pledge promises it no longer requires.
2022-07-20LibELF: Copy the entire TLS segment instead of each symbol one-by-oneTim Schumacher
This automatically fixes an issue where we were accidentally copying garbage data from beyond the TLS segment as uninitialized data isn't actually stored inside the image.
2022-07-20LibELF: Remove outdated TLS handling in generic program header codeTim Schumacher
2022-07-19LibC: Remove a bunch of weak `pthread_*` symbolsTim Schumacher
2022-07-12Everywhere: Use default StringView constructor over nullptrsin-ack
While null StringViews are just as bad, these prevent the removal of StringView(char const*) as that constructor accepts a nullptr. No functional changes.
2022-07-12Everywhere: Add sv suffix to strings relying on StringView(char const*)sin-ack
Each of these strings would previously rely on StringView's char const* constructor overload, which would call __builtin_strlen on the string. Since we now have operator ""sv, we can replace these with much simpler versions. This opens the door to being able to remove StringView(char const*). No functional changes.
2022-07-12Everywhere: Explicitly specify the size in StringView constructorssin-ack
This commit moves the length calculations out to be directly on the StringView users. This is an important step towards the goal of removing StringView(char const*), as it moves the responsibility of calculating the size of the string to the user of the StringView (which will prevent naive uses causing OOB access).
2022-07-10DynamicLoader: Stop performing relative relocations on non-pie objectsIdan Horowitz
Co-authored-by: Daniel Bertalan <dani@danielbertalan.dev>
2022-07-08LibC: Move stack canary initialization before the global constructorsTim Schumacher
Once again, QEMU creates threads while running its constructors, which is a recipe for disaster if we switch out the stack guard while that is already running in the background. To solve that, move initialization to our LibC initialization stage, which is before any actual external initialization code runs.
2022-07-06AK: Use an enum instead of a bool for String::replace(all_occurences)DexesTTP
This commit has no behavior changes. In particular, this does not fix any of the wrong uses of the previous default parameter (which used to be 'false', meaning "only replace the first occurence in the string"). It simply replaces the default uses by String::replace(..., ReplaceMode::FirstOnly), leaving them incorrect.
2022-07-05LibELF: Take TLS segment alignment into account in DynamicLoaderIdan Horowitz
Previously we would just tightly pack the different libraries' TLS segments together, but that is incorrect, as they might require some kind of minimum alignment for their TLS base address. We now plumb the required TLS segment alignment down to the TLS block linear allocator and align the base address down to the appropriate alignment.
2022-06-30LibELF: Store the full file path in DynamicObjectTim Schumacher
Otherwise, our `dirname` call on the parent object will always be empty when trying to resolve dependencies.
2022-06-24LibELF: Warn on self-dlopening libraries while initializingTim Schumacher
2022-06-24LibELF: Check if initializers ran instead of trusting s_global_objectsTim Schumacher
The original heuristic of "a library being in `s_global_objects` means that it was fully initialized already" doesn't hold up anymore since we changed the loading order. This was causing us to skip parts of the initialization of dependency libraries when running dlopen (since it was the only user of that setting). Instead, set a flag after we run stage 4 (which is the "run the global initializers" stage) and check that flag when determining unfinished dependencies. This entirely replaces the `skip_global_objects` logic.
2022-06-21LibELF: Only collect region sizes before reserving memoryTim Schumacher
This keeps us from needlessly allocating storage via `malloc` as part of the `Vector`s that early, which we might conflict on while reserving memory for the main executable.
2022-06-21LibELF: Unmap the source file temporarily while reserving spaceTim Schumacher
This further reduces the chance that we will conflict with data that is already present at the target location.
2022-06-21LibELF: Store DynamicLoader ELF images using an OwnPtrTim Schumacher
This is preparation work for the next commit, where we will replace the stored ELF image mid-load.
2022-06-21LibELF: Actually do the library mapping as early as possibleTim Schumacher
We previously trusted the `map` part in `map_library` too much, and assumed that this would already lock in the binary at its final place. However, the `map()` function of the loader was only called in `load_main_library`, which ran only right before jumping to the entrypoint. Make our binary loading a bit more stable by actually mapping the binary right after we read its information, and only do the linking right before jumping to the entrypoint.
2022-06-12LibELF: Always use parent object basename for $ORIGIN processingAndrew Kaster
Using the main executable basename produces the wrong $ORIGIN processing for libraries that are secondary dependencies of the main executable, or dependencies of an object loaded via dlopen.
2022-05-07LibELF: Name library maps with the full file pathTim Schumacher
2022-05-07LibELF: Separate library resolving into a new functionTim Schumacher
2022-05-01LibELF: Fail gracefully when IFUNC resolver's object has textrelsDaniel Bertalan
.text sections of objects that contain textrels have to be writable during the relocation procedure. Because of this, we would segfault if we tried to execute IFUNC resolvers defined in them. Let's print a meaningful error message instead. Additionally, a warning is now printed when we load objects with textrels, as in the future, additional security mitigations might interfere with them being loaded.
2022-05-01LibELF: Add support for IFUNCsDaniel Bertalan
IFUNC is a GNU extension to the ELF standard that allows a function to have multiple implementations. A resolver function has to be called at load time to choose the right one to use. The PLT will contain the entry to the resolved function, so branching and more indirect jumps can be avoided at run-time. This mechanism is usually used when a routine can be made faster using CPU features that are available in only some models, and a fallback implementation has to exist for others. We will use this feature to have two separate memset implementations for CPUs with and without ERMS (Enhanced REP MOVSB/STOSB) support.
2022-05-01LibELF: Keep track of whether the PLT contains REL or RELA relocationsDaniel Bertalan
2022-05-01LibELF: Perform .relr.dyn relocations before .rel.dynDaniel Bertalan
IFUNC resolvers depend on the resolved function's address having been relocated by the time they are called. This means that relative relocations have to be done first. The linker is kind enough to put R_*_RELATIVE before R_*_IRELATIVE in .rel.dyn, but .relr.dyn contains relative relocations too.
2022-05-01LibELF: Relax restriction on allowed values of EI_OSABI to allow GNUAndrew Kaster
This check is here to make sure we only try to load serenity binaries. However, with -fprofile-instr-generate -fcoverage-mapping, clang sets the EI_OSABI field to 3, for GNU. The instrumentation uses a lot of retained COMDAT sections for coverage instrumentation that get the SHF_GNU_RETAINED section header flag set on them, forcing llvm to set the ABI to GNU.
2022-04-03LibELF: Look up symbols in all global modulesTimur Sultanov
dlsym() called with RTLD_DEFAULT (nullptr) should look up symbol in all global modules instead of only looking into the executable file
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-31LibELF: Skip DynamicObject::dump() if logging isn't enabledBrian Gianforcaro
I noticed that we were populating this StringBuilder and then throwing away the result while profiling `true` with UserSpace emulator. Before: courage:~ $ time -n 1000 true Timing report: 3454 ms ============== Command: true Average time: 3.45 ms (median: 3, stddev: 3.42, min: 0, max:11) Excluding first: 3.45 ms (median: 3, stddev: 3.42, min: 0, max:11) After: courage:~ $ time -n 1000 true Timing report: 3308 ms ============== Command: true Average time: 3.30 ms (median: 3, stddev: 3.28, min: 0, max:12) Excluding first: 3.30 ms (median: 3, stddev: 3.29, min: 0, max:12)
2022-03-10Libraries: Use default constructors/destructors in LibELFLenny Maiorani
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cother-other-default-operation-rules "The compiler is more likely to get the default semantics right and you cannot implement these functions better than the compiler."
2022-03-08DynamicLinker: Replace $ORIGIN with the executable pathTim Schumacher
2022-03-08DynamicLinker: Implement support for RPATH and RUNPATHTim Schumacher
2022-03-08DynamicLoader: Make the cached DynamicObject publicly accessibleTim Schumacher
2022-02-16Kernel+LibELF+LibVT: Remove unused AK::String header includesIdan Horowitz
2022-02-16LibELF: Exclude sorted symbols APIs from the KernelIdan Horowitz
These are only used by userland, and are implemented using infallible Strings, so let's just ifdef them out of the Kernel.
2022-02-16LibELF: Exclude MemoryRegionInfo::object_name() from the KernelIdan Horowitz
This API is only used by userland, and it uses infallible Strings, so let's just ifdef it out of the Kernel.
2022-02-16LibELF: Use StringBuilder::string_view() to avoid String allocationIdan Horowitz
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
2022-01-28Userland: Remove a bunch of unnecessary Vector importskleines Filmröllchen
How silly :^)
2022-01-24Everywhere: Convert ByteBuffer factory methods from Optional -> ErrorOrSam Atkins
Apologies for the enormous commit, but I don't see a way to split this up nicely. In the vast majority of cases it's a simple change. A few extra places can use TRY instead of manual error checking though. :^)
2022-01-15LibELF: Use shared memory mapping when loading ELF objectsAndreas Kling
There's no reason to make a private read-only mapping just for reading (and validating) the ELF headers, and copying out the data segments.
2022-01-13LibELF: Accept Span instead of Pointer+Size in validate_program_headersIdan Horowitz
2022-01-13LibELF: Use StringBuilders instead of Strings for the interpreter pathIdan Horowitz
This is required for the Kernel's usage of LibELF, since Strings do not expose allocation failure.
2022-01-05LibELF: Add `LD_LIBRARY_PATH` envvar support :^)Jesse Buhagiar
The dynamic linker now supports having custom library paths as specified by the user.
2021-12-29Kernel: Use Process::require_promise() instead of REQUIRE_PROMISE()Brian Gianforcaro
This change lays the foundation for making the require_promise return an error hand handling the process abort outside of the syscall implementations, to avoid cases where we would leak resources. It also has the advantage that it makes removes a gs pointer read to look up the current thread, then process for every syscall. We can instead go through the Process this pointer in most cases.
2021-12-23LibELF: Use MAP_FIXED_NOREPLACE for address space reservationDaniel Bertalan
This ensures that we don't corrupt our address space if a non-PIE program's requested address space happens to coincide with memory we already use.
2021-12-22LibELF: Ignore unknown dynamic tags instead of assertingIdan Horowitz
Some programs (like wine) add custom dynamic tags to their binaries that are used internally by them, so we can just ignore them.