diff options
author | Andreas Kling <kling@serenityos.org> | 2020-12-25 02:14:56 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-12-25 02:14:56 +0100 |
commit | 1e4c01064351d2f8ce3d55a173c5022d2601ad40 (patch) | |
tree | 07397a8f13d69ea15a191a0a16e58cedd35d8a10 /Libraries/LibELF | |
parent | 7551a66f738ccd5f3f78e25493b46479ad50851d (diff) | |
download | serenity-1e4c01064351d2f8ce3d55a173c5022d2601ad40.zip |
LibELF: Remove ELF::Loader and move everyone to ELF::Image
This commit gets rid of ELF::Loader entirely since its very ambiguous
purpose was actually to load executables for the kernel, and that is
now handled by the kernel itself.
This patch includes some drive-by cleanup in LibDebug and CrashDaemon
enabled by the fact that we no longer need to keep the ref-counted
ELF::Loader around.
Diffstat (limited to 'Libraries/LibELF')
-rw-r--r-- | Libraries/LibELF/Image.cpp | 81 | ||||
-rw-r--r-- | Libraries/LibELF/Image.h | 13 | ||||
-rw-r--r-- | Libraries/LibELF/Loader.cpp | 128 | ||||
-rw-r--r-- | Libraries/LibELF/Loader.h | 85 |
4 files changed, 94 insertions, 213 deletions
diff --git a/Libraries/LibELF/Image.cpp b/Libraries/LibELF/Image.cpp index 085cb97aa3..f455a7d98b 100644 --- a/Libraries/LibELF/Image.cpp +++ b/Libraries/LibELF/Image.cpp @@ -26,6 +26,7 @@ #include <AK/Demangle.h> #include <AK/Memory.h> +#include <AK/QuickSort.h> #include <AK/StringBuilder.h> #include <AK/StringView.h> #include <LibELF/Image.h> @@ -323,4 +324,84 @@ Optional<Image::Symbol> Image::find_demangled_function(const String& name) const return found; } +Optional<Image::Symbol> Image::find_symbol(u32 address, u32* out_offset) const +{ + auto symbol_count = this->symbol_count(); + if (!symbol_count) + return {}; + + SortedSymbol* sorted_symbols = nullptr; + if (m_sorted_symbols.is_empty()) { + m_sorted_symbols.ensure_capacity(symbol_count); + for_each_symbol([this](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; + }); + } + sorted_symbols = m_sorted_symbols.data(); + + for (size_t i = 0; i < symbol_count; ++i) { + if (sorted_symbols[i].address > address) { + if (i == 0) + return {}; + auto& symbol = sorted_symbols[i - 1]; + if (out_offset) + *out_offset = address - symbol.address; + return symbol.symbol; + } + } + return {}; +} + +String Image::symbolicate(u32 address, u32* out_offset) const +{ + auto symbol_count = this->symbol_count(); + if (!symbol_count) { + if (out_offset) + *out_offset = 0; + return "??"; + } + SortedSymbol* sorted_symbols = nullptr; + + if (m_sorted_symbols.is_empty()) { + m_sorted_symbols.ensure_capacity(symbol_count); + for_each_symbol([this](auto& symbol) { + m_sorted_symbols.append({ symbol.value(), symbol.name(), {}, {} }); + return IterationDecision::Continue; + }); + quick_sort(m_sorted_symbols, [](auto& a, auto& b) { + return a.address < b.address; + }); + } + sorted_symbols = m_sorted_symbols.data(); + + for (size_t i = 0; i < symbol_count; ++i) { + if (sorted_symbols[i].address > address) { + if (i == 0) { + if (out_offset) + *out_offset = 0; + return "!!"; + } + auto& symbol = sorted_symbols[i - 1]; + + auto& demangled_name = symbol.demangled_name; + if (demangled_name.is_null()) { + demangled_name = demangle(symbol.name); + } + + if (out_offset) { + *out_offset = address - symbol.address; + return demangled_name; + } + return String::format("%s +%u", demangled_name.characters(), address - symbol.address); + } + } + if (out_offset) + *out_offset = 0; + return "??"; +} + } // end namespace ELF diff --git a/Libraries/LibELF/Image.h b/Libraries/LibELF/Image.h index 4cb941c019..eb444ab412 100644 --- a/Libraries/LibELF/Image.h +++ b/Libraries/LibELF/Image.h @@ -210,6 +210,10 @@ public: Optional<Symbol> find_demangled_function(const String& name) const; + bool has_symbols() const { return symbol_count(); } + String symbolicate(u32 address, u32* offset = nullptr) const; + Optional<Image::Symbol> find_symbol(u32 address, u32* offset = nullptr) const; + private: const char* raw_data(unsigned offset) const; const Elf32_Ehdr& header() const; @@ -227,6 +231,15 @@ private: bool m_valid { false }; unsigned m_symbol_table_section_index { 0 }; unsigned m_string_table_section_index { 0 }; + + struct SortedSymbol { + u32 address; + StringView name; + String demangled_name; + Optional<Image::Symbol> symbol; + }; + + mutable Vector<SortedSymbol> m_sorted_symbols; }; template<typename F> diff --git a/Libraries/LibELF/Loader.cpp b/Libraries/LibELF/Loader.cpp deleted file mode 100644 index 4b0bd25279..0000000000 --- a/Libraries/LibELF/Loader.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "Loader.h" -#include <AK/Demangle.h> -#include <AK/Memory.h> -#include <AK/QuickSort.h> - -//#define Loader_DEBUG - -namespace ELF { - -Loader::Loader(const u8* buffer, size_t size, String&&, bool verbose_logging) - : m_image(buffer, size, verbose_logging) -{ - if (m_image.is_valid()) - m_symbol_count = m_image.symbol_count(); -} - -Loader::~Loader() -{ -} - -#ifndef KERNEL -Optional<Image::Symbol> Loader::find_symbol(u32 address, u32* out_offset) const -{ - if (!m_symbol_count) - return {}; - - SortedSymbol* sorted_symbols = nullptr; - if (m_sorted_symbols.is_empty()) { - m_sorted_symbols.ensure_capacity(m_symbol_count); - m_image.for_each_symbol([this](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; - }); - } - sorted_symbols = m_sorted_symbols.data(); - - for (size_t i = 0; i < m_symbol_count; ++i) { - if (sorted_symbols[i].address > address) { - if (i == 0) - return {}; - auto& symbol = sorted_symbols[i - 1]; - if (out_offset) - *out_offset = address - symbol.address; - return symbol.symbol; - } - } - return {}; -} - -String Loader::symbolicate(u32 address, u32* out_offset) const -{ - if (!m_symbol_count) { - if (out_offset) - *out_offset = 0; - return "??"; - } - SortedSymbol* sorted_symbols = nullptr; - - if (m_sorted_symbols.is_empty()) { - m_sorted_symbols.ensure_capacity(m_symbol_count); - m_image.for_each_symbol([this](auto& symbol) { - m_sorted_symbols.append({ symbol.value(), symbol.name(), {}, {} }); - return IterationDecision::Continue; - }); - quick_sort(m_sorted_symbols, [](auto& a, auto& b) { - return a.address < b.address; - }); - } - sorted_symbols = m_sorted_symbols.data(); - - for (size_t i = 0; i < m_symbol_count; ++i) { - if (sorted_symbols[i].address > address) { - if (i == 0) { - if (out_offset) - *out_offset = 0; - return "!!"; - } - auto& symbol = sorted_symbols[i - 1]; - - auto& demangled_name = symbol.demangled_name; - if (demangled_name.is_null()) { - demangled_name = demangle(symbol.name); - } - - if (out_offset) { - *out_offset = address - symbol.address; - return demangled_name; - } - return String::format("%s +%u", demangled_name.characters(), address - symbol.address); - } - } - if (out_offset) - *out_offset = 0; - return "??"; -} - -#endif - -} // end namespace ELF diff --git a/Libraries/LibELF/Loader.h b/Libraries/LibELF/Loader.h deleted file mode 100644 index afa6c391a5..0000000000 --- a/Libraries/LibELF/Loader.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once - -#include <AK/Function.h> -#include <AK/HashMap.h> -#include <AK/NonnullRefPtr.h> -#include <AK/OwnPtr.h> -#include <AK/StringView.h> -#include <AK/Vector.h> -#include <LibELF/Image.h> - -#ifdef KERNEL -# include <Kernel/VirtualAddress.h> -namespace Kernel { -class Region; -} -#endif - -namespace ELF { - -class Loader : public RefCounted<Loader> { -public: - static NonnullRefPtr<Loader> create(const u8* data, size_t size, String&& name = String::empty(), bool verbose_logging = true) { return adopt(*new Loader(data, size, move(name), verbose_logging)); } - ~Loader(); - - VirtualAddress entry() const - { - return m_image.entry(); - } - const Image& image() const { return m_image; } - Optional<Image::Symbol> find_demangled_function(const String& name) const - { - return m_image.find_demangled_function(name); - } - - bool has_symbols() const { return m_symbol_count; } - - String symbolicate(u32 address, u32* offset = nullptr) const; - Optional<Image::Symbol> find_symbol(u32 address, u32* offset = nullptr) const; - -private: - explicit Loader(const u8*, size_t, String&& name, bool verbose_logging); - - bool layout(); - - Image m_image; - - size_t m_symbol_count { 0 }; - - struct SortedSymbol { - u32 address; - StringView name; - String demangled_name; - Optional<Image::Symbol> symbol; - }; - - mutable Vector<SortedSymbol> m_sorted_symbols; -}; - -} // end namespace ELF |