mirror of
https://github.com/SerenityOS/serenity.git
synced 2026-11-07 04:29:30 -10:00
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.
15 lines
546 B
C
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)
|