Files
serenity/Kernel/HiddenVisibility.h
Sönke Holz d7f65d06d6 Kernel: Give all declarations hidden visibility
This causes GCC and Clang to generate relative loads when accessing
global variables instead of using the global offset table (GOT).
This saves one load for every global variable access.
We unfortunately have to do this by injecting a header into every
source file, since "-fvisibility=hidden" doesn't affect `extern`
declarations.

This additionally means that accessing global variables doesn't
depend on relocations anymore, so pre_init code no longer needs to
access variables through `adjust_by_mapping_base()`.
Next to this, some other small tweaks are required in pre_init because
global variables now have the "correct" addresses while we are still
identity mapped.

Being able to simplify pre_init like this was also the original
motivation for this patch. Clang trunk started optimizing
`adjust_by_mapping_base()` on AArch64 such that it avoids using the GOT
when we attempt to get the address of the global variable in high
memory. As a consequence, we now directly get the address in low memory
on Clang trunk, causing us to redundantly subtract the physical to link
time address offset and end up with an incorrect address.
With this patch, we no longer need to rely on the compiler not doing
such optimizations anymore.

The .got section still exists on non-x86 but only contains 2-3 entries:
- the start of the .dynamic section (I'm not sure why),
- the __stack_chk_guard (only actually used on RISC-V GCC),
- __clz_tab (only on RISC-V GCC).
Additionally, there are some other GOT entries caused by the RISC-V `la`
pseudo-instruction, which will be removed in the next commit.
It's a bit unfortunate that RISC-V GCC still uses the GOT to access the
stack protector (__stack_chk_guard), but that's not under our control.

RISC-V GCC and AArch64 GCC also still contain a .got.plt section, but
none of the other toolchain+architecture combinations.
2026-08-05 15:39:22 +02:00

15 lines
546 B
C

/*
* Copyright (c) 2026, Sönke Holz <[email protected]>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
// This header is injected into every source file via -include.
// It gives all declarations hidden visibility, preventing global variable accesses from going through the global offset table (GOT).
// GOT indirections are unnecessary in the kernel since it isn't dynamically linked.
// "-fvisibility=hidden" isn't sufficient because it doesn't make `extern` declarations hidden.
#pragma GCC visibility push(hidden)