From 04b0285d8329e45cea426aa1a8e69203685a4467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Mon, 28 Oct 2024 10:15:18 +0000 Subject: Move iterator and container into generic template classes. Use algorithms instead of raw pointer for loops --- .../src/memory/allocator/area_frame_allocator.cpp | 4 +- arch/x86_64/src/memory/multiboot/memory_map.cpp | 73 -------------------- arch/x86_64/src/memory/multiboot/reader.cpp | 79 ++++++++++++---------- 3 files changed, 44 insertions(+), 112 deletions(-) delete mode 100644 arch/x86_64/src/memory/multiboot/memory_map.cpp (limited to 'arch/x86_64/src/memory') 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 + namespace teachos::arch::memory::multiboot { namespace @@ -15,7 +18,8 @@ namespace teachos::arch::memory::multiboot return reinterpret_cast(reinterpret_cast(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(&symbol->end); + auto begin = elf_section_header_container::iterator{reinterpret_cast(&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(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(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(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; } } -- cgit v1.2.3