diff options
| author | Matteo Gmür <matteo.gmuer1@ost.ch> | 2024-10-28 10:15:18 +0000 |
|---|---|---|
| committer | Matteo Gmür <matteo.gmuer1@ost.ch> | 2024-10-28 10:15:18 +0000 |
| commit | 04b0285d8329e45cea426aa1a8e69203685a4467 (patch) | |
| tree | 00c55d9dffddf3724da38b07427cf3460f883b1e /arch | |
| parent | 58d01f6aae80a66faa5163602c399c28dcf30cb6 (diff) | |
| download | teachos-04b0285d8329e45cea426aa1a8e69203685a4467.tar.xz teachos-04b0285d8329e45cea426aa1a8e69203685a4467.zip | |
Move iterator and container into generic template classes. Use algorithms instead of raw pointer for loops
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/x86_64/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/memory/multiboot/elf_symbols_section.hpp | 7 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/memory/multiboot/memory_map.hpp | 178 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/memory/multiboot/reader.hpp | 9 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/shared/container.hpp | 73 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/shared/random_access_iterator.hpp | 167 | ||||
| -rw-r--r-- | arch/x86_64/src/memory/allocator/area_frame_allocator.cpp | 4 | ||||
| -rw-r--r-- | arch/x86_64/src/memory/multiboot/memory_map.cpp | 73 | ||||
| -rw-r--r-- | arch/x86_64/src/memory/multiboot/reader.cpp | 79 |
9 files changed, 300 insertions, 291 deletions
diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt index 8658ed7..e1b7352 100644 --- a/arch/x86_64/CMakeLists.txt +++ b/arch/x86_64/CMakeLists.txt @@ -42,7 +42,6 @@ target_sources("_video" PRIVATE target_sources("_memory" PRIVATE "src/memory/multiboot/elf_symbols_section.cpp" - "src/memory/multiboot/memory_map.cpp" "src/memory/multiboot/reader.cpp" "src/memory/allocator/area_frame_allocator.cpp" "src/memory/allocator/physical_frame.cpp" diff --git a/arch/x86_64/include/arch/memory/multiboot/elf_symbols_section.hpp b/arch/x86_64/include/arch/memory/multiboot/elf_symbols_section.hpp index fc8cb15..c9989ae 100644 --- a/arch/x86_64/include/arch/memory/multiboot/elf_symbols_section.hpp +++ b/arch/x86_64/include/arch/memory/multiboot/elf_symbols_section.hpp @@ -1,7 +1,10 @@ #ifndef TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_ELF_SYBOLS_SECTION_HPP #define TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_ELF_SYBOLS_SECTION_HPP -#include "info.hpp" +#include "arch/memory/multiboot/info.hpp" +#include "arch/shared/container.hpp" +#include "arch/shared/random_access_iterator.hpp" + #include <bitset> #include <cstdint> @@ -158,6 +161,8 @@ namespace teachos::arch::memory::multiboot std::byte end; ///< Marks the end of the tag, used to mark the beginning of any additional data. ///< contained in the section, to ensure byte alignment is actually 4 byte. }; + + typedef shared::container<shared::random_access_iterator<elf_section_header>> elf_section_header_container; } // namespace teachos::arch::memory::multiboot #endif // TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_ELF_SYBOLS_SECTION_HPP diff --git a/arch/x86_64/include/arch/memory/multiboot/memory_map.hpp b/arch/x86_64/include/arch/memory/multiboot/memory_map.hpp index f9c902a..910eecb 100644 --- a/arch/x86_64/include/arch/memory/multiboot/memory_map.hpp +++ b/arch/x86_64/include/arch/memory/multiboot/memory_map.hpp @@ -1,9 +1,11 @@ #ifndef TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_MEMORY_MAP_HPP #define TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_MEMORY_MAP_HPP -#include "info.hpp" +#include "arch/memory/multiboot/info.hpp" +#include "arch/shared/container.hpp" +#include "arch/shared/random_access_iterator.hpp" + #include <cstdint> -#include <iterator> namespace teachos::arch::memory::multiboot { @@ -44,177 +46,7 @@ namespace teachos::arch::memory::multiboot struct memory_area entries; ///< Specific memory regions. }; - /** - * @brief Random access iterator for memory areas. - */ - struct memory_area_iterator - { - using iterator_category = std::random_access_iterator_tag; ///< Iterator category of this type. - using difference_type = std::ptrdiff_t; ///< Type when diving one instance of this iterator by another. - using value_type = memory_area; ///< Underlying value pointed to by this iterator. - - /** - * @brief Defaulted constructor. - */ - memory_area_iterator() = default; - - /** - * @brief Constructor. - * - * @param p Underlying address the iterator should point too, ensure to not pass an invalid pointer or the - * constructor will halt execution. - */ - explicit memory_area_iterator(value_type * p); - - /** - * @brief Dereferences the initally given pointer to its value. - * - * @return Reference to the value. - */ - auto operator*() const -> value_type &; - - /** - * @brief Get underlying value, which is the intially passed pointer. - * - * @return Underlying value passed intially. - */ - auto operator->() const -> value_type *; - - /** - * @brief Post increment operator. Returns a copy of the value. - * - * @return Copy of the incremented underlying address. - */ - auto operator++(int) -> memory_area_iterator; - - /** - * @brief Pre increment operator. Returns a reference to the changed value. - * - * @return Reference to the incremented underlying address. - */ - auto operator++() -> memory_area_iterator &; - - /** - * @brief Addition assignment operator. Returns a reference to the changed value. - * - * @param value Value we want to add to the underlying address. - * @return Reference to the changed underlying address. - */ - auto operator+=(difference_type value) -> memory_area_iterator &; - - /** - * @brief Subtraction assignment operator. Returns a reference to the changed value. - * - * @param value Value we want to subtract from the underlying address. - * @return Reference to the changed underlying address. - */ - auto operator-=(difference_type value) -> memory_area_iterator &; - - /** - * @brief Addition operator. Returns the changed value. - * - * @param value Value we want to add to a copy of the underlying address. - * @return Copy of underlying address incremented by the given value. - */ - auto operator+(difference_type value) const -> memory_area_iterator; - - /** - * @brief Subtraction operator. Returns the changed value. - * - * @param value Value we want to subtrcat from a copy of the underlying address. - * @return Copy of underlying address decremented by the given value. - */ - auto operator-(difference_type value) const -> memory_area_iterator; - - /** - * @brief Subtraction operator. Returns the size difference between two iterators. - * - * @param other Other iterator we want to substract the underlying address with ours. - * @return Size difference between the underlying address of this instance and the given iterator. - */ - auto operator-(const memory_area_iterator & other) const -> difference_type; - - /** - * @brief Index operator overload. Returns a reference to the value at the given index. Simply returns the - * dereferenced underlying pointer incremented by the given index. - * - * @param index Index we want to access and get the value from. - * @return Reference to the value at the given index. - */ - auto operator[](difference_type index) const -> value_type &; - - /** - * @brief Defaulted comparsion operator. Simply compares the memory address of both iterators. - * - * @param other Other iterator to compare to. - * @return Whether both iterators point to the same underlying address in memory. - */ - auto operator==(memory_area_iterator const & other) const -> bool = default; - - /** - * @brief Defaulted threeway comparsion operator. Simply compares the memory address of both iterators. - * - * @param other Other iterator to compare to. - * @return Whether the given iterator is smaller or larger than this iterator. - */ - auto operator<=>(memory_area_iterator const & other) const -> std::strong_ordering = default; - - private: - value_type * ptr; ///< Underlying address the iterator is currently pointing too. - }; - - /** - * @brief Read-only container for memory areas, that allow to easily use the memory_area_iterator in C++20 ranges - * calls. - */ - struct memory_area_container - { - using iterator = memory_area_iterator; ///< Iterators used by this container. - using size_type = std::size_t; ///< Maximum size of this container. - - /** - * @brief Constructor. - * - * @param begin Pointer to the first memory area, will be used to construct the begin iterator. - * @param size Amount of entries in the container we want to construct. - */ - memory_area_container(memory_area_iterator::value_type * begin, size_type size); - - /** - * @brief Returns the iterator pointing to the first element of the memory area. - * Allows using this class in the for each loop, because it follows the InputIterator template scheme. - * - * @return Iterator pointing to first element of the memory area. - */ - auto begin() const -> iterator; - - /** - * @brief Returns the iterator pointing to one past the last element of the memory area. - * Allows using this class in the for each loop, because it follows the InputIterator template scheme. - * - * @return Iterator pointing to one past the last element of the memory area. - */ - auto end() const -> iterator; - - /** - * @brief Calculates the size of this container, simply subtracts the iterator pointing to the first element by the - * last. - * - * @return Actual size of this container. - */ - auto size() const -> size_type; - - /** - * @brief Calcualtes the size and returns true if the size is 0 and the container therefore emtpy. - * - * @return Whether the container is empty, size being 0 or not - */ - auto empty() const -> bool; - - private: - iterator area_begin; ///< Pointer to the first element of all memory areas. - iterator area_end; ///< Pointer to one pas the last element of all memory areas. - }; + typedef shared::container<shared::random_access_iterator<memory_area>> memory_area_container; } // namespace teachos::arch::memory::multiboot #endif // TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_MEMORY_MAP_HPP diff --git a/arch/x86_64/include/arch/memory/multiboot/reader.hpp b/arch/x86_64/include/arch/memory/multiboot/reader.hpp index 393db8b..baa49c9 100644 --- a/arch/x86_64/include/arch/memory/multiboot/reader.hpp +++ b/arch/x86_64/include/arch/memory/multiboot/reader.hpp @@ -1,8 +1,8 @@ #ifndef TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_READER_HPP #define TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_READER_HPP -#include "elf_symbols_section.hpp" -#include "memory_map.hpp" +#include "arch/memory/multiboot/memory_map.hpp" + #include <cstdint> namespace teachos::arch::memory::multiboot @@ -17,8 +17,9 @@ namespace teachos::arch::memory::multiboot std::size_t kernel_end; ///< End address of the kernel code in memory. std::size_t multiboot_start; ///< Start address of the multiboot code in memory. std::size_t multiboot_end; ///< End address of the multiboot code in memory. - memory_area * memory_areas; ///< Non-owning pointer to the first element of all memory areas. - uint8_t area_count; ///< Amount of total entries in the memory_areas array. + memory_area_container::iterator + begin_area; ///< Iterator containing non-owning pointer to the first element of all memory areas. + memory_area_container::iterator end_area; ///< Iterator pointing to one past the last element of all memory areas. }; /** diff --git a/arch/x86_64/include/arch/shared/container.hpp b/arch/x86_64/include/arch/shared/container.hpp new file mode 100644 index 0000000..8ea0d08 --- /dev/null +++ b/arch/x86_64/include/arch/shared/container.hpp @@ -0,0 +1,73 @@ +#ifndef TEACHOS_ARCH_X86_64_SHARED_CONTAINER_HPP +#define TEACHOS_ARCH_X86_64_SHARED_CONTAINER_HPP + +#include "arch/exception_handling/assert.hpp" + +#include <iterator> + +namespace teachos::arch::shared +{ + /** + * @brief Read-only container for given template type, that allow to easily use this container instance in C++20 + * ranges calls. + * + * @tparam T Iterator the container uses to signal the start and end of it's data. + */ + template<typename T> + struct container + { + using iterator = T; ///< Iterators used by this container. + using size_type = std::size_t; ///< Maximum size of this container. + + /** + * @brief Constructor. + * + * @param begin Iterator containing non-owning pointer to the first element of all memory areas. + * @param end Iterator pointing to one past the last element of all memory areas. + */ + container(iterator begin, iterator end) + : begin_itr(begin) + , end_itr(end) + { + exception_handling::assert(begin != iterator{}, "[Memory Area] Attempted to pass nullptr as begin iterator"); + exception_handling::assert(end != iterator{}, "[Memory Area] Attempted to pass nullptr as end iterator"); + } + + /** + * @brief Returns the iterator pointing to the first element of the memory area. + * Allows using this class in the for each loop, because it follows the InputIterator template scheme. + * + * @return Iterator pointing to first element of the memory area. + */ + auto begin() const -> iterator { return begin_itr; } + + /** + * @brief Returns the iterator pointing to one past the last element of the memory area. + * Allows using this class in the for each loop, because it follows the InputIterator template scheme. + * + * @return Iterator pointing to one past the last element of the memory area. + */ + auto end() const -> iterator { return end_itr; } + + /** + * @brief Calculates the size of this container, simply subtracts the iterator pointing to the first element by the + * last. + * + * @return Actual size of this container. + */ + auto size() const -> size_type { return std::distance(begin(), end()); } + + /** + * @brief Calcualtes the size and returns true if the size is 0 and the container therefore emtpy. + * + * @return Whether the container is empty, size being 0 or not + */ + auto empty() const -> bool { return size() == 0; } + + private: + iterator begin_itr; ///< Pointer to the first element of the given template type. + iterator end_itr; ///< Pointer to one pas the last element of the given template type. + }; +} // namespace teachos::arch::shared + +#endif // TEACHOS_ARCH_X86_64_SHARED_CONTAINER_HPP diff --git a/arch/x86_64/include/arch/shared/random_access_iterator.hpp b/arch/x86_64/include/arch/shared/random_access_iterator.hpp new file mode 100644 index 0000000..392b925 --- /dev/null +++ b/arch/x86_64/include/arch/shared/random_access_iterator.hpp @@ -0,0 +1,167 @@ +#ifndef TEACHOS_ARCH_X86_64_SHARED_RANDOM_ACCESS_ITERATOR_HPP +#define TEACHOS_ARCH_X86_64_SHARED_RANDOM_ACCESS_ITERATOR_HPP + +#include <iterator> + +namespace teachos::arch::shared +{ + /** + * @brief Generic random access iterator for given template type. Can be a nullptr, ensure to check when using this + * iterator. Allows to easily use this iterator instance in algorithm calls. + * + * @tparam T Value the iterator points too. + */ + template<typename T> + struct random_access_iterator + { + using iterator_category = std::random_access_iterator_tag; ///< Iterator category of this type. + using difference_type = std::ptrdiff_t; ///< Type when diving one instance of this iterator by another. + using value_type = T; ///< Underlying value pointed to by this iterator. + + /** + * @brief Defaulted constructor. + */ + random_access_iterator() = default; + + /** + * @brief Constructor. + * + * @param p Underlying address the iterator should point too, ensure to not pass an invalid pointer or the + * constructor will halt execution. + */ + explicit random_access_iterator(value_type * p) + : ptr(p) + { + // Nothing to do + } + + /** + * @brief Dereferences the initally given pointer to its value. + * + * @return Reference to the value. + */ + auto operator*() const -> value_type & { return *ptr; } + + /** + * @brief Get underlying value, which is the intially passed pointer. + * + * @return Underlying value passed intially. + */ + auto operator->() const -> value_type * { return ptr; } + + /** + * @brief Post increment operator. Returns a copy of the value. + * + * @return Copy of the incremented underlying address. + */ + auto operator++(int) -> random_access_iterator + { + random_access_iterator old_value = *this; + ++ptr; + return old_value; + } + + /** + * @brief Pre increment operator. Returns a reference to the changed value. + * + * @return Reference to the incremented underlying address. + */ + auto operator++() -> random_access_iterator & + { + ++ptr; + return *this; + } + + /** + * @brief Addition assignment operator. Returns a reference to the changed value. + * + * @param value Value we want to add to the underlying address. + * @return Reference to the changed underlying address. + */ + auto operator+=(difference_type value) -> random_access_iterator & + { + ptr += value; + return *this; + } + + /** + * @brief Subtraction assignment operator. Returns a reference to the changed value. + * + * @param value Value we want to subtract from the underlying address. + * @return Reference to the changed underlying address. + */ + auto operator-=(difference_type value) -> random_access_iterator & + { + ptr -= value; + return *this; + } + + /** + * @brief Addition operator. Returns the changed value. + * + * @param value Value we want to add to a copy of the underlying address. + * @return Copy of underlying address incremented by the given value. + */ + auto operator+(difference_type value) const -> random_access_iterator + { + return random_access_iterator{ptr + value}; + } + + /** + * @brief Subtraction operator. Returns the changed value. + * + * @param value Value we want to subtrcat from a copy of the underlying address. + * @return Copy of underlying address decremented by the given value. + */ + auto operator-(difference_type value) const -> random_access_iterator + { + return random_access_iterator{ptr - value}; + } + + /** + * @brief Subtraction operator. Returns the size difference between two iterators. + * + * @param other Other iterator we want to substract the underlying address with ours. + * @return Size difference between the underlying address of this instance and the given iterator. + */ + auto operator-(const random_access_iterator & other) const -> difference_type { return ptr - other.ptr; } + + /** + * @brief Index operator overload. Returns a reference to the value at the given index. Simply returns the + * dereferenced underlying pointer incremented by the given index. + * + * @param index Index we want to access and get the value from. + * @return Reference to the value at the given index. + */ + auto operator[](difference_type index) const -> value_type & { return *(ptr + index); } + + /** + * @brief Defaulted comparsion operator. Simply compares the memory address of both iterators. + * + * @param other Other iterator to compare to. + * @return Whether both iterators point to the same underlying address in memory. + */ + auto operator==(random_access_iterator const & other) const -> bool = default; + + /** + * @brief Defaulted negated comparsion operator. Simply compares the memory address of both iterators. + * + * @param other Other iterator to compare to. + * @return Whether both iterators don't point to the same underlying address in memory. + */ + auto operator!=(random_access_iterator const & other) const -> bool = default; + + /** + * @brief Defaulted threeway comparsion operator. Simply compares the memory address of both iterators. + * + * @param other Other iterator to compare to. + * @return Whether the given iterator is smaller or larger than this iterator. + */ + auto operator<=>(random_access_iterator const & other) const -> std::strong_ordering = default; + + private: + value_type * ptr = {}; ///< Underlying address the iterator is currently pointing too. + }; +} // namespace teachos::arch::shared + +#endif // TEACHOS_ARCH_X86_64_SHARED_RANDOM_ACCESS_ITERATOR_HPP diff --git a/arch/x86_64/src/memory/allocator/area_frame_allocator.cpp b/arch/x86_64/src/memory/allocator/area_frame_allocator.cpp index 6ed4f28..e03c66a 100644 --- a/arch/x86_64/src/memory/allocator/area_frame_allocator.cpp +++ b/arch/x86_64/src/memory/allocator/area_frame_allocator.cpp @@ -9,9 +9,9 @@ namespace teachos::arch::memory::allocator { area_frame_allocator::area_frame_allocator(multiboot::memory_information mem_info) - : next_free_frame(0) + : next_free_frame(0U) , current_area(std::nullopt) - , memory_areas(mem_info.memory_areas, mem_info.area_count) + , memory_areas(mem_info.begin_area, mem_info.end_area) , kernel_start(physical_frame::containing_address(mem_info.kernel_start)) , kernel_end(physical_frame::containing_address(mem_info.kernel_end)) , multiboot_start(physical_frame::containing_address(mem_info.multiboot_start)) diff --git a/arch/x86_64/src/memory/multiboot/memory_map.cpp b/arch/x86_64/src/memory/multiboot/memory_map.cpp deleted file mode 100644 index b5e2759..0000000 --- a/arch/x86_64/src/memory/multiboot/memory_map.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include "arch/memory/multiboot/memory_map.hpp" - -#include "arch/exception_handling/assert.hpp" - -namespace teachos::arch::memory::multiboot -{ - memory_area_iterator::memory_area_iterator(value_type * p) - : ptr(p) - { - exception_handling::assert(ptr, "[Memory Area] Attempted to pass nullptr as iterator"); - } - - auto memory_area_iterator::operator*() const -> value_type & { return *ptr; } - - auto memory_area_iterator::operator->() const -> value_type * { return ptr; } - - auto memory_area_iterator::operator++(int) -> memory_area_iterator - { - memory_area_iterator old_value = *this; - ++ptr; - return old_value; - } - - auto memory_area_iterator::operator++() -> memory_area_iterator & - { - ++ptr; - return *this; - } - - auto memory_area_iterator::operator+=(difference_type value) -> memory_area_iterator & - { - ptr += value; - return *this; - } - - auto memory_area_iterator::operator-=(difference_type value) -> memory_area_iterator & - { - ptr -= value; - return *this; - } - - auto memory_area_iterator::operator+(difference_type value) const -> memory_area_iterator - { - return memory_area_iterator{ptr + value}; - } - - auto memory_area_iterator::operator-(difference_type value) const -> memory_area_iterator - { - return memory_area_iterator{ptr - value}; - } - - auto memory_area_iterator::operator-(const memory_area_iterator & other) const -> difference_type - { - return ptr - other.ptr; - } - - auto memory_area_iterator::operator[](difference_type index) const -> value_type & { return *(ptr + index); } - - memory_area_container::memory_area_container(memory_area * begin, std::size_t size) - : area_begin(begin) - , area_end(begin + size) - { - // Nothing to do - } - - auto memory_area_container::begin() const -> multiboot::memory_area_iterator { return area_begin; } - - auto memory_area_container::end() const -> multiboot::memory_area_iterator { return area_end; } - - auto memory_area_container::size() const -> size_type { return std::distance(begin(), end()); } - - auto memory_area_container::empty() const -> bool { return size() == 0; } -} // namespace teachos::arch::memory::multiboot diff --git a/arch/x86_64/src/memory/multiboot/reader.cpp b/arch/x86_64/src/memory/multiboot/reader.cpp index c750ae1..228aa09 100644 --- a/arch/x86_64/src/memory/multiboot/reader.cpp +++ b/arch/x86_64/src/memory/multiboot/reader.cpp @@ -2,8 +2,11 @@ #include "arch/boot/pointers.hpp" #include "arch/exception_handling/assert.hpp" +#include "arch/memory/multiboot/elf_symbols_section.hpp" #include "arch/memory/multiboot/info.hpp" +#include <algorithm> + namespace teachos::arch::memory::multiboot { namespace @@ -15,7 +18,8 @@ namespace teachos::arch::memory::multiboot return reinterpret_cast<T>(reinterpret_cast<uint8_t *>(ptr) + ((size + 7) & ~7)); } - auto process_memory_map(memory_map_header * mminfo, memory_area *& memory_areas, uint8_t & area_count) -> void + auto process_memory_map(memory_map_header * mminfo, memory_area_container::iterator & begin_area, + memory_area_container::iterator & end_area) -> void { auto expected_entry_size = mminfo->entry_size; constexpr auto actual_entry_size = sizeof(memory_area); @@ -26,8 +30,8 @@ namespace teachos::arch::memory::multiboot auto total_entries_size = total_size - sizeof(memory_map_header) + actual_entry_size; auto number_of_entries = total_entries_size / actual_entry_size; - memory_areas = &mminfo->entries; - area_count = number_of_entries; + begin_area = memory_area_container::iterator{&mminfo->entries}; + end_area = begin_area + number_of_entries; } auto process_elf_sections(elf_symbols_section_header * symbol, uint64_t & kernel_start, @@ -45,40 +49,30 @@ namespace teachos::arch::memory::multiboot exception_handling::assert(expected_total_size == actual_total_size, "[Multiboot Reader] Unexpected elf symbols section header total size"); - auto begin = reinterpret_cast<elf_section_header *>(&symbol->end); + auto begin = elf_section_header_container::iterator{reinterpret_cast<elf_section_header *>(&symbol->end)}; auto end = begin + symbol->number_of_sections; exception_handling::assert(begin->is_null(), "[Multiboot Reader] Elf symbols section not starting with SHT_NULL section"); - std::size_t symbol_table_section_count = 0U; - std::size_t dynamic_section_count = 0U; + elf_section_header_container container{begin, end}; - for (auto section = begin; section != end; ++section) - { - if (section->virtual_address < kernel_start) - { - kernel_start = section->virtual_address; - } - auto virtual_address_end = section->virtual_address + section->section_size; - if (virtual_address_end > kernel_end) - { - kernel_end = virtual_address_end; - } + auto elf_section_with_lowest_virtual_address = + std::ranges::min_element(container, [](elf_section_header const & a, elf_section_header const & b) { + return a.virtual_address < b.virtual_address; + }); - switch (section->type) - { - case elf_section_type::DYNAMIC_SYMBOL_TABLE: - case elf_section_type::SYMBOL_TABLE: - symbol_table_section_count++; - break; - case elf_section_type::DYNAMIC: - dynamic_section_count++; - break; - default: - // All other cases are not important and can be ignored - break; - } - } + auto elf_section_with_highest_virtual_address = + std::ranges::max_element(container, [](elf_section_header const & a, elf_section_header const & b) { + auto a_virtual_address_end = a.virtual_address + a.section_size; + auto b_virtual_address_end = b.virtual_address + b.section_size; + return a_virtual_address_end < b_virtual_address_end; + }); + + auto symbol_table_section_count = std::ranges::count_if(container, [](elf_section_header const & section) { + return section.type == elf_section_type::DYNAMIC_SYMBOL_TABLE || section.type == elf_section_type::SYMBOL_TABLE; + }); + auto dynamic_section_count = std::ranges::count_if( + container, [](elf_section_header const & section) { return section.type == elf_section_type::DYNAMIC; }); exception_handling::assert( symbol_table_section_count == 1U, @@ -86,15 +80,26 @@ namespace teachos::arch::memory::multiboot exception_handling::assert( dynamic_section_count <= 1U, "[Multiboot Reader] ELF Specifications allows only (1) or less dynamic sections, but got more"); + + auto lowest_elf_section = *elf_section_with_lowest_virtual_address; + kernel_start = lowest_elf_section.virtual_address; + + auto highest_elf_section = *elf_section_with_highest_virtual_address; + kernel_end = highest_elf_section.virtual_address + highest_elf_section.section_size; } } // namespace auto read_multiboot2() -> memory_information { - memory_information mem_info{UINT64_MAX, 0U, boot::multiboot_information_pointer, 0U, nullptr, 0U}; - - auto * multiboot_information_pointer = reinterpret_cast<info_header *>(boot::multiboot_information_pointer); - auto multiboot_tag = &(multiboot_information_pointer->tags); + memory_information mem_info{UINT64_MAX, + 0U, + boot::multiboot_information_pointer, + 0U, + memory_area_container::iterator{}, + memory_area_container::iterator{}}; + + auto multiboot_information_pointer = reinterpret_cast<info_header *>(boot::multiboot_information_pointer); + auto multiboot_tag = &multiboot_information_pointer->tags; mem_info.multiboot_end = mem_info.multiboot_start + multiboot_information_pointer->total_size; for (auto tag = multiboot_tag; tag->type != tag_type::END; tag = align_to_8_byte_boundary(tag, tag->size)) @@ -108,11 +113,11 @@ namespace teachos::arch::memory::multiboot } case tag_type::MEMORY_MAP: { auto mminfo = reinterpret_cast<memory_map_header *>(tag); - process_memory_map(mminfo, mem_info.memory_areas, mem_info.area_count); + process_memory_map(mminfo, mem_info.begin_area, mem_info.end_area); break; } default: - // All other cases are not important and can be ignored + // All other cases are not important and can be ignored. break; } } |
