This commit introduces the changes needed in the port build system that
will allow us to compile ports with Clang. Note that many ports still
don't build, especially due to linker differences. Fixing these is
outside the scope of this PR.
For now, building bash, ncurses and nano is known to work. Bash runs
fine, while nano crashes due to DT_VERSYM not being supported by our
dynamic loader.
By enabling LTO for the kernel_heap object too, we open the door for
optimization opportunities that come from (partially) inlining `::new`
or kmalloc. Every software spends a non-trivial amount of its run time
on allocating memory, so hopefully this change will make LTO builds even
faster.
This commit updates the Clang toolchain's version to 13.0.0, which comes
with better C++20 support and improved handling of new features by
clang-format. Due to the newly enabled `-Bsymbolic-functions` flag, our
Clang binaries will only be 2-4% slower than if we dynamically linked
them, but we save hundreds of megabytes of disk space.
The `BuildClang.sh` script has been reworked to build the entire
toolchain in just three steps: one for the compiler, one for GNU
binutils, and one for the runtime libraries. This reduces the complexity
of the build script, and will allow us to modify the CI configuration to
only rebuild the libraries when our libc headers change.
Most of the compile flags have been moved out to a separate CMake cache
file, similarly to how the Android and Fuchsia toolchains are
implemented within the LLVM repo. This provides a nicer interface than
the heaps of command-line arguments.
We no longer build separate toolchains for each architecture, as the
same Clang binary can compile code for multiple targets.
The horrible mess that `SERENITY_CLANG_ARCH` was, has been removed in
this commit. Clang happily accepts an `i686-pc-serenity` target triple,
which matches what our GCC toolchain accepts.
LLD fails to define the _GLOBAL_OFFSET_TABLE_ symbol if all inputs to it
are LLVM bitcode files (i.e. those used for LTO). To allow the kernel to
be built with ThinLTO, the workaround suggested in the original LLVM bug
report (<https://bugs.llvm.org/show_bug.cgi?id=39634>) is added in this
commit.
Previously we rejected all entries from Loader.so even if the faulting
address was located in it, i.e. the actual issue was with the dynamic
loader. We no longer do that to make debugging Loader crashes easier.
Our implementation (naively) assumes that there is a one-to-one
correspondence between compilation units and line programs, and that
their orders are identical. This is not the case for embedded resources,
as Clang only creates line programs for it, but not compilation units.
This mismatch caused an assertion failure, which made generating
backtraces for GUI applications impossible. This commit introduces a
hack that skips creating CompilationUnit objects for LinePrograms that
come from embedded resources.
These forms were introduced in DWARF5, and have a fair deal of
advantages over the more traditional encodings: they reduce the size of
the binary and the number of relocations.
GCC does not emit these with `-g1` by default, but Clang does at all
debug levels.
This will be needed when we add `DW_FORM_strx*` and `DW_FORM_addrx*`
support, which requires us to fetch `DW_AT_str_offsets_base` and
`DW_AT_addr_base` attributes from the parent compilation unit. This
can't be done as we read the values, because it would create infinite
recursion (as we might try to parse the compilation unit's
`DW_FORM_strx*` encoded name before we get to the attribute). Having
getters ensures that we will perform lookups if they are needed.
Our Clang toolchain uses versioned names for its shared libraries,
meaning that our applications link against `libc++.so.1.0`, not simply
`libc++.so`. Without this change, the LLVM runtime libraries are
excluded from backtraces, which makes debugging toolchain issues harder.
There is no need to have a user-defined copy constructor that simply
calls the base class's copy constructor. By having the compiler generate
it for us, Span is made trivially copyable, so it can be passed in
registers.
This allows the linker to link against these dynamic libraries when
compiling libc++/libunwind, without having to do a separate
bootstrapping LibC build.
Without this change, libc++ would fail to pick up the need to link to
`LibPthread` if no prior builds of it existed. Because of this, we'd
immediately have an assertion failure in SystemServer, as mutexes are
used for the safe construction of function-local static variables.
The `wcsxfrm` function copies a wide character string into a buffer,
such that comparing the new string against any similarly pre-processed
string with `wcscmp` produces the same result as if the original strings
were compared with `wcscoll`.
Our current `wcscoll` implementation is simply an alias for `wcscmp`, so
`wcsxfrm` needs to perform no actions other than copying the string.
The ELAST macro is used on many systems to refer to the largest possible
valid errno value. LLVM's libc++ uses errno values of ELAST+1 and
ELAST+2 internally, and defines an arbitrary fallback value for
platforms which don't have the macro. This means that it's possible for
their internal errno numbers could coincide with values we actually use,
which would be a very bad thing.
Note our Attribute class is what the spec refers to as just "Attr". The
main differences between the existing implementation and the spec are
just that the spec defines more fields.
Attributes can contain namespace URIs and prefixes. However, note that
these are not parsed in HTML documents unless the document content-type
is XML. So for now, these are initialized to null. Web pages are able to
set the namespace via JavaScript (setAttributeNS), so these fields may
be filled in when the corresponding APIs are implemented.
The main change to be aware of is that an attribute is a node. This has
implications on how attributes are stored in the Element class. Nodes
are non-copyable and non-movable because these constructors are deleted
by the EventTarget base class. This means attributes cannot be stored in
a Vector or HashMap as these containers assume copyability / movability.
So for now, the Vector holding attributes is changed to hold RefPtrs to
attributes instead. This might change when attribute storage is
implemented according to the spec (by way of NamedNodeMap).
ProcFSGlobalInode now calls `write_bytes()`, `truncate()` and
`set_mtime()` on its associated component. This allows us to write 0 or
1 to a ProcFSSystemBoolean component to toggle a boolean value.