aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/kernel/drivers/init.cpp17
-rw-r--r--kernel/kernel/vfs/driver_registry.cpp21
2 files changed, 28 insertions, 10 deletions
diff --git a/kernel/kernel/drivers/init.cpp b/kernel/kernel/drivers/init.cpp
index f0e78593..ab0f6426 100644
--- a/kernel/kernel/drivers/init.cpp
+++ b/kernel/kernel/drivers/init.cpp
@@ -6,6 +6,7 @@
#include <kstd/memory.hpp>
#include <kstd/print.hpp>
+#include <new>
#include <ranges>
#include <span>
#include <utility>
@@ -16,10 +17,15 @@ namespace kernel::drivers
extern "C"
{
// We need to suppress clang-tidy linting warnings here, since these symbols are generated by the linker and we
- // cannot choose their names, unless we wanted to extend the linker script needlessly.
+ // cannot choose their names, unless we want to write a bht linker script for no reason. Additionally, these symbols
+ // need to be arrays, because otherwise any pointer arithmetic on them, beyond trivial cases of adding 0 or 1, is
+ // undefined behavior by the rules of the C++ abstract machine. To ensure the compiler does not try to perform
+ // constant folding, the pointers, these arrays of unknown bound decay to, need to be laundered before dereferencing
+ // them.
+
// NOLINTBEGIN(readability-identifier-naming)
- extern kstd::observer_ptr<kapi::devices::driver_descriptor> const __start_kernel_drivers;
- extern kstd::observer_ptr<kapi::devices::driver_descriptor> const __stop_kernel_drivers;
+ extern kstd::observer_ptr<kapi::devices::driver_descriptor> const __start_kernel_drivers[];
+ extern kstd::observer_ptr<kapi::devices::driver_descriptor> const __stop_kernel_drivers[];
// NOLINTEND(readability-identifier-naming)
}
@@ -29,7 +35,10 @@ namespace kernel::drivers
auto & registry = kapi::devices::driver_registry::get();
- auto descriptors = std::span{&__start_kernel_drivers, &__stop_kernel_drivers} | //
+ auto clean_start = std::launder(__start_kernel_drivers);
+ auto clean_stop = std::launder(__stop_kernel_drivers);
+
+ auto descriptors = std::span{clean_start, clean_stop} | //
std::views::filter([](auto p) { return p != nullptr; });
for (auto driver : descriptors)
diff --git a/kernel/kernel/vfs/driver_registry.cpp b/kernel/kernel/vfs/driver_registry.cpp
index 736cfcbc..cfb8c748 100644
--- a/kernel/kernel/vfs/driver_registry.cpp
+++ b/kernel/kernel/vfs/driver_registry.cpp
@@ -14,6 +14,7 @@
#include <algorithm>
#include <cstdint>
#include <functional>
+#include <new>
#include <optional>
#include <ranges>
#include <span>
@@ -26,10 +27,15 @@ namespace kernel::vfs
extern "C"
{
// We need to suppress clang-tidy linting warnings here, since these symbols are generated by the linker and we
- // cannot choose their names, unless we wanted to extend the linker script needlessly.
+ // cannot choose their names, unless we want to write a bht linker script for no reason. Additionally, these symbols
+ // need to be arrays, because otherwise any pointer arithmetic on them, beyond trivial cases of adding 0 or 1, is
+ // undefined behavior by the rules of the C++ abstract machine. To ensure the compiler does not try to perform
+ // constant folding, the pointers, these arrays of unknown bound decay to, need to be laundered before dereferencing
+ // them.
+
// NOLINTBEGIN(readability-identifier-naming)
- extern kstd::observer_ptr<driver_descriptor const> const __start_filesystem_drivers;
- extern kstd::observer_ptr<driver_descriptor const> const __stop_filesystem_drivers;
+ extern kstd::observer_ptr<driver_descriptor const> const __start_filesystem_drivers[];
+ extern kstd::observer_ptr<driver_descriptor const> const __stop_filesystem_drivers[];
// NOLINTEND(readability-identifier-naming)
}
@@ -47,10 +53,13 @@ namespace kernel::vfs
instance.emplace();
+ auto clean_start = std::launder(__start_filesystem_drivers);
+ auto clean_stop = std::launder(__stop_filesystem_drivers);
+
auto instances =
- std::span{&__start_filesystem_drivers, &__stop_filesystem_drivers} |
- std::views::filter([](auto descriptor) { return descriptor != nullptr; }) |
- std::views::transform([](auto descriptor) { return std::pair{descriptor, descriptor->make_instance()}; }) |
+ std::span{clean_start, clean_stop} | //
+ std::views::filter([](auto descriptor) { return descriptor != nullptr; }) | //
+ std::views::transform([](auto descriptor) { return std::pair{descriptor, descriptor->make_instance()}; }) | //
std::views::filter([](auto entry) { return entry.second != nullptr; });
std::ranges::for_each(instances, [](auto entry) {