diff options
| -rw-r--r-- | arch/x86_64/include/arch/io/port_io.hpp | 1 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/memory/frame_allocator.hpp | 86 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/memory/multiboot.hpp | 345 | ||||
| -rw-r--r-- | arch/x86_64/src/kernel/main.cpp | 3 | ||||
| -rw-r--r-- | arch/x86_64/src/memory/multiboot.cpp | 41 |
5 files changed, 331 insertions, 145 deletions
diff --git a/arch/x86_64/include/arch/io/port_io.hpp b/arch/x86_64/include/arch/io/port_io.hpp index c0f1ef3..1945261 100644 --- a/arch/x86_64/include/arch/io/port_io.hpp +++ b/arch/x86_64/include/arch/io/port_io.hpp @@ -8,7 +8,6 @@ namespace teachos::arch::io { - /** * @brief An I/O port of a given size at a given address. * diff --git a/arch/x86_64/include/arch/memory/frame_allocator.hpp b/arch/x86_64/include/arch/memory/frame_allocator.hpp index 35d7360..3989cdf 100644 --- a/arch/x86_64/include/arch/memory/frame_allocator.hpp +++ b/arch/x86_64/include/arch/memory/frame_allocator.hpp @@ -4,6 +4,7 @@ #include "multiboot.hpp" #include <cstddef> #include <optional> +#include <type_traits> namespace teachos::arch::memory { @@ -12,51 +13,74 @@ namespace teachos::arch::memory const std::size_t PAGE_FRAME_SIZE = 4096U; } + /** + * @brief Specific frame containing helper functions to determine if a specific address is in that frame or not + */ struct frame { - std::size_t frame_number; + std::size_t frame_number; ///< Index number of the current frame, used to distinguish it from other frames + /** + * @brief Constructor + * + * @param frame_number Index number that should be assigned to this frame + */ frame(std::size_t frame_number) : frame_number(frame_number) { // Nothing to do } + /** + * @brief Returns the frame the given address is contained in + * + * @param address Address we want to get the corresponding frame for + * @return Frame the given address is contained in + */ static auto containing_address(std::size_t address) -> frame { return frame{address / PAGE_FRAME_SIZE}; } - constexpr bool operator==(const frame & other) const noexcept { return frame_number == other.frame_number; } - constexpr bool operator>(const frame & other) const noexcept { return frame_number > other.frame_number; } - constexpr bool operator<(const frame & other) const noexcept { return frame_number < other.frame_number; } - constexpr bool operator>=(const frame & other) const noexcept { return frame_number >= other.frame_number; } - constexpr bool operator<=(const frame & other) const noexcept { return frame_number <= other.frame_number; } - }; + /** + * @brief Defaulted equals operator + */ + constexpr auto operator==(const frame & other) const -> bool = default; - struct frame_allocator - { - virtual auto allocate_frame() -> std::optional<frame> = 0; - virtual auto deallocate_frame(frame frame) -> void = 0; + /** + * @brief Defaulted three-way comparsion operator + */ + constexpr auto operator<=>(const frame & other) const -> std::partial_ordering = default; }; - // TODO: FIX CONCEPT USAGE - // template<typename T> - // concept FrameAllocator = requires(T t) { - // { t.allocate_frame() } -> std::optional<frame>; - // { t.deallocate_frame() } -> void; - // }; + template<typename T> + concept FrameAllocator = requires(T t) { + { t.allocate_frame() } -> std::optional<frame>; + { t.deallocate_frame() } -> void; + }; - // template<FrameAllocator T> - struct area_frame_allocator : frame_allocator + /** + * @brief Allocates memory using memory areas read from the multiboot2 information pointer + * + */ + struct area_frame_allocator { - frame next_free_frame{0}; //!< The frame after the last allocated one - std::optional<arch::memory::memory_area> current_area{std::nullopt}; //!< The current memory area - arch::memory::memory_area * areas; //!< A list of all memory areas - frame kernel_start; //!< The start address of the kernel code in memory - frame kernel_end; //!< The end address of the kernel code in memory - frame multiboot_start; //!< The start address of the multiboot code in memory - frame multiboot_end; //!< The end address of the multiboot code in memory + frame next_free_frame{0}; //!< The frame after the last allocated one + std::optional<memory_area> current_area{std::nullopt}; //!< The current memory area + memory_area * areas; //!< Pointer to the first element of all memory areas + frame kernel_start; //!< The start address of the kernel code in memory + frame kernel_end; //!< The end address of the kernel code in memory + frame multiboot_start; //!< The start address of the multiboot code in memory + frame multiboot_end; //!< The end address of the multiboot code in memory + /** + * @brief Constructor + * + * @param kernel_start Start address of the kernel code in memory + * @param kernel_end End address of the kernel code in memory + * @param multiboot_start Start address of the multiboot code in memory + * @param multiboot_end End address of the multiboot code in memory + * @param memory_areas Pointer to the first element of all memory areas + */ area_frame_allocator(std::size_t kernel_start, std::size_t kernel_end, std::size_t multiboot_start, - std::size_t multiboot_end, arch::memory::memory_area * memory_areas) + std::size_t multiboot_end, memory_area * memory_areas) : kernel_start(frame{kernel_start}) , kernel_end(frame{kernel_end}) , multiboot_start(frame{multiboot_start}) @@ -67,7 +91,7 @@ namespace teachos::arch::memory } /** - * @brief Allocate memory be finding and returning a free frame + * @brief Allocate memory by finding and returning a free frame * * The frame allocation executes multiple checks before returning * the frame that is available to allocate. It must at least @@ -77,6 +101,12 @@ namespace teachos::arch::memory * - update the next_free_frame after finding a free frame */ auto allocate_frame() -> std::optional<frame>; + + /** + * @brief Deallocates a previously allocated frame + * + * @param frame Previously allocated frame that should be allocated + */ auto deallocate_frame(frame frame) -> void; private: diff --git a/arch/x86_64/include/arch/memory/multiboot.hpp b/arch/x86_64/include/arch/memory/multiboot.hpp index f6ff480..5990260 100644 --- a/arch/x86_64/include/arch/memory/multiboot.hpp +++ b/arch/x86_64/include/arch/memory/multiboot.hpp @@ -6,154 +6,264 @@ namespace teachos::arch::memory { - /* - * Define all multiboot tag types to ther respective values - * The gnu boot information format is defined here: - * https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html#Boot-information-format + /** + * @brief Defines all possible types a multiboot2 tag structure can have. + * See + * https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html#Boot-information-format for more information. */ enum class multi_boot_tag_type : uint32_t { - END, - CMDLINE, - BOOT_LOADER_NAME, - MODULE, - BASIC_MEMORY_INFO, - BOOTDEV, - MEMORY_MAP, - VBE, - FRAMEBUFFER, - ELF_SECTIONS, - APM, - EFI32, - EFI64, - SMBIOS, - ACPI_OLD, - ACPI_NEW, - NETWORK, - EFI_MEMORY_MAP, - EFI_BS, - EFI32_IH, - EFI64_IH, - LOAD_BASE_ADDRESS + 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 Basic structure that every entry in the multi_boot_tag array of the multi_boot_info struct has to begin + * with. + */ struct multi_boot_tag { - multi_boot_tag_type type; - uint32_t size; + multi_boot_tag_type type; ///< Specific type of this multi_boot_tag entry, used to differentiate handling + uint32_t size; ///< Total size of this multi_boot_tag entry with all fields of the actual type }; + /** + * @brief Basic structure the multiboot_information_pointer points too and which contains all information of + * multiboot2 in the tags array of different types. + */ struct multi_boot_info { - uint32_t total_size; - /* - * field "tags" is an array of multi_boot_tag, however the array is never - * being accessed by index we don't know the real size at compile-time, - * and using an array definition with size 0 produces a compiler error. - */ - alignas(8) struct multi_boot_tag tags; + uint32_t total_size; ///< Total size of all multi_boot_tags and their data + alignas(8) struct multi_boot_tag tags; ///< Specific tags }; + /** + * @brief Defines an entry in the multi_boot_tag array of the multi_boot_info struct, of type + * multi_boot_tag_type::BASIC_MEMORY_INFO. + */ struct memory_info { - multi_boot_tag tag; - uint32_t mem_lower; - uint32_t mem_upper; + multi_boot_tag tag; ///< Basic multi_boot_tag information + uint32_t mem_lower; ///< Amount of lower memory (0MB start address) + uint32_t mem_upper; ///< Amount of upper memory (1MB start address) }; + /** + * @brief Defines all memory area types possible that the memory region can be in. + */ enum class memory_area_type : uint32_t { - AVAILABLE = 1, - RESERVED, - ACPI_AVAILABLE, - RESERVED_HIBERNATION, - DEFECTIVE + AVAILABLE = 1, ///< Region is available for use by the OS + RESERVED, ///< Region is reserved by firmware or bootloader and should not be used by OS + ACPI_AVAILABLE, ///< Region is reclaimable by OS after ACPI event + RESERVED_HIBERNATION, ///< Region is used for Non-volatile Storage (NVS) + DEFECTIVE ///< Region is defective or unusable }; + /** + * @brief Defines an entry in the entries array of the memory_map struct. + */ struct memory_area { - uint64_t base_address; - uint64_t area_length; - alignas(8) memory_area_type type; + uint64_t base_address; ///< Base address the memory region starts at + uint64_t area_length; ///< Size of the memory region, added to base_address results in the final address + alignas(8) memory_area_type type; ///< Specific type of memory the region can contain }; + /** + * @brief Defines an entry in the multi_boot_tag array of the multi_boot_info struct, of type + * multi_boot_tag_type::MEMORY_MAP. + */ struct memory_map { - multi_boot_tag tag; - uint32_t entry_size; - uint32_t entry_version; - /* - * field "entries" is an array of memory_area, however the array is never - * being accessed by index, we don't know the real size at compile-time, - * and using an array definition with size 0 produces a compiler error. - */ - struct memory_area entries; + multi_boot_tag tag; ///< Basic multi_boot_tag information + uint32_t entry_size; ///< Size of each entry in the memory_area array. Guaranteed multiple of 8 + uint32_t entry_version; ///< Version of the entries, currently 0 + struct memory_area entries; ///< Specific memory regions }; /** - * https://refspecs.linuxfoundation.org/LSB_2.1.0/LSB-Core-generic/LSB-Core-generic/elftypes.html + * @brief Defines all elf section types an elf section header can have. + * The first section will always be INACTIVE, there can only ever be one DYNAMIC section and only either one + * DYNAMIC_SYMBOL_TABLE or SYMBOL_TABLE. See https://docs.oracle.com/cd/E19683-01/816-1386/chapter6-94076/index.html + * for more information. */ enum class elf_section_type : uint32_t { - INACTIVE, - PROGRAMM, - SYMBOL_TABLE, - STRING_TABLE, - RELOCATION_ENTRY_WITH_EXPLICIT_ADDENDS, - SYMBOL_HASH_TABLE, - DYNAMIC, - NOTE, - EMPTY, - RELOCATION_ENTRY_WITHOUT_EXPLICIT_ADDENDS, - UNSPECIFIED, - DYNAMIC_SYMBOL, - INITALIZATION_FUNCTION_ARRAY = 14, - TERMINATION_FUNCTION_ARRAY, - PRE_INITALIZATION_FUNCTION_ARRAY + INACTIVE, ///< (SHT_NULL) Unused, meaning all values are zeroed out + PROGRAMM, ///< (SHT_PROGBITS) Program data + SYMBOL_TABLE, ///< (SHT_SYMBTAB) Contains actual entries pointed to in symbol hash table + STRING_TABLE, ///< (SHT_STRTAB) Contains symbols, section and deubbging null-terminated strings + RELOCATION_ENTRY_WITH_ADDENDS, ///< (SHT_RELA) Only used on 64 bit systems + SYMBOL_HASH_TABLE, ///< (SHT_HASH) Hash table used by dynamic linker to locate symbols + DYNAMIC, ///< (SHT_DYNAMIC) Contains dynamic linking information + NOTE, ///< (SHT_NOTE) Stores information that marks files in some way + EMPTY, ///< (SHT_NOBITS) Program data section, that occupies no space in the file (.bss) + RELOCATION_ENTRY_WITHOUT_ADDENDS, ///< (SHT_REL) Only used on 32 bit systems + UNSPECIFIED, ///< (SHT_SHLIB) Reserved but has unspecified semantics + DYNAMIC_SYMBOL_TABLE, ///< (SHT_DYNSYM) Holds minimal set of symbols adequate for dynamic linking + INITALIZATION_FUNCTION_ARRAY = 14, ///< (SHT_INIT_ARRAY) Array of pointers to intialization functions () -> void + TERMINATION_FUNCTION_ARRAY, ///< (SHT_FINI_ARRAY) Array of pointers to termination functions () -> void + PRE_INITALIZATION_FUNCTION_ARRAY ///< (SHT_PRE_INIT_ARRAY) Array of pointers to functions invoked before other + ///< initalization functions () -> void }; /** - * https://docs.oracle.com/cd/E19683-01/816-1386/chapter6-94076/index.html + * @brief Defines helper function for all states that the elf section flags of an elf section header can + * have. See https://docs.oracle.com/cd/E19683-01/816-1386/chapter6-94076/index.html + * See https://docs.oracle.com/cd/E19683-01/816-1386/chapter6-94076/index.html for more information. */ - class elf_section_flags + struct elf_section_flags { - public: - elf_section_flags(uint64_t flags) + /** + * @brief Constructor. + * + * @param flags Actual value read from the elf section header, which should be converted into a std::bitset, to + * allow reading the state of single bits more easily. + */ + explicit elf_section_flags(uint64_t flags) : flags(flags) { // Nothing to do } - auto writeable() const -> bool { return is_bit_set(0); } + /** + * @brief (SHF_WRITE) Wether the current section is writable or not. Read from bit index 0. + * + * @return Current section is writable. + */ + auto writeable() const -> bool; - auto occupies_memory() const -> bool { return is_bit_set(1); } + /** + * @brief (SHF_ALLOC) Whether the current section occupies memory during execution or not. Read from bit index 1. + * + * @return Current section occupies memory during execution. + */ + auto occupies_memory() const -> bool; - auto is_executable() const -> bool { return is_bit_set(2); } + /** + * @brief (SHF_EXECINSTR) Whether the current section is executable or not. Read from bit index 2. + * + * @return Current section is executable. + */ + auto is_executable() const -> bool; - auto contains_duplicate_data() const -> bool { return is_bit_set(4); } + /** + * @brief (SHF_MERGE) Whether the current section might be merged with another section or not. Read from bit + * index 4. + * + * @return Current section might be merged with another section + */ + auto contains_duplicate_data() const -> bool; - auto contains_strings() const -> bool { return is_bit_set(5); } + /** + * @brief (SHF_STRINGS) Whether the current section contains null-terminated strings or not. Read from bit + * index 5. + * + * @return Current section contains null-terminated strings + */ + auto contains_strings() const -> bool; - auto section_header_info_is_section_header_table_index() const -> bool { return is_bit_set(6); } + /** + * @brief (SHF_INFO_LINK) Whether the current section contains the section header table index in the (sh_info) + * additional_information variable or not. Read from bit index 6. + * + * @return Current section contains the section header table index in the (sh_info) + * additional_information variable + */ + auto section_header_info_is_section_header_table_index() const -> bool; - auto preserve_ordering_after_combination() const -> bool { return is_bit_set(7); } + /** + * @brief (SHF_LINK_ORDER) Whether the current section preserves order after combining with another section or not. + * Read from bit index 7. + * + * @return Current section preserves order after combining with another section + */ + auto preserve_ordering_after_combination() const -> bool; - auto requires_special_os_processing() const -> bool { return is_bit_set(8); } + /** + * @brief (SHF_OS_NONCONFORMING) Whether the current section requires non-standard OS specific handling of its code + * or data, which does not confirm to standard ELF specifications. Read from bit index 8. + * + * @return Current section requires non-standard OS specific handling + */ + auto requires_special_os_processing() const -> bool; - auto is_section_group_member() const -> bool { return is_bit_set(9); } + /** + * @brief (SHF_GROUP) Whether the current section is a member of a section group or not. Read from bit index 9. + * + * @return Current section is a member of a section group + */ + auto is_section_group_member() const -> bool; - auto holds_thread_local_data() const -> bool { return is_bit_set(10); } + /** + * @brief (SHF_TLS) Whether the current section holds thread-local data or not. Read from bit + * index 10. + * + * @return Current section holds thread-local data + */ + auto holds_thread_local_data() const -> bool; - auto is_compressed() const -> bool { return is_bit_set(11); } + /** + * @brief (SHF_COMPRESSED) Whether the current section contains compressed data or not. Read from bit + * index 11. + * + * @return Current section contains compressed data + */ + auto is_compressed() const -> bool; - auto has_special_ordering_requirements() const -> bool { return is_bit_set(30); } + /** + * @brief (SHF_ORDERED) Whether the current section has special ordering requirements, meaning it should be ordered + * in relation to other sections of the same type. Read from bit index 30. + * + * @return current section has special ordering requirements + */ + auto has_special_ordering_requirements() const -> bool; - auto is_excluded_unless_referenced_or_allocated() const -> bool { return is_bit_set(31); } + /** + * @brief (SHF_EXCLUDE) Whether the current section is excluded unless refereenced or allocated, used for LTO + * (Link-Time Optimizations). Read from bit index 31. + * + * @return Current section is excluded unless refereenced or allocated + */ + auto is_excluded_unless_referenced_or_allocated() const -> bool; - auto operator==(elf_section_flags const & other) const -> bool { return flags == other.flags; } + /** + * @brief Allows to compare the underlying std::bitset of two instances + * + * @param other Other instance that we want to compare with + * @return Whether the underlying std::bitset of both types is the same + */ + auto operator==(elf_section_flags const & other) const -> bool; private: - auto is_bit_set(uint8_t index) const -> bool { return flags[index] == 1; } + /** + * @brief Checks the underlying std::bitset if the bit at the specific index is set, meaning a value of 1 + * + * @param index Specific index we want to check at + * @return Bit value 1 is set and will return true + */ + auto is_bit_set(uint8_t index) const -> bool; std::bitset<64U> flags; }; @@ -164,41 +274,44 @@ namespace teachos::arch::memory */ struct elf_section_header { - uint32_t name_table_index; - elf_section_type type; - elf_section_flags flags; - uint64_t virtual_address; - uint64_t file_offset; - uint64_t section_size; - uint32_t other_section; - uint32_t additional_information; - uint64_t address_alignment; - uint64_t fixed_table_entry_size; - - /** - * @brief Detect whether e section header is inactive or not, should always be the case for the first entry in the + uint32_t name_table_index; ///< Index into the section header string table, specifies the name of the section + elf_section_type type; ///< Categorizes the sections content and semantics + elf_section_flags flags; ///< 1-bit flgas that describe section attributes + uint64_t virtual_address; ///< If section appears in memory image of a process, gives address at which the sections + ///< first byte should reside, otherwise 0 + uint64_t file_offset; ///< Offset from the beginning of the file to the first byte in the section. SHT_NOBITS + ///< contains the conceptual placement instead (because it occupies no space in the file) + uint64_t section_size; ///< Complete section size in bytes, SHT_NOBITS may have non-zero value but will always + ///< occupy no space in the file + uint32_t other_section; ///< Section header table index link, behaviour varies on type + ///< https://refspecs.linuxbase.org/elf/gabi4+/ch4.sheader.html#sh_link + uint32_t additional_information; ///< Extra information, behaviour varies on type + ///< https://refspecs.linuxbase.org/elf/gabi4+/ch4.sheader.html#sh_link + uint64_t address_alignment; ///< Possible address alignment constraints. Value of virutal_address must be 0 % value + ///< of address_alignment. Value 0 or 1 mean no alignment constraints + uint64_t fixed_table_entry_size; ///< If sections holds table with fixed-sized entries, this gives the size in + ///< bytes of each entry + + /** + * @brief Detect whether a section header is inactive or not, should always be the case for the first entry in the * sections table * @return Whether the current section header is actually null or not, requires all fields besides section_size and - * other_section to actually contain 0 + * other_section to contain 0 */ - auto is_null() const -> bool - { - return name_table_index == 0U && type == elf_section_type::UNSPECIFIED && flags == 0U && virtual_address == 0U && - file_offset == 0U && additional_information == 0U && address_alignment == 0U && - fixed_table_entry_size == 0U; - } + auto is_null() const -> bool; }; /** - * https://gist.github.com/x0nu11byt3/bcb35c3de461e5fb66173071a2379779 + * @brief Defines an entry in the multi_boot_tag array of the multi_boot_info struct, of type + * multi_boot_tag_type::ELF_SECTIONS. */ struct elf_symbols_section { - multi_boot_tag tag; - uint32_t number_of_sections; - uint32_t entry_size; - uint32_t section_index; - alignas(8) struct elf_section_header sections; + multi_boot_tag tag; ///< Basic multi_boot_tag information + uint32_t number_of_sections; ///< Number of sections in the sections array + uint32_t entry_size; ///< Size of each entry in the sections array + uint32_t section_index; ///< Index to the string table used for symbol names + alignas(8) struct elf_section_header sections; ///< Specific sectons }; } // namespace teachos::arch::memory diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index 2ba4fe2..6486b7c 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -63,6 +63,9 @@ namespace teachos::arch::kernel // value should be zero :( // assert(begin->is_null()); + // TODO: Check if only contains one DYNSYM or SYMTAB but not both! + // TODO: Check if only contains one dynamic section + for (auto section = begin; section != end; ++section) { video::vga::text::write("Looping Code section", video::vga::text::common_attributes::green_on_black); diff --git a/arch/x86_64/src/memory/multiboot.cpp b/arch/x86_64/src/memory/multiboot.cpp new file mode 100644 index 0000000..91e7550 --- /dev/null +++ b/arch/x86_64/src/memory/multiboot.cpp @@ -0,0 +1,41 @@ +#include "multiboot.hpp" + +namespace teachos::arch::memory +{ + auto elf_section_flags::writeable() const -> bool { return is_bit_set(0); } + + auto elf_section_flags::occupies_memory() const -> bool { return is_bit_set(1); } + + auto elf_section_flags::is_executable() const -> bool { return is_bit_set(2); } + + auto elf_section_flags::contains_duplicate_data() const -> bool { return is_bit_set(4); } + + auto elf_section_flags::contains_strings() const -> bool { return is_bit_set(5); } + + auto elf_section_flags::section_header_info_is_section_header_table_index() const -> bool { return is_bit_set(6); } + + auto elf_section_flags::preserve_ordering_after_combination() const -> bool { return is_bit_set(7); } + + auto elf_section_flags::requires_special_os_processing() const -> bool { return is_bit_set(8); } + + auto elf_section_flags::is_section_group_member() const -> bool { return is_bit_set(9); } + + auto elf_section_flags::holds_thread_local_data() const -> bool { return is_bit_set(10); } + + auto elf_section_flags::is_compressed() const -> bool { return is_bit_set(11); } + + auto elf_section_flags::has_special_ordering_requirements() const -> bool { return is_bit_set(30); } + + auto elf_section_flags::is_excluded_unless_referenced_or_allocated() const -> bool { return is_bit_set(31); } + + auto elf_section_flags::operator==(elf_section_flags const & other) const -> bool { return flags == other.flags; } + + auto elf_section_flags::is_bit_set(uint8_t index) const -> bool { return flags[index] == 1; } + + auto elf_section_header::is_null() const -> bool + { + return name_table_index == 0U && type == elf_section_type::UNSPECIFIED && + flags == teachos::arch::memory::elf_section_flags{0U} && virtual_address == 0U && file_offset == 0U && + additional_information == 0U && address_alignment == 0U && fixed_table_entry_size == 0U; + } +} // namespace teachos::arch::memory |
