diff options
author | Nicholas Baron <nicholas.baron.ten@gmail.com> | 2021-05-16 02:36:52 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-16 10:36:52 +0100 |
commit | aa4d41fe2c473c3bb78327a1dbe8ec85530259ca (patch) | |
tree | 925d408b37ab1f7750a3af37adfb2949fcafa836 /Userland/Libraries | |
parent | bbaa4630323c20e37e2a0ead478987cb5f02fc53 (diff) | |
download | serenity-aa4d41fe2c473c3bb78327a1dbe8ec85530259ca.zip |
AK+Kernel+LibELF: Remove the need for `IteratorDecision::Continue`
By constraining two implementations, the compiler will select the best
fitting one. All this will require is duplicating the implementation and
simplifying for the `void` case.
This constraining also informs both the caller and compiler by passing
the callback parameter types as part of the constraint
(e.g.: `IterationFunction<int>`).
Some `for_each` functions in LibELF only take functions which return
`void`. This is a minimal correctness check, as it removes one way for a
function to incompletely do something.
There seems to be a possible idiom where inside a lambda, a `return;` is
the same as `continue;` in a for-loop.
Diffstat (limited to 'Userland/Libraries')
-rw-r--r-- | Userland/Libraries/LibELF/DynamicLinker.cpp | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibELF/DynamicLoader.cpp | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibELF/DynamicObject.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibELF/DynamicObject.h | 54 | ||||
-rw-r--r-- | Userland/Libraries/LibELF/Image.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibELF/Image.h | 80 |
6 files changed, 104 insertions, 41 deletions
diff --git a/Userland/Libraries/LibELF/DynamicLinker.cpp b/Userland/Libraries/LibELF/DynamicLinker.cpp index 37281ad971..43d2d0cb6b 100644 --- a/Userland/Libraries/LibELF/DynamicLinker.cpp +++ b/Userland/Libraries/LibELF/DynamicLinker.cpp @@ -125,9 +125,8 @@ static Vector<String> get_dependencies(const String& name) lib->for_each_needed_library([&dependencies, &name](auto needed_name) { if (name == needed_name) - return IterationDecision::Continue; + return; dependencies.append(needed_name); - return IterationDecision::Continue; }); return dependencies; } diff --git a/Userland/Libraries/LibELF/DynamicLoader.cpp b/Userland/Libraries/LibELF/DynamicLoader.cpp index 5c8a7f9be8..934de40153 100644 --- a/Userland/Libraries/LibELF/DynamicLoader.cpp +++ b/Userland/Libraries/LibELF/DynamicLoader.cpp @@ -93,7 +93,6 @@ const DynamicObject& DynamicLoader::dynamic_object() const if (program_header.type() == PT_DYNAMIC) { dynamic_section_address = VirtualAddress(program_header.raw_data()); } - return IterationDecision::Continue; }); VERIFY(!dynamic_section_address.is_null()); @@ -109,7 +108,6 @@ size_t DynamicLoader::calculate_tls_size() const if (program_header.type() == PT_TLS) { tls_size = program_header.size_in_memory(); } - return IterationDecision::Continue; }); return tls_size; } @@ -194,7 +192,6 @@ void DynamicLoader::do_main_relocations() case RelocationResult::Success: break; } - return IterationDecision::Continue; }; m_dynamic_object->relocation_section().for_each_relocation(do_single_relocation); m_dynamic_object->plt_relocation_section().for_each_relocation(do_single_relocation); @@ -273,7 +270,6 @@ void DynamicLoader::load_program_headers() VERIFY(!relro_region.has_value()); relro_region = region; } - return IterationDecision::Continue; }); VERIFY(!text_regions.is_empty() || !data_regions.is_empty()); diff --git a/Userland/Libraries/LibELF/DynamicObject.cpp b/Userland/Libraries/LibELF/DynamicObject.cpp index 39dc9f435f..439d5ca16a 100644 --- a/Userland/Libraries/LibELF/DynamicObject.cpp +++ b/Userland/Libraries/LibELF/DynamicObject.cpp @@ -49,7 +49,6 @@ void DynamicObject::dump() const String name_field = String::formatted("({})", name_for_dtag(entry.tag())); builder.appendff("{:#08x} {:17} {:#08x}\n", entry.tag(), name_field, entry.val()); num_dynamic_sections++; - return IterationDecision::Continue; }); if (m_has_soname) @@ -171,7 +170,6 @@ void DynamicObject::parse() VERIFY_NOT_REACHED(); // FIXME: Maybe just break out here and return false? break; } - return IterationDecision::Continue; }); if (!m_size_of_relocation_entry) { diff --git a/Userland/Libraries/LibELF/DynamicObject.h b/Userland/Libraries/LibELF/DynamicObject.h index 08b2f4d217..8381be9c0f 100644 --- a/Userland/Libraries/LibELF/DynamicObject.h +++ b/Userland/Libraries/LibELF/DynamicObject.h @@ -8,6 +8,7 @@ #pragma once #include <AK/Assertions.h> +#include <AK/Concepts.h> #include <AK/RefCounted.h> #include <AK/String.h> #include <Kernel/VirtualAddress.h> @@ -125,8 +126,11 @@ public: unsigned relocation_count() const { return entry_count(); } Relocation relocation(unsigned index) const; Relocation relocation_at_offset(unsigned offset) const; - template<typename F> + + template<IteratorFunction<DynamicObject::Relocation&> F> void for_each_relocation(F) const; + template<VoidFunction<DynamicObject::Relocation&> F> + void for_each_relocation(F func) const; }; class Relocation { @@ -251,16 +255,18 @@ public: ElfW(Half) program_header_count() const; const ElfW(Phdr) * program_headers() const; - template<typename F> + template<VoidFunction<StringView> F> void for_each_needed_library(F) const; - template<typename F> + template<VoidFunction<InitializationFunction&> F> void for_each_initialization_array_function(F f) const; - template<typename F> + template<IteratorFunction<DynamicEntry&> F> void for_each_dynamic_entry(F) const; + template<VoidFunction<DynamicEntry&> F> + void for_each_dynamic_entry(F func) const; - template<typename F> + template<VoidFunction<Symbol&> F> void for_each_symbol(F) const; struct SymbolLookupResult { @@ -341,7 +347,7 @@ private: // End Section information from DT_* entries }; -template<typename F> +template<IteratorFunction<DynamicObject::Relocation&> F> inline void DynamicObject::RelocationSection::for_each_relocation(F func) const { for (unsigned i = 0; i < relocation_count(); ++i) { @@ -353,16 +359,24 @@ inline void DynamicObject::RelocationSection::for_each_relocation(F func) const } } -template<typename F> +template<VoidFunction<DynamicObject::Relocation&> F> +inline void DynamicObject::RelocationSection::for_each_relocation(F func) const +{ + for_each_relocation([&](auto& reloc) { + func(reloc); + return IterationDecision::Continue; + }); +} + +template<VoidFunction<DynamicObject::Symbol&> F> inline void DynamicObject::for_each_symbol(F func) const { for (unsigned i = 0; i < symbol_count(); ++i) { - if (func(symbol(i)) == IterationDecision::Break) - break; + func(symbol(i)); } } -template<typename F> +template<IteratorFunction<DynamicObject::DynamicEntry&> F> inline void DynamicObject::for_each_dynamic_entry(F func) const { auto* dyns = reinterpret_cast<const ElfW(Dyn)*>(m_dynamic_address.as_ptr()); @@ -374,21 +388,29 @@ inline void DynamicObject::for_each_dynamic_entry(F func) const break; } } -template<typename F> + +template<VoidFunction<DynamicObject::DynamicEntry&> F> +inline void DynamicObject::for_each_dynamic_entry(F func) const +{ + for_each_dynamic_entry([&](auto& dyn) { + func(dyn); + return IterationDecision::Continue; + }); +} + +template<VoidFunction<StringView> F> inline void DynamicObject::for_each_needed_library(F func) const { for_each_dynamic_entry([func, this](auto entry) { if (entry.tag() != DT_NEEDED) - return IterationDecision::Continue; + return; ElfW(Word) offset = entry.val(); StringView name { (const char*)(m_base_address.offset(m_string_table_offset).offset(offset)).as_ptr() }; - if (func(StringView(name)) == IterationDecision::Break) - return IterationDecision::Break; - return IterationDecision::Continue; + func(name); }); } -template<typename F> +template<VoidFunction<DynamicObject::InitializationFunction&> F> void DynamicObject::for_each_initialization_array_function(F f) const { if (!has_init_array_section()) diff --git a/Userland/Libraries/LibELF/Image.cpp b/Userland/Libraries/LibELF/Image.cpp index 91d5596919..97ea2eba1e 100644 --- a/Userland/Libraries/LibELF/Image.cpp +++ b/Userland/Libraries/LibELF/Image.cpp @@ -97,7 +97,6 @@ void Image::dump() const dbgln(" offset: {:x}", program_header.offset()); dbgln(" flags: {:x}", program_header.flags()); dbgln(" }}"); - return IterationDecision::Continue; }); for (unsigned i = 0; i < header().e_shnum; ++i) { @@ -344,7 +343,6 @@ NEVER_INLINE void Image::sort_symbols() const m_sorted_symbols.ensure_capacity(symbol_count()); for_each_symbol([this](const auto& symbol) { m_sorted_symbols.append({ symbol.value(), symbol.name(), {}, symbol }); - return IterationDecision::Continue; }); quick_sort(m_sorted_symbols, [](auto& a, auto& b) { return a.address < b.address; diff --git a/Userland/Libraries/LibELF/Image.h b/Userland/Libraries/LibELF/Image.h index d8b8a391a8..b55519a0f2 100644 --- a/Userland/Libraries/LibELF/Image.h +++ b/Userland/Libraries/LibELF/Image.h @@ -6,6 +6,7 @@ #pragma once +#include <AK/Concepts.h> #include <AK/String.h> #include <AK/Vector.h> #include <Kernel/VirtualAddress.h> @@ -134,7 +135,8 @@ public: } unsigned relocation_count() const { return entry_count(); } Relocation relocation(unsigned index) const; - template<typename F> + + template<VoidFunction<Image::Relocation&> F> void for_each_relocation(F) const; }; @@ -167,13 +169,24 @@ public: ProgramHeader program_header(unsigned) const; FlatPtr program_header_table_offset() const; - template<typename F> + template<IteratorFunction<Image::Section> F> + void for_each_section(F) const; + template<VoidFunction<Section> F> void for_each_section(F) const; - template<typename F> + + template<IteratorFunction<Section&> F> + void for_each_section_of_type(unsigned, F) const; + template<VoidFunction<Section&> F> void for_each_section_of_type(unsigned, F) const; - template<typename F> + + template<IteratorFunction<Symbol> F> + void for_each_symbol(F) const; + template<VoidFunction<Symbol> F> void for_each_symbol(F) const; - template<typename F> + + template<IteratorFunction<ProgramHeader> F> + void for_each_program_header(F func) const; + template<VoidFunction<ProgramHeader> F> void for_each_program_header(F) const; Optional<Section> lookup_section(String const& name) const; @@ -222,15 +235,26 @@ private: mutable Vector<SortedSymbol> m_sorted_symbols; }; -template<typename F> +template<IteratorFunction<Image::Section> F> inline void Image::for_each_section(F func) const { auto section_count = this->section_count(); - for (unsigned i = 0; i < section_count; ++i) - func(section(i)); + for (unsigned i = 0; i < section_count; ++i) { + if (func(section(i)) == IterationDecision::Break) + break; + } +} + +template<VoidFunction<Image::Section> F> +inline void Image::for_each_section(F func) const +{ + for_each_section([&](auto section) { + func(move(section)); + return IterationDecision::Continue; + }); } -template<typename F> +template<IteratorFunction<Image::Section&> F> inline void Image::for_each_section_of_type(unsigned type, F func) const { auto section_count = this->section_count(); @@ -243,17 +267,25 @@ inline void Image::for_each_section_of_type(unsigned type, F func) const } } -template<typename F> +template<VoidFunction<Image::Section&> F> +inline void Image::for_each_section_of_type(unsigned type, F func) const +{ + for_each_section_of_type(type, [&](auto& section) { + func(section); + return IterationDecision::Continue; + }); +} + +template<VoidFunction<Image::Relocation&> F> inline void Image::RelocationSection::for_each_relocation(F func) const { auto relocation_count = this->relocation_count(); for (unsigned i = 0; i < relocation_count; ++i) { - if (func(relocation(i)) == IterationDecision::Break) - break; + func(relocation(i)); } } -template<typename F> +template<IteratorFunction<Image::Symbol> F> inline void Image::for_each_symbol(F func) const { auto symbol_count = this->symbol_count(); @@ -263,14 +295,32 @@ inline void Image::for_each_symbol(F func) const } } -template<typename F> +template<VoidFunction<Image::Symbol> F> +inline void Image::for_each_symbol(F func) const +{ + for_each_symbol([&](auto symbol) { + func(move(symbol)); + return IterationDecision::Continue; + }); +} + +template<IteratorFunction<Image::ProgramHeader> F> inline void Image::for_each_program_header(F func) const { auto program_header_count = this->program_header_count(); for (unsigned i = 0; i < program_header_count; ++i) { if (func(program_header(i)) == IterationDecision::Break) - return; + break; } } +template<VoidFunction<Image::ProgramHeader> F> +inline void Image::for_each_program_header(F func) const +{ + for_each_program_header([&](auto header) { + func(move(header)); + return IterationDecision::Continue; + }); +} + } // end namespace ELF |