Commit graph

42 commits

Author SHA1 Message Date
Liav A
a4c87fac56 LibELF+LibSymbolication: Remove i686 support 2022-12-28 11:53:41 +01:00
Linus Groh
6e19ab2bbc AK+Everywhere: Rename String to DeprecatedString
We have a new, improved string type coming up in AK (OOM aware, no null
state), and while it's going to use UTF-8, the name UTF8String is a
mouthful - so let's free up the String name by renaming the existing
class.
Making the old one have an annoying name will hopefully also help with
quick adoption :^)
2022-12-06 08:54:33 +01:00
sin-ack
c70f45ff44 Everywhere: Explicitly specify the size in StringView constructors
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-12 23:11:35 +02:00
Tim Schumacher
e2036ca2ca LibELF: Store the full file path in DynamicObject
Otherwise, our `dirname` call on the parent object will always be empty
when trying to resolve dependencies.
2022-06-30 11:57:10 +02:00
Daniel Bertalan
08c459e495 LibELF: Add support for IFUNCs
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-01 12:42:01 +02:00
Idan Horowitz
086969277e Everywhere: Run clang-format 2022-04-01 21:24:45 +01:00
Lenny Maiorani
271d82e23f Libraries: Use default constructors/destructors in LibELF
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-10 18:04:26 -08:00
Daniel Bertalan
3974cac148 LibELF: Implement support for DT_RELR relative relocations
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-02-11 18:07:53 +01:00
Andreas Kling
8b1108e485 Everywhere: Pass AK::StringView by value 2021-11-11 01:27:46 +01:00
Rodrigo Tobar
3efd7b458a LibELF+readelf: Remove duplicated dtag->string map
A copy of the same mapping was found both in LibELF and in the readelf
utility, which uses LibELF; keeping them both is redundant and removing
the duplicate saves (a bit of) space.
2021-09-26 12:45:55 +02:00
Brian Gianforcaro
5dbc72a158 LibELF: Use default instead of an empty constructor/destructor
Default implementations allow for more optimizations.
See: https://pvs-studio.com/en/docs/warnings/v832/
2021-09-16 17:17:13 +02:00
Gunnar Beutner
db1c5c4830 LibELF+Utilities: Avoid truncating 64-bit values
This fixes displaying 64-bit addresses in readelf and also fixes
showing backtraces from core dumps on x86_64.
2021-07-22 08:57:01 +02:00
Gunnar Beutner
5f6ee4c539 LibELF: Save the negative TLS offset in m_tls_offset
This makes it unnecessary to track the symbol size which just isn't
available for unexported symbols (e.g. for 'static __thread').
2021-07-04 01:07:28 +02:00
Gunnar Beutner
f9a8c6f053 LibELF: Implement support for RELA relocations 2021-07-01 10:50:00 +02:00
Gunnar Beutner
2eb025b2ea LibELF: Use correct accessor macros on x86_64 for some ELF fields 2021-06-29 20:03:36 +02:00
Andrew Kaster
7b4dc590e7 AK+Userland: Use akaster@serenityos.org for my copyright headers 2021-05-30 14:35:34 +01:00
Nicholas Baron
aa4d41fe2c
AK+Kernel+LibELF: Remove the need for IteratorDecision::Continue
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.
2021-05-16 10:36:52 +01:00
Gunnar Beutner
fdbe66a7b4 LibELF+LibC: Support building LibELF for 64-bit targets 2021-05-03 08:42:39 +02:00
Itamar
101ac45c1a LibELF: Change TLS offset calculation
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-30 18:47:39 +02:00
Gunnar Beutner
f40ee1b03f LibC+LibELF: Implement more fully-features dlfcn functionality
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-25 10:14:50 +02:00
Gunnar Beutner
f74b8a2d1f LibELF: Avoid calculating symbol hashes when we don't need them 2021-04-23 23:35:36 +02:00
Brian Gianforcaro
1682f0b760 Everything: Move to SPDX license identifiers in all files.
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-22 11:22:27 +02:00
Gunnar Beutner
6cb28ecee8 LibC+LibELF: Implement support for the dl_iterate_phdr helper
This helper is used by libgcc_s to figure out where the .eh_frame sections
are located for all loaded shared objects.
2021-04-18 10:55:25 +02:00
Brendan Coles
8ad74684ea LibELF: DynamicObject: Add rpath and runpath helpers 2021-03-22 17:46:05 +01:00
Brendan Coles
f8c603fe7e LibELF: DynamicObject: set for_each_symbol/for_each_dynamic_entry public 2021-03-21 09:40:30 +01:00
Brian Gianforcaro
141e6724d1 LibELF: Use StringView literal syntax to build section names. 2021-02-24 14:38:31 +01:00
Andreas Kling
b33a6a443e LibELF: Inline DynamicObject::hash_section()
This was high up in profiles and gets almost entirely optimized out
when inlined, so let's do that.
2021-02-23 20:33:32 +01:00
Andreas Kling
22b8110554 LibELF: Avoid doing strlen() on everything while iterating GNU hash
It's a lot faster to iterate the GNU hash tables if we don't have to
compute the length of every symbol name before rejecting it anyway while
comparing the first character. :^)
2021-02-23 19:43:44 +01:00
Andreas Kling
46a94a9a9e LibELF: Rename lookup_elf_symbol() => lookup_sysv_symbol()
We have two kinds of lookup, SYSV and GNU hash. Both are ELF lookups.
2021-02-23 19:43:44 +01:00
Andreas Kling
d6af3302e8 LibELF: Don't recompute the same ELF hashes over and over
When performing a global symbol lookup, we were recomputing the symbol
hashes once for every dynamic object searched. The hash function was
at the very top of a profile (15%) of program startup.

With this change, the hash function is no longer visible among the top
stacks in the profile. :^)
2021-02-23 19:43:44 +01:00
Andreas Kling
37420f1baf LibELF: Move ELF hash functions to their own file (and make constexpr) 2021-02-23 19:43:44 +01:00
Andreas Kling
f23b29f605 LibELF: Move DynamicObject::lookup_symbol() to DynamicLoader
Also simplify it by removing an unreachable code path.
2021-02-21 00:29:52 +01:00
Andreas Kling
a43910acc3 LibELF: Make SymbolLookupResult::address a VirtualAddress
Let's use a stronger type than void* for this since we're talking
specifically about a virtual address and not necessarily a pointer
to something actually in memory (yet).
2021-02-21 00:02:21 +01:00
Andreas Kling
c5d93e55d0 LibELF: Simplify DynamicObject::Symbol class a bit
We no longer need the create_undefined() helper function.
Also we don't need a member field for is_undefined().
2021-02-21 00:02:21 +01:00
Andreas Kling
1997d5de1a LibELF: Make symbol lookup functions return Optional<Symbol>
It was very confusing how these functions used the "undefined" state
of Symbol to signal lookup failure. Let's use Optional<T> to make things
a bit more understandable.
2021-02-21 00:02:21 +01:00
Andreas Kling
ba1eea9898 LibELF+DynamicLoader: Rename DynamicObject::construct() => create() 2021-02-21 00:02:21 +01:00
Andreas Kling
01f1e480e5 LibELF: Fix various clang-tidy warnings
Remove a bunch of unused code, unnecessary const, and make some
non-object-specific member functions static.
2021-02-21 00:02:21 +01:00
Andreas Kling
0c0127dc3f LibELF: Use StringView instead of "const char*" in dynamic linker code
There's no reason to use C strings more than absolutely necessary.
2021-02-20 22:29:12 +01:00
Andreas Kling
4df3a34bc2 LibELF: Only set up PLT trampoline for objects with a PLT 2021-02-05 12:10:45 +01:00
Andreas Kling
41d8734288 LibELF: Use Optional<SymbolLookupResult> as a return type
Instead of storing a "found" state inside the result object.
2021-01-25 18:57:06 +01:00
Linus Groh
6715ca3e16 LibELF: Remove unused m_global_symbol_lookup_func from DynamicObject
This was refactored in 3e815ad, leaving this unused member behind.
2021-01-18 19:17:52 +01:00
Andreas Kling
13d7c09125 Libraries: Move to Userland/Libraries/ 2021-01-12 12:17:46 +01:00
Renamed from Libraries/LibELF/DynamicObject.h (Browse further)