From 22fbbf849497c32f5b237ab70e9ed8aef63e54cf Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 14 Jul 2025 15:21:32 +0000 Subject: libs: extract multiboot library --- libs/multiboot2/CMakeLists.txt | 26 ++++ libs/multiboot2/include/multiboot2/constants.hpp | 20 +++ libs/multiboot2/include/multiboot2/impl/data.hpp | 130 +++++++++++++++++ libs/multiboot2/include/multiboot2/impl/ids.hpp | 79 ++++++++++ .../include/multiboot2/impl/iterator.hpp | 63 ++++++++ libs/multiboot2/include/multiboot2/impl/tag.hpp | 113 +++++++++++++++ libs/multiboot2/include/multiboot2/information.hpp | 160 +++++++++++++++++++++ 7 files changed, 591 insertions(+) create mode 100644 libs/multiboot2/CMakeLists.txt create mode 100644 libs/multiboot2/include/multiboot2/constants.hpp create mode 100644 libs/multiboot2/include/multiboot2/impl/data.hpp create mode 100644 libs/multiboot2/include/multiboot2/impl/ids.hpp create mode 100644 libs/multiboot2/include/multiboot2/impl/iterator.hpp create mode 100644 libs/multiboot2/include/multiboot2/impl/tag.hpp create mode 100644 libs/multiboot2/include/multiboot2/information.hpp (limited to 'libs/multiboot2') diff --git a/libs/multiboot2/CMakeLists.txt b/libs/multiboot2/CMakeLists.txt new file mode 100644 index 0000000..af56d5a --- /dev/null +++ b/libs/multiboot2/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION "3.27") + +project("multiboot2" + LANGUAGES CXX + VERSION "1.0.0" +) + +add_library("multiboot2" INTERFACE) +add_library("multiboot2::multiboot2" ALIAS "multiboot2") + +target_sources("multiboot2" INTERFACE + FILE_SET HEADERS + BASE_DIRS "include" + FILES + "include/multiboot2/constants.hpp" + "include/multiboot2/information.hpp" + + "include/multiboot2/impl/data.hpp" + "include/multiboot2/impl/ids.hpp" + "include/multiboot2/impl/iterator.hpp" + "include/multiboot2/impl/tag.hpp" +) + +target_include_directories("multiboot2" INTERFACE + "include" +) diff --git a/libs/multiboot2/include/multiboot2/constants.hpp b/libs/multiboot2/include/multiboot2/constants.hpp new file mode 100644 index 0000000..30d52d0 --- /dev/null +++ b/libs/multiboot2/include/multiboot2/constants.hpp @@ -0,0 +1,20 @@ +#ifndef MULTIBOOT2_CONSTANTS_HPP +#define MULTIBOOT2_CONSTANTS_HPP + +#include "impl/ids.hpp" // IWYU pragma: export + +#include + +namespace multiboot2 +{ + + using impl::architecture_id; + using impl::information_id; + using impl::memory_type; + using impl::tag_id; + + auto constexpr inline header_magic = std::uint32_t{0xe85250d6}; + +} // namespace multiboot2 + +#endif diff --git a/libs/multiboot2/include/multiboot2/impl/data.hpp b/libs/multiboot2/include/multiboot2/impl/data.hpp new file mode 100644 index 0000000..367e8cb --- /dev/null +++ b/libs/multiboot2/include/multiboot2/impl/data.hpp @@ -0,0 +1,130 @@ +#ifndef MULTIBOOT2_IMPL_DATA_HPP +#define MULTIBOOT2_IMPL_DATA_HPP + +#include "multiboot2/impl/ids.hpp" + +#include + +namespace multiboot2::impl +{ + template + struct tag_data + { + auto constexpr inline static id = Id; + }; + + /** + * @brief Basic system memory information + */ + struct basic_memory_data : tag_data + { + /** + * @brief Amount of lower memory (below 1MiB) available to the system. + * + * The maximum possible value for this field is 640 KiB. + */ + std::uint32_t const lower_KiB; + + /** + * @brief Amount of upper memory (above 1MiB) available to the system. + * + * The maximum possible value for this field is the address of the first upper memory hole minus 1MiB. + */ + std::uint32_t const upper_KiB; + }; + + /** + * @brief Device the image got loaded from + */ + struct bios_boot_device_data : tag_data + { + /** + * @brief BIOS device number as understood by INT 13h. + */ + std::uint32_t device_number; + + /** + * @brief Number of the primary partition. + */ + std::uint32_t partition_number; + + /** + * @brief Number the sub-partion on the primary partition. + */ + std::uint32_t sub_partition_number; + }; + + /** + * @brief Supplied image command line + */ + struct command_line_data : tag_data + { + /* This struct intentionally left blank. */ + }; + + /** + * @brief ELF symbols of the image + */ + struct elf_symbols_data : tag_data + { + std::uint32_t count; + std::uint32_t entry_size; + std::uint32_t string_table_index; + }; + + /** + * @brief Name of the boot loader + */ + struct loader_name_data : tag_data + { + /* This struct intentionally left blank. */ + }; + + /** + * @brief Detailed map of the memory regions present in the system + * + */ + struct memory_map_data : tag_data + { + /** + * @brief A region of memory + */ + struct region + { + /** + * @brief Check if the memory described by this region is available for use. + */ + auto constexpr available() const noexcept { return type == memory_type::AVAILABLE; } + + /** + * @brief Start address of this region + */ + std::uint64_t const base; + + /** + * @brief Size of this region in bytes. + */ + std::uint64_t const size_in_B; + + /** + * @brief Type of this region. + */ + memory_type const type; + + std::uint32_t : 0; + }; + + /** + * @brief Size of each entry present in the map + */ + std::uint32_t const entry_size; + + /** + * @brief Version of each entry present in the map + */ + std::uint32_t const entry_version; + }; + +} // namespace multiboot2::impl + +#endif \ No newline at end of file diff --git a/libs/multiboot2/include/multiboot2/impl/ids.hpp b/libs/multiboot2/include/multiboot2/impl/ids.hpp new file mode 100644 index 0000000..3a7215e --- /dev/null +++ b/libs/multiboot2/include/multiboot2/impl/ids.hpp @@ -0,0 +1,79 @@ +#ifndef MULTIBOOT2_IMPL_IDS_HPP +#define MULTIBOOT2_IMPL_IDS_HPP + +#include + +namespace multiboot2::impl +{ + + /** + * @brief Information tag IDs. + */ + enum struct information_id : std::uint32_t + { + END, ///< Signals final tag for the multiboot2 information structure. + CMDLINE, ///< Contains the command line string. + BOOT_LOADER_NAME, ///< Contains the name of the boot loader booting the kernel. + MODULE, ///< Indicates the boot module which was loaded along the kernel image. + BASIC_MEMORY_INFO, ///< Contains the amount of lower (0MB start address) and upper memory (1MB start address). + BOOTDEV, ///< Indicates which BIOS disk device the hoot loader has loaded the OS image from. + MEMORY_MAP, ///< Describes the memory layout of the system with individual areas and their flags. + VBE_INFO, ///< Includes information to access and utilize the device GPU. + FRAMEBUFFER, ///< VBE framebuffer information. + ELF_SECTIONS, ///< Includes list of all section headers from the loaded ELF kernel. + APM_INFO, ///< Advanced Power Management information. + EFI32, ///< EFI 32 bit system table pointer. + EFI64, ///< EFI 64 bit system table pointer. + SMBIOS, ///< Contains copy of all Sytem Management BIOS tables. + ACPI_OLD, ///< Contains copy of RSDP as defined per ACPI1.0 specification. + ACPI_NEW, ///< Contains copy of RSDP as defined per ACPI2.0 or later specification. + NETWORK, ///< Contains network information specified specified as DHCP. + EFI_MEMORY_MAP, ///< Contains EFI memory map. + EFI_BS_NOT_TERMINATED, ///< Indicated ExitBootServies wasn't called. + EFI32_IMAGE_HANDLE, ///< EFI 32 bit image handle pointer. + EFI64_IMAGE_HANDLE, ///< EFI 64 bit imae handle pointer. + LOAD_BASE_ADDRESS ///< Contains image load base physical address. + }; + + /** + * @brief Header tag IDs. + */ + enum struct tag_id : std::uint32_t + { + END, + INFORMATION_REQUEST, + ADDRESSES, + ENTRY_ADDRESS, + CONSOLE_FLAGS, + PREFERRED_FRAMEBUFFER_MODE, + PAGE_ALIGN_MODULES, + EFI_BOOT_SERVICES_SUPPORTED, + EFI32_ENTRY_ADDRESS, + EFI64_ENTRY_ADDRESS, + RELOCATABLE, + }; + + /** + * @brief System architecture IDs. + */ + enum struct architecture_id : std::uint32_t + { + I386 = 0, + MIPS32 = 4, + }; + + /** + * @brief Memory type IDs. + */ + enum struct memory_type : std::uint32_t + { + AVAILABLE = 1, + RESERVED, + ACPI_RECLAIMABLE, + NON_VOLATILE_STORAGE, + BAD_RAM, + }; + +} // namespace multiboot2::impl + +#endif \ No newline at end of file diff --git a/libs/multiboot2/include/multiboot2/impl/iterator.hpp b/libs/multiboot2/include/multiboot2/impl/iterator.hpp new file mode 100644 index 0000000..b84ef2c --- /dev/null +++ b/libs/multiboot2/include/multiboot2/impl/iterator.hpp @@ -0,0 +1,63 @@ +#ifndef MULTIBOOT2_IMPL_INFORMATION_ITERATOR_HPP +#define MULTIBOOT2_IMPL_INFORMATION_ITERATOR_HPP + +#include "multiboot2/impl/ids.hpp" +#include "multiboot2/impl/tag.hpp" + +#include +#include +#include + +namespace multiboot2::impl +{ + + struct information_iterator + { + using iterator_category = std::forward_iterator_tag; + using value_type = impl::tag_header; + using pointer = value_type const *; + using reference = value_type const &; + using difference_type = std::ptrdiff_t; + + constexpr information_iterator() = default; + + constexpr explicit information_iterator(impl::tag_header const * offset) + : m_current(offset) + { + } + + auto constexpr operator==(information_iterator const &) const noexcept -> bool = default; + + auto constexpr operator*() const noexcept -> reference { return *(m_current.value()); } + + auto constexpr operator->() const noexcept -> pointer { return m_current.value(); } + + auto constexpr operator++() noexcept -> information_iterator & + { + if (m_current) + { + if (auto next = m_current.value()->next(); next->information_id() != information_id::END) + { + m_current = next; + } + m_current.reset(); + } + return *this; + } + + auto constexpr operator++(int) noexcept -> information_iterator + { + auto copy = *this; + ++(*this); + return copy; + } + + private: + std::optional m_current{}; + }; + + static_assert(std::input_or_output_iterator); + +} // namespace multiboot2::impl + +#endif \ No newline at end of file diff --git a/libs/multiboot2/include/multiboot2/impl/tag.hpp b/libs/multiboot2/include/multiboot2/impl/tag.hpp new file mode 100644 index 0000000..f7471a4 --- /dev/null +++ b/libs/multiboot2/include/multiboot2/impl/tag.hpp @@ -0,0 +1,113 @@ +#ifndef MULTIBOOT2_IMPL_TAG_HPP +#define MULTIBOOT2_IMPL_TAG_HPP + +#include "multiboot2/impl/ids.hpp" + +#include +#include +#include + +namespace multiboot2::impl +{ + + /** + * @brief Header data and functionality shared by all tags. + */ + struct tag_header + { + tag_header() + : m_id{} + , m_size{} + { + } + + tag_header(tag_header const * data) + : tag_header{*data} + { + } + + auto full_size() const noexcept -> std::size_t { return (m_size + 7) & (~7); } + + auto information_id() const noexcept -> impl::information_id const & { return m_id; } + + auto next() const noexcept -> tag_header const * + { + return std::bit_cast(std::bit_cast(this) + full_size()); + } + + auto unaligned_size() const noexcept -> std::uint32_t { return m_size; } + + protected: + impl::information_id const m_id; + std::uint32_t const m_size; + }; + + /** + * @brief A tag containing no variable length array data. + */ + template + struct tag : tag_header, Data + { + tag() + : tag_header{} + , Data{} + { + } + + explicit tag(tag_header const * header) + requires(sizeof(tag) > sizeof(tag_header)) + : tag_header{header} + , Data{*std::bit_cast(header + 1)} + { + } + + explicit tag(tag_header const * header) + requires(sizeof(tag) == sizeof(tag_header)) + : tag_header{header} + , Data{} + { + } + }; + + /** + * @brief A tag containing variable length array data. + */ + template typename Range> + struct vla_tag : tag + { + using range_type = Range; + + vla_tag() + : tag{} + , m_vla{} + { + } + + explicit vla_tag(tag_header const * header) + : tag{header} + , m_vla{vla_start(header), vla_size(header)} + { + } + + protected: + auto static vla_start(tag_header const * header) noexcept -> VlaData * + { + auto raw = std::bit_cast(header); + auto start = raw + sizeof(tag); + return std::bit_cast(start); + } + + auto static vla_size(tag_header const * header) noexcept -> std::size_t + { + auto size = (header->unaligned_size() - sizeof(tag) - + std::is_same_v> * 1) / + sizeof(VlaData); + return size; + } + + range_type const m_vla; + }; + +} // namespace multiboot2::impl + +#endif \ No newline at end of file diff --git a/libs/multiboot2/include/multiboot2/information.hpp b/libs/multiboot2/include/multiboot2/information.hpp new file mode 100644 index 0000000..04ba183 --- /dev/null +++ b/libs/multiboot2/include/multiboot2/information.hpp @@ -0,0 +1,160 @@ +#ifndef JOS_MULTIBOOT2_INFORMATION_HPP +#define JOS_MULTIBOOT2_INFORMATION_HPP + +#include "impl/data.hpp" +#include "impl/iterator.hpp" +#include "impl/tag.hpp" + +#include +#include +#include +#include +#include +#include + +namespace multiboot2 +{ + + /** + * @copydoc multiboot2::impl::basic_memory_data + */ + struct basic_memory : impl::tag + { + using tag::tag; + }; + + /** + * @copydoc multiboot2::impl::bios_boot_device_data + */ + struct bios_boot_device : impl::tag + { + using tag::tag; + }; + + /** + * @copydoc multiboot2::impl::command_line_data + */ + struct command_line : impl::vla_tag + { + using vla_tag::vla_tag; + + /** + * @brief The command line string + */ + auto string() const noexcept -> range_type { return m_vla; } + }; + + /** + * @copydoc multiboot2::impl::elf_symbols_data + */ + struct elf_symbols : impl::vla_tag + { + using vla_tag::vla_tag; + + using iterator = range_type::iterator; + + auto data() const noexcept -> range_type { return m_vla; } + }; + + /** + * @copydoc multiboot2::impl::loader_name_data + */ + struct loader_name : impl::vla_tag + { + using vla_tag::vla_tag; + + /** + * @brief The name of the bootloader + */ + auto string() const noexcept -> std::string_view { return m_vla; } + }; + + /** + * @copydoc multiboot2::impl::memory_map_data + */ + struct memory_map : impl::vla_tag + { + using vla_tag::vla_tag; + + using iterator = range_type::iterator; + + auto begin() const noexcept -> iterator { return regions().begin(); } + + auto end() const noexcept -> iterator { return regions().end(); } + + /** + * @brief The available memory regions + */ + auto regions() const noexcept -> range_type { return m_vla; } + }; + + struct information_view + { + using iterator = impl::information_iterator; + using value_type = impl::information_iterator::value_type; + using pointer = impl::information_iterator::pointer; + using reference = impl::information_iterator::reference; + + auto size_bytes() const noexcept -> std::size_t { return m_size; } + + // Range access + + auto begin() const noexcept -> iterator { return iterator{&m_tags}; } + + auto end() const noexcept -> iterator { return iterator{}; } + + // Tag access + + template + auto has() const noexcept -> bool + { + return get().has_value(); + } + + auto maybe_basic_memory() const noexcept -> std::optional { return get(); } + + auto basic_memory() const -> basic_memory { return maybe_basic_memory().value(); } + + auto maybe_bios_boot_device() const noexcept -> std::optional + { + return get(); + } + + auto bios_boot_device() const -> bios_boot_device { return maybe_bios_boot_device().value(); } + + auto maybe_command_line() const noexcept -> std::optional { return get(); } + + auto command_line() const -> command_line { return maybe_command_line().value(); } + + auto maybe_elf_symbols() const noexcept -> std::optional { return get(); } + + auto elf_symbols() const -> elf_symbols { return maybe_elf_symbols().value(); } + + auto maybe_loader_name() const noexcept -> std::optional { return get(); } + + auto loader_name() const -> loader_name { return maybe_loader_name().value(); } + + auto maybe_memory_map() const noexcept -> std::optional { return get(); } + + auto memory_map() const -> memory_map { return maybe_memory_map().value(); } + + private: + template + auto constexpr get() const noexcept -> std::optional + { + if (auto found = std::ranges::find_if(*this, [](auto tag) { return tag.information_id() == Tag::id; }); + found != end()) + { + return Tag{&*found}; + } + return std::nullopt; + } + + [[maybe_unused]] uint32_t const m_size{}; + uint32_t : 32; + impl::tag_header const m_tags{}; + }; + +} // namespace multiboot2 + +#endif \ No newline at end of file -- cgit v1.2.3 From 1b603d1145b9ee10b1b12a0f765bd2bc1ebe2b3c Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 14 Jul 2025 15:39:59 +0000 Subject: libs: rename multiboot alias --- libs/multiboot2/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libs/multiboot2') diff --git a/libs/multiboot2/CMakeLists.txt b/libs/multiboot2/CMakeLists.txt index af56d5a..386a127 100644 --- a/libs/multiboot2/CMakeLists.txt +++ b/libs/multiboot2/CMakeLists.txt @@ -6,7 +6,7 @@ project("multiboot2" ) add_library("multiboot2" INTERFACE) -add_library("multiboot2::multiboot2" ALIAS "multiboot2") +add_library("libs::multiboot2" ALIAS "multiboot2") target_sources("multiboot2" INTERFACE FILE_SET HEADERS -- cgit v1.2.3 From ec572bff8150e2f8cd2dc99e053c5e8c8a0b99e3 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 14 Jul 2025 16:25:00 +0000 Subject: arch: prepare interfaces --- libs/multiboot2/CMakeLists.txt | 7 ------- 1 file changed, 7 deletions(-) (limited to 'libs/multiboot2') diff --git a/libs/multiboot2/CMakeLists.txt b/libs/multiboot2/CMakeLists.txt index 386a127..7b9e58a 100644 --- a/libs/multiboot2/CMakeLists.txt +++ b/libs/multiboot2/CMakeLists.txt @@ -1,10 +1,3 @@ -cmake_minimum_required(VERSION "3.27") - -project("multiboot2" - LANGUAGES CXX - VERSION "1.0.0" -) - add_library("multiboot2" INTERFACE) add_library("libs::multiboot2" ALIAS "multiboot2") -- cgit v1.2.3 From 14ed096fc5de6844cb116f3319c0d03043d26ea2 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 17 Jul 2025 21:09:02 +0000 Subject: x86-64: prepare new architecture --- libs/multiboot2/include/multiboot2/impl/data.hpp | 6 +++--- libs/multiboot2/include/multiboot2/impl/iterator.hpp | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'libs/multiboot2') diff --git a/libs/multiboot2/include/multiboot2/impl/data.hpp b/libs/multiboot2/include/multiboot2/impl/data.hpp index 367e8cb..a5f2e14 100644 --- a/libs/multiboot2/include/multiboot2/impl/data.hpp +++ b/libs/multiboot2/include/multiboot2/impl/data.hpp @@ -99,17 +99,17 @@ namespace multiboot2::impl /** * @brief Start address of this region */ - std::uint64_t const base; + std::uint64_t base; /** * @brief Size of this region in bytes. */ - std::uint64_t const size_in_B; + std::uint64_t size_in_B; /** * @brief Type of this region. */ - memory_type const type; + memory_type type; std::uint32_t : 0; }; diff --git a/libs/multiboot2/include/multiboot2/impl/iterator.hpp b/libs/multiboot2/include/multiboot2/impl/iterator.hpp index b84ef2c..e82326d 100644 --- a/libs/multiboot2/include/multiboot2/impl/iterator.hpp +++ b/libs/multiboot2/include/multiboot2/impl/iterator.hpp @@ -40,7 +40,10 @@ namespace multiboot2::impl { m_current = next; } - m_current.reset(); + else + { + m_current.reset(); + } } return *this; } -- cgit v1.2.3 From b157e2c472d8bd67ac1656404a6a6ee821260f4b Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 29 Oct 2025 15:01:43 +0100 Subject: chore: reformat source code --- libs/multiboot2/include/multiboot2/constants.hpp | 2 +- libs/multiboot2/include/multiboot2/impl/data.hpp | 7 +- .../include/multiboot2/impl/iterator.hpp | 19 ++-- libs/multiboot2/include/multiboot2/impl/tag.hpp | 34 +++---- libs/multiboot2/include/multiboot2/information.hpp | 102 ++++++++++++++++----- 5 files changed, 117 insertions(+), 47 deletions(-) (limited to 'libs/multiboot2') diff --git a/libs/multiboot2/include/multiboot2/constants.hpp b/libs/multiboot2/include/multiboot2/constants.hpp index 30d52d0..0f6b82f 100644 --- a/libs/multiboot2/include/multiboot2/constants.hpp +++ b/libs/multiboot2/include/multiboot2/constants.hpp @@ -13,7 +13,7 @@ namespace multiboot2 using impl::memory_type; using impl::tag_id; - auto constexpr inline header_magic = std::uint32_t{0xe85250d6}; + constexpr auto inline header_magic = std::uint32_t{0xe852'50d6}; } // namespace multiboot2 diff --git a/libs/multiboot2/include/multiboot2/impl/data.hpp b/libs/multiboot2/include/multiboot2/impl/data.hpp index a5f2e14..3cda162 100644 --- a/libs/multiboot2/include/multiboot2/impl/data.hpp +++ b/libs/multiboot2/include/multiboot2/impl/data.hpp @@ -10,7 +10,7 @@ namespace multiboot2::impl template struct tag_data { - auto constexpr inline static id = Id; + constexpr auto static inline id = Id; }; /** @@ -94,7 +94,10 @@ namespace multiboot2::impl /** * @brief Check if the memory described by this region is available for use. */ - auto constexpr available() const noexcept { return type == memory_type::AVAILABLE; } + constexpr auto available() const noexcept + { + return type == memory_type::AVAILABLE; + } /** * @brief Start address of this region diff --git a/libs/multiboot2/include/multiboot2/impl/iterator.hpp b/libs/multiboot2/include/multiboot2/impl/iterator.hpp index e82326d..f8955cb 100644 --- a/libs/multiboot2/include/multiboot2/impl/iterator.hpp +++ b/libs/multiboot2/include/multiboot2/impl/iterator.hpp @@ -23,16 +23,21 @@ namespace multiboot2::impl constexpr explicit information_iterator(impl::tag_header const * offset) : m_current(offset) - { - } + {} - auto constexpr operator==(information_iterator const &) const noexcept -> bool = default; + constexpr auto operator==(information_iterator const &) const noexcept -> bool = default; - auto constexpr operator*() const noexcept -> reference { return *(m_current.value()); } + constexpr auto operator*() const noexcept -> reference + { + return *(m_current.value()); + } - auto constexpr operator->() const noexcept -> pointer { return m_current.value(); } + constexpr auto operator->() const noexcept -> pointer + { + return m_current.value(); + } - auto constexpr operator++() noexcept -> information_iterator & + constexpr auto operator++() noexcept -> information_iterator & { if (m_current) { @@ -48,7 +53,7 @@ namespace multiboot2::impl return *this; } - auto constexpr operator++(int) noexcept -> information_iterator + constexpr auto operator++(int) noexcept -> information_iterator { auto copy = *this; ++(*this); diff --git a/libs/multiboot2/include/multiboot2/impl/tag.hpp b/libs/multiboot2/include/multiboot2/impl/tag.hpp index f7471a4..f151b54 100644 --- a/libs/multiboot2/include/multiboot2/impl/tag.hpp +++ b/libs/multiboot2/include/multiboot2/impl/tag.hpp @@ -18,24 +18,31 @@ namespace multiboot2::impl tag_header() : m_id{} , m_size{} - { - } + {} tag_header(tag_header const * data) : tag_header{*data} + {} + + auto full_size() const noexcept -> std::size_t { + return (m_size + 7) & (~7); } - auto full_size() const noexcept -> std::size_t { return (m_size + 7) & (~7); } - - auto information_id() const noexcept -> impl::information_id const & { return m_id; } + auto information_id() const noexcept -> impl::information_id const & + { + return m_id; + } auto next() const noexcept -> tag_header const * { return std::bit_cast(std::bit_cast(this) + full_size()); } - auto unaligned_size() const noexcept -> std::uint32_t { return m_size; } + auto unaligned_size() const noexcept -> std::uint32_t + { + return m_size; + } protected: impl::information_id const m_id; @@ -51,22 +58,19 @@ namespace multiboot2::impl tag() : tag_header{} , Data{} - { - } + {} explicit tag(tag_header const * header) requires(sizeof(tag) > sizeof(tag_header)) : tag_header{header} , Data{*std::bit_cast(header + 1)} - { - } + {} explicit tag(tag_header const * header) requires(sizeof(tag) == sizeof(tag_header)) : tag_header{header} , Data{} - { - } + {} }; /** @@ -80,14 +84,12 @@ namespace multiboot2::impl vla_tag() : tag{} , m_vla{} - { - } + {} explicit vla_tag(tag_header const * header) : tag{header} , m_vla{vla_start(header), vla_size(header)} - { - } + {} protected: auto static vla_start(tag_header const * header) noexcept -> VlaData * diff --git a/libs/multiboot2/include/multiboot2/information.hpp b/libs/multiboot2/include/multiboot2/information.hpp index 04ba183..ac03069 100644 --- a/libs/multiboot2/include/multiboot2/information.hpp +++ b/libs/multiboot2/include/multiboot2/information.hpp @@ -41,7 +41,10 @@ namespace multiboot2 /** * @brief The command line string */ - auto string() const noexcept -> range_type { return m_vla; } + auto string() const noexcept -> range_type + { + return m_vla; + } }; /** @@ -53,7 +56,10 @@ namespace multiboot2 using iterator = range_type::iterator; - auto data() const noexcept -> range_type { return m_vla; } + auto data() const noexcept -> range_type + { + return m_vla; + } }; /** @@ -66,7 +72,10 @@ namespace multiboot2 /** * @brief The name of the bootloader */ - auto string() const noexcept -> std::string_view { return m_vla; } + auto string() const noexcept -> std::string_view + { + return m_vla; + } }; /** @@ -78,14 +87,23 @@ namespace multiboot2 using iterator = range_type::iterator; - auto begin() const noexcept -> iterator { return regions().begin(); } + auto begin() const noexcept -> iterator + { + return regions().begin(); + } - auto end() const noexcept -> iterator { return regions().end(); } + auto end() const noexcept -> iterator + { + return regions().end(); + } /** * @brief The available memory regions */ - auto regions() const noexcept -> range_type { return m_vla; } + auto regions() const noexcept -> range_type + { + return m_vla; + } }; struct information_view @@ -95,13 +113,22 @@ namespace multiboot2 using pointer = impl::information_iterator::pointer; using reference = impl::information_iterator::reference; - auto size_bytes() const noexcept -> std::size_t { return m_size; } + auto size_bytes() const noexcept -> std::size_t + { + return m_size; + } // Range access - auto begin() const noexcept -> iterator { return iterator{&m_tags}; } + auto begin() const noexcept -> iterator + { + return iterator{&m_tags}; + } - auto end() const noexcept -> iterator { return iterator{}; } + auto end() const noexcept -> iterator + { + return iterator{}; + } // Tag access @@ -111,36 +138,69 @@ namespace multiboot2 return get().has_value(); } - auto maybe_basic_memory() const noexcept -> std::optional { return get(); } + auto maybe_basic_memory() const noexcept -> std::optional + { + return get(); + } - auto basic_memory() const -> basic_memory { return maybe_basic_memory().value(); } + auto basic_memory() const -> basic_memory + { + return maybe_basic_memory().value(); + } auto maybe_bios_boot_device() const noexcept -> std::optional { return get(); } - auto bios_boot_device() const -> bios_boot_device { return maybe_bios_boot_device().value(); } + auto bios_boot_device() const -> bios_boot_device + { + return maybe_bios_boot_device().value(); + } - auto maybe_command_line() const noexcept -> std::optional { return get(); } + auto maybe_command_line() const noexcept -> std::optional + { + return get(); + } - auto command_line() const -> command_line { return maybe_command_line().value(); } + auto command_line() const -> command_line + { + return maybe_command_line().value(); + } - auto maybe_elf_symbols() const noexcept -> std::optional { return get(); } + auto maybe_elf_symbols() const noexcept -> std::optional + { + return get(); + } - auto elf_symbols() const -> elf_symbols { return maybe_elf_symbols().value(); } + auto elf_symbols() const -> elf_symbols + { + return maybe_elf_symbols().value(); + } - auto maybe_loader_name() const noexcept -> std::optional { return get(); } + auto maybe_loader_name() const noexcept -> std::optional + { + return get(); + } - auto loader_name() const -> loader_name { return maybe_loader_name().value(); } + auto loader_name() const -> loader_name + { + return maybe_loader_name().value(); + } - auto maybe_memory_map() const noexcept -> std::optional { return get(); } + auto maybe_memory_map() const noexcept -> std::optional + { + return get(); + } - auto memory_map() const -> memory_map { return maybe_memory_map().value(); } + auto memory_map() const -> memory_map + { + return maybe_memory_map().value(); + } private: template - auto constexpr get() const noexcept -> std::optional + constexpr auto get() const noexcept -> std::optional { if (auto found = std::ranges::find_if(*this, [](auto tag) { return tag.information_id() == Tag::id; }); found != end()) -- cgit v1.2.3 From 78f0df1cf849af8b0ade40a8ebcffd7fb53635cb Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 30 Oct 2025 15:59:48 +0100 Subject: libs: begin ELF support implementation --- libs/multiboot2/CMakeLists.txt | 8 +++++++ libs/multiboot2/include/multiboot2/information.hpp | 25 ++++++++++++++-------- 2 files changed, 24 insertions(+), 9 deletions(-) (limited to 'libs/multiboot2') diff --git a/libs/multiboot2/CMakeLists.txt b/libs/multiboot2/CMakeLists.txt index 7b9e58a..350a996 100644 --- a/libs/multiboot2/CMakeLists.txt +++ b/libs/multiboot2/CMakeLists.txt @@ -17,3 +17,11 @@ target_sources("multiboot2" INTERFACE target_include_directories("multiboot2" INTERFACE "include" ) + +target_link_libraries("multiboot2" INTERFACE + "libs::elf" +) + +set_target_properties("multiboot2" PROPERTIES + VERIFY_INTERFACE_HEADER_SETS YES +) \ No newline at end of file diff --git a/libs/multiboot2/include/multiboot2/information.hpp b/libs/multiboot2/include/multiboot2/information.hpp index ac03069..d2b4c98 100644 --- a/libs/multiboot2/include/multiboot2/information.hpp +++ b/libs/multiboot2/include/multiboot2/information.hpp @@ -5,6 +5,9 @@ #include "impl/iterator.hpp" #include "impl/tag.hpp" +#include +#include + #include #include #include @@ -50,15 +53,17 @@ namespace multiboot2 /** * @copydoc multiboot2::impl::elf_symbols_data */ - struct elf_symbols : impl::vla_tag + template + struct elf_symbols : impl::vla_tag const, std::span> { - using vla_tag::vla_tag; + using base = impl::vla_tag const, std::span>; + using base::base; - using iterator = range_type::iterator; + using iterator = base::range_type::iterator; - auto data() const noexcept -> range_type + auto data() const noexcept -> base::range_type { - return m_vla; + return this->m_vla; } }; @@ -168,14 +173,16 @@ namespace multiboot2 return maybe_command_line().value(); } - auto maybe_elf_symbols() const noexcept -> std::optional + template + auto maybe_elf_symbols() const noexcept -> std::optional> { - return get(); + return get>(); } - auto elf_symbols() const -> elf_symbols + template + auto elf_symbols() const -> elf_symbols { - return maybe_elf_symbols().value(); + return maybe_elf_symbols().value(); } auto maybe_loader_name() const noexcept -> std::optional -- cgit v1.2.3 From 31c5f011b2c7b4cc65d4017d92c2fe0bdf7f4ba6 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 31 Oct 2025 11:16:12 +0100 Subject: libs/elf: implement section headers --- libs/multiboot2/include/multiboot2/information.hpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'libs/multiboot2') diff --git a/libs/multiboot2/include/multiboot2/information.hpp b/libs/multiboot2/include/multiboot2/information.hpp index d2b4c98..462528d 100644 --- a/libs/multiboot2/include/multiboot2/information.hpp +++ b/libs/multiboot2/include/multiboot2/information.hpp @@ -176,7 +176,17 @@ namespace multiboot2 template auto maybe_elf_symbols() const noexcept -> std::optional> { - return get>(); + return get>().and_then( + [](auto x) -> std::optional> { + if (x.entry_size == elf::section_header_size) + { + return std::optional{x}; + } + else + { + return std::nullopt; + } + }); } template -- cgit v1.2.3 From c01073b04a6dcdf067342cf17fe5363a66d85eed Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 5 Dec 2025 14:48:31 +0100 Subject: multiboot2: add range support to VLA tags --- libs/multiboot2/include/multiboot2/impl/tag.hpp | 85 +++++++++++++++++++++- libs/multiboot2/include/multiboot2/information.hpp | 25 +------ 2 files changed, 84 insertions(+), 26 deletions(-) (limited to 'libs/multiboot2') diff --git a/libs/multiboot2/include/multiboot2/impl/tag.hpp b/libs/multiboot2/include/multiboot2/impl/tag.hpp index f151b54..5edcd6f 100644 --- a/libs/multiboot2/include/multiboot2/impl/tag.hpp +++ b/libs/multiboot2/include/multiboot2/impl/tag.hpp @@ -5,6 +5,7 @@ #include #include +#include #include namespace multiboot2::impl @@ -79,7 +80,18 @@ namespace multiboot2::impl template typename Range> struct vla_tag : tag { - using range_type = Range; + using range_type = Range; + + using iterator = range_type::const_iterator; + using const_iterator = range_type::const_iterator; + using reverse_iterator = range_type::const_reverse_iterator; + using const_reverse_iterator = range_type::const_reverse_iterator; + using size_type = range_type::size_type; + using difference_type = range_type::difference_type; + using reference = range_type::const_reference; + using const_reference = range_type::const_reference; + using pointer = range_type::const_pointer; + using const_pointer = range_type::const_pointer; vla_tag() : tag{} @@ -91,10 +103,75 @@ namespace multiboot2::impl , m_vla{vla_start(header), vla_size(header)} {} - protected: + [[nodiscard]] auto begin() const noexcept -> const_iterator + { + return m_vla.begin(); + } + + [[nodiscard]] auto end() const noexcept -> const_iterator + { + return m_vla.end(); + } + + [[nodiscard]] auto cbegin() const noexcept -> const_iterator + { + return begin(); + } + + [[nodiscard]] auto cend() const noexcept -> const_iterator + { + return end(); + } + + [[nodiscard]] auto rbegin() const noexcept -> const_reverse_iterator + { + return m_vla.rbegin(); + } + + [[nodiscard]] auto rend() const noexcept -> const_reverse_iterator + { + return m_vla.rend(); + } + + [[nodiscard]] auto crbegin() const noexcept -> const_reverse_iterator + { + return rbegin(); + } + + [[nodiscard]] auto crend() const noexcept -> const_reverse_iterator + { + return rend(); + } + + [[nodiscard]] auto front() const noexcept -> const_reference + { + return m_vla.front(); + } + + [[nodiscard]] auto back() const noexcept -> const_reference + { + return m_vla.back(); + } + + [[nodiscard]] auto size() const noexcept -> std::size_t + { + return m_vla.size(); + } + + [[nodiscard]] auto empty() const noexcept -> bool + { + return m_vla.empty(); + } + + [[nodiscard]] auto data() const noexcept -> const_pointer + { + return m_vla.data(); + } + + private: auto static vla_start(tag_header const * header) noexcept -> VlaData * { - auto raw = std::bit_cast(header); + auto raw = std::bit_cast(header); auto start = raw + sizeof(tag); return std::bit_cast(start); } @@ -107,7 +184,7 @@ namespace multiboot2::impl return size; } - range_type const m_vla; + range_type m_vla; }; } // namespace multiboot2::impl diff --git a/libs/multiboot2/include/multiboot2/information.hpp b/libs/multiboot2/include/multiboot2/information.hpp index 462528d..4be32aa 100644 --- a/libs/multiboot2/include/multiboot2/information.hpp +++ b/libs/multiboot2/include/multiboot2/information.hpp @@ -46,7 +46,7 @@ namespace multiboot2 */ auto string() const noexcept -> range_type { - return m_vla; + return {data(), size()}; } }; @@ -58,13 +58,6 @@ namespace multiboot2 { using base = impl::vla_tag const, std::span>; using base::base; - - using iterator = base::range_type::iterator; - - auto data() const noexcept -> base::range_type - { - return this->m_vla; - } }; /** @@ -79,7 +72,7 @@ namespace multiboot2 */ auto string() const noexcept -> std::string_view { - return m_vla; + return {data(), size()}; } }; @@ -90,24 +83,12 @@ namespace multiboot2 { using vla_tag::vla_tag; - using iterator = range_type::iterator; - - auto begin() const noexcept -> iterator - { - return regions().begin(); - } - - auto end() const noexcept -> iterator - { - return regions().end(); - } - /** * @brief The available memory regions */ auto regions() const noexcept -> range_type { - return m_vla; + return {data(), size()}; } }; -- cgit v1.2.3 From 1124eb4e0a88e7cd13d6ebd9820d6ddcde343110 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 5 Dec 2025 18:22:53 +0100 Subject: multiboot2: implement section name reading --- libs/multiboot2/include/multiboot2/impl/tag.hpp | 20 ++++++++++++++++---- libs/multiboot2/include/multiboot2/information.hpp | 14 ++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) (limited to 'libs/multiboot2') diff --git a/libs/multiboot2/include/multiboot2/impl/tag.hpp b/libs/multiboot2/include/multiboot2/impl/tag.hpp index 5edcd6f..a6e2678 100644 --- a/libs/multiboot2/include/multiboot2/impl/tag.hpp +++ b/libs/multiboot2/include/multiboot2/impl/tag.hpp @@ -82,16 +82,18 @@ namespace multiboot2::impl { using range_type = Range; + using value_type = range_type::value_type; + using reference = range_type::const_reference; + using const_reference = range_type::const_reference; + using pointer = range_type::const_pointer; + using const_pointer = range_type::const_pointer; + using iterator = range_type::const_iterator; using const_iterator = range_type::const_iterator; using reverse_iterator = range_type::const_reverse_iterator; using const_reverse_iterator = range_type::const_reverse_iterator; using size_type = range_type::size_type; using difference_type = range_type::difference_type; - using reference = range_type::const_reference; - using const_reference = range_type::const_reference; - using pointer = range_type::const_pointer; - using const_pointer = range_type::const_pointer; vla_tag() : tag{} @@ -168,6 +170,16 @@ namespace multiboot2::impl return m_vla.data(); } + [[nodiscard]] auto at() const -> const_reference + { + return m_vla.at(); + } + + [[nodiscard]] auto operator[](std::size_t index) const noexcept -> const_reference + { + return m_vla[index]; + } + private: auto static vla_start(tag_header const * header) noexcept -> VlaData * { diff --git a/libs/multiboot2/include/multiboot2/information.hpp b/libs/multiboot2/include/multiboot2/information.hpp index 4be32aa..25f034d 100644 --- a/libs/multiboot2/include/multiboot2/information.hpp +++ b/libs/multiboot2/include/multiboot2/information.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,19 @@ namespace multiboot2 { using base = impl::vla_tag const, std::span>; using base::base; + + [[nodiscard]] auto name(elf::section_header const & section) const noexcept -> std::string_view + { + if (!this->string_table_index) + { + std::abort(); + } + + auto string_table = this->begin()[this->string_table_index]; + auto name_offset = section.name_offset; + auto name_array = std::bit_cast(string_table.virtual_load_address); + return name_array + name_offset; + } }; /** -- cgit v1.2.3 From 178d566278f580ed5625d2d34831b4d263ee09af Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 5 Dec 2025 18:33:01 +0100 Subject: multiboot2: silence some warnings --- libs/multiboot2/include/multiboot2/impl/data.hpp | 12 +++--- libs/multiboot2/include/multiboot2/impl/ids.hpp | 8 ++-- .../include/multiboot2/impl/iterator.hpp | 2 + libs/multiboot2/include/multiboot2/impl/tag.hpp | 21 ++++++----- libs/multiboot2/include/multiboot2/information.hpp | 44 +++++++++++----------- 5 files changed, 48 insertions(+), 39 deletions(-) (limited to 'libs/multiboot2') diff --git a/libs/multiboot2/include/multiboot2/impl/data.hpp b/libs/multiboot2/include/multiboot2/impl/data.hpp index 3cda162..733ce3a 100644 --- a/libs/multiboot2/include/multiboot2/impl/data.hpp +++ b/libs/multiboot2/include/multiboot2/impl/data.hpp @@ -1,6 +1,8 @@ #ifndef MULTIBOOT2_IMPL_DATA_HPP #define MULTIBOOT2_IMPL_DATA_HPP +// IWYU pragma: private + #include "multiboot2/impl/ids.hpp" #include @@ -23,14 +25,14 @@ namespace multiboot2::impl * * The maximum possible value for this field is 640 KiB. */ - std::uint32_t const lower_KiB; + std::uint32_t lower_KiB; /** * @brief Amount of upper memory (above 1MiB) available to the system. * * The maximum possible value for this field is the address of the first upper memory hole minus 1MiB. */ - std::uint32_t const upper_KiB; + std::uint32_t upper_KiB; }; /** @@ -94,7 +96,7 @@ namespace multiboot2::impl /** * @brief Check if the memory described by this region is available for use. */ - constexpr auto available() const noexcept + [[nodiscard]] constexpr auto available() const noexcept { return type == memory_type::AVAILABLE; } @@ -120,12 +122,12 @@ namespace multiboot2::impl /** * @brief Size of each entry present in the map */ - std::uint32_t const entry_size; + std::uint32_t entry_size; /** * @brief Version of each entry present in the map */ - std::uint32_t const entry_version; + std::uint32_t entry_version; }; } // namespace multiboot2::impl diff --git a/libs/multiboot2/include/multiboot2/impl/ids.hpp b/libs/multiboot2/include/multiboot2/impl/ids.hpp index 3a7215e..98bc1f2 100644 --- a/libs/multiboot2/include/multiboot2/impl/ids.hpp +++ b/libs/multiboot2/include/multiboot2/impl/ids.hpp @@ -1,6 +1,8 @@ #ifndef MULTIBOOT2_IMPL_IDS_HPP #define MULTIBOOT2_IMPL_IDS_HPP +// IWYU pragma: private + #include namespace multiboot2::impl @@ -24,14 +26,14 @@ namespace multiboot2::impl APM_INFO, ///< Advanced Power Management information. EFI32, ///< EFI 32 bit system table pointer. EFI64, ///< EFI 64 bit system table pointer. - SMBIOS, ///< Contains copy of all Sytem Management BIOS tables. + SMBIOS, ///< Contains copy of all System Management BIOS tables. ACPI_OLD, ///< Contains copy of RSDP as defined per ACPI1.0 specification. ACPI_NEW, ///< Contains copy of RSDP as defined per ACPI2.0 or later specification. NETWORK, ///< Contains network information specified specified as DHCP. EFI_MEMORY_MAP, ///< Contains EFI memory map. - EFI_BS_NOT_TERMINATED, ///< Indicated ExitBootServies wasn't called. + EFI_BS_NOT_TERMINATED, ///< Indicates ExitBootServices wasn't called. EFI32_IMAGE_HANDLE, ///< EFI 32 bit image handle pointer. - EFI64_IMAGE_HANDLE, ///< EFI 64 bit imae handle pointer. + EFI64_IMAGE_HANDLE, ///< EFI 64 bit image handle pointer. LOAD_BASE_ADDRESS ///< Contains image load base physical address. }; diff --git a/libs/multiboot2/include/multiboot2/impl/iterator.hpp b/libs/multiboot2/include/multiboot2/impl/iterator.hpp index f8955cb..5651f22 100644 --- a/libs/multiboot2/include/multiboot2/impl/iterator.hpp +++ b/libs/multiboot2/include/multiboot2/impl/iterator.hpp @@ -1,6 +1,8 @@ #ifndef MULTIBOOT2_IMPL_INFORMATION_ITERATOR_HPP #define MULTIBOOT2_IMPL_INFORMATION_ITERATOR_HPP +// IWYU pragma: private + #include "multiboot2/impl/ids.hpp" #include "multiboot2/impl/tag.hpp" diff --git a/libs/multiboot2/include/multiboot2/impl/tag.hpp b/libs/multiboot2/include/multiboot2/impl/tag.hpp index a6e2678..3d0cea5 100644 --- a/libs/multiboot2/include/multiboot2/impl/tag.hpp +++ b/libs/multiboot2/include/multiboot2/impl/tag.hpp @@ -1,6 +1,8 @@ #ifndef MULTIBOOT2_IMPL_TAG_HPP #define MULTIBOOT2_IMPL_TAG_HPP +// IWYU pragma: private + #include "multiboot2/impl/ids.hpp" #include @@ -25,29 +27,30 @@ namespace multiboot2::impl : tag_header{*data} {} - auto full_size() const noexcept -> std::size_t + [[nodiscard]] auto full_size() const noexcept -> std::size_t { + // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers) return (m_size + 7) & (~7); } - auto information_id() const noexcept -> impl::information_id const & + [[nodiscard]] auto information_id() const noexcept -> impl::information_id const & { return m_id; } - auto next() const noexcept -> tag_header const * + [[nodiscard]] auto next() const noexcept -> tag_header const * { - return std::bit_cast(std::bit_cast(this) + full_size()); + return std::bit_cast(std::bit_cast(this) + full_size()); } - auto unaligned_size() const noexcept -> std::uint32_t + [[nodiscard]] auto unaligned_size() const noexcept -> std::uint32_t { return m_size; } - protected: - impl::information_id const m_id; - std::uint32_t const m_size; + private: + impl::information_id m_id; + std::uint32_t m_size; }; /** @@ -64,7 +67,7 @@ namespace multiboot2::impl explicit tag(tag_header const * header) requires(sizeof(tag) > sizeof(tag_header)) : tag_header{header} - , Data{*std::bit_cast(header + 1)} + , Data{*std::bit_cast(header + 1)} // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) {} explicit tag(tag_header const * header) diff --git a/libs/multiboot2/include/multiboot2/information.hpp b/libs/multiboot2/include/multiboot2/information.hpp index 25f034d..2d60a6d 100644 --- a/libs/multiboot2/include/multiboot2/information.hpp +++ b/libs/multiboot2/include/multiboot2/information.hpp @@ -45,7 +45,7 @@ namespace multiboot2 /** * @brief The command line string */ - auto string() const noexcept -> range_type + [[nodiscard]] auto string() const noexcept -> range_type { return {data(), size()}; } @@ -84,7 +84,7 @@ namespace multiboot2 /** * @brief The name of the bootloader */ - auto string() const noexcept -> std::string_view + [[nodiscard]] auto string() const noexcept -> std::string_view { return {data(), size()}; } @@ -100,7 +100,7 @@ namespace multiboot2 /** * @brief The available memory regions */ - auto regions() const noexcept -> range_type + [[nodiscard]] auto regions() const noexcept -> range_type { return {data(), size()}; } @@ -113,19 +113,19 @@ namespace multiboot2 using pointer = impl::information_iterator::pointer; using reference = impl::information_iterator::reference; - auto size_bytes() const noexcept -> std::size_t + [[nodiscard]] auto size_bytes() const noexcept -> std::size_t { return m_size; } // Range access - auto begin() const noexcept -> iterator + [[nodiscard]] auto begin() const noexcept -> iterator { return iterator{&m_tags}; } - auto end() const noexcept -> iterator + [[nodiscard]] auto end() const noexcept -> iterator { return iterator{}; } @@ -133,43 +133,43 @@ namespace multiboot2 // Tag access template - auto has() const noexcept -> bool + [[nodiscard]] auto has() const noexcept -> bool { return get().has_value(); } - auto maybe_basic_memory() const noexcept -> std::optional + [[nodiscard]] auto maybe_basic_memory() const noexcept -> std::optional { return get(); } - auto basic_memory() const -> basic_memory + [[nodiscard]] auto basic_memory() const -> basic_memory { return maybe_basic_memory().value(); } - auto maybe_bios_boot_device() const noexcept -> std::optional + [[nodiscard]] auto maybe_bios_boot_device() const noexcept -> std::optional { return get(); } - auto bios_boot_device() const -> bios_boot_device + [[nodiscard]] auto bios_boot_device() const -> bios_boot_device { return maybe_bios_boot_device().value(); } - auto maybe_command_line() const noexcept -> std::optional + [[nodiscard]] auto maybe_command_line() const noexcept -> std::optional { return get(); } - auto command_line() const -> command_line + [[nodiscard]] auto command_line() const -> command_line { return maybe_command_line().value(); } template - auto maybe_elf_symbols() const noexcept -> std::optional> + [[nodiscard]] auto maybe_elf_symbols() const noexcept -> std::optional> { return get>().and_then( [](auto x) -> std::optional> { @@ -185,34 +185,34 @@ namespace multiboot2 } template - auto elf_symbols() const -> elf_symbols + [[nodiscard]] auto elf_symbols() const -> elf_symbols { return maybe_elf_symbols().value(); } - auto maybe_loader_name() const noexcept -> std::optional + [[nodiscard]] auto maybe_loader_name() const noexcept -> std::optional { return get(); } - auto loader_name() const -> loader_name + [[nodiscard]] auto loader_name() const -> loader_name { return maybe_loader_name().value(); } - auto maybe_memory_map() const noexcept -> std::optional + [[nodiscard]] auto maybe_memory_map() const noexcept -> std::optional { return get(); } - auto memory_map() const -> memory_map + [[nodiscard]] auto memory_map() const -> memory_map { return maybe_memory_map().value(); } private: template - constexpr auto get() const noexcept -> std::optional + [[nodiscard]] constexpr auto get() const noexcept -> std::optional { if (auto found = std::ranges::find_if(*this, [](auto tag) { return tag.information_id() == Tag::id; }); found != end()) @@ -222,9 +222,9 @@ namespace multiboot2 return std::nullopt; } - [[maybe_unused]] uint32_t const m_size{}; + uint32_t m_size{}; uint32_t : 32; - impl::tag_header const m_tags{}; + impl::tag_header m_tags{}; }; } // namespace multiboot2 -- cgit v1.2.3