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 | |
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')
-rw-r--r-- | Libraries/LibDebug/DebugInfo.cpp | 10 | ||||
-rw-r--r-- | Libraries/LibDebug/DebugInfo.h | 10 | ||||
-rw-r--r-- | Libraries/LibDebug/DebugSession.cpp | 3 | ||||
-rw-r--r-- | Libraries/LibDebug/DebugSession.h | 5 | ||||
-rw-r--r-- | Libraries/LibDebug/Dwarf/DwarfInfo.cpp | 4 | ||||
-rw-r--r-- | Libraries/LibDebug/Dwarf/DwarfInfo.h | 9 | ||||
-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 | ||||
-rw-r--r-- | Libraries/LibX86/ELFSymbolProvider.h | 10 |
11 files changed, 118 insertions, 240 deletions
diff --git a/Libraries/LibDebug/DebugInfo.cpp b/Libraries/LibDebug/DebugInfo.cpp index 6ceb72b455..10204f23d3 100644 --- a/Libraries/LibDebug/DebugInfo.cpp +++ b/Libraries/LibDebug/DebugInfo.cpp @@ -35,9 +35,9 @@ namespace Debug { -DebugInfo::DebugInfo(NonnullRefPtr<const ELF::Loader> elf) - : m_elf(elf) - , m_dwarf_info(Dwarf::DwarfInfo::create(m_elf)) +DebugInfo::DebugInfo(NonnullOwnPtr<const ELF::Image> elf) + : m_elf(move(elf)) + , m_dwarf_info(*m_elf) { prepare_variable_scopes(); prepare_lines(); @@ -45,7 +45,7 @@ DebugInfo::DebugInfo(NonnullRefPtr<const ELF::Loader> elf) void DebugInfo::prepare_variable_scopes() { - m_dwarf_info->for_each_compilation_unit([&](const Dwarf::CompilationUnit& unit) { + m_dwarf_info.for_each_compilation_unit([&](const Dwarf::CompilationUnit& unit) { auto root = unit.root_die(); parse_scopes_impl(root); }); @@ -102,7 +102,7 @@ void DebugInfo::parse_scopes_impl(const Dwarf::DIE& die) void DebugInfo::prepare_lines() { - auto section = m_elf->image().lookup_section(".debug_line"); + auto section = elf().lookup_section(".debug_line"); if (section.is_undefined()) return; diff --git a/Libraries/LibDebug/DebugInfo.h b/Libraries/LibDebug/DebugInfo.h index cb4fe30b8a..bcb5db3cbc 100644 --- a/Libraries/LibDebug/DebugInfo.h +++ b/Libraries/LibDebug/DebugInfo.h @@ -33,14 +33,16 @@ #include <LibDebug/Dwarf/DIE.h> #include <LibDebug/Dwarf/DwarfInfo.h> #include <LibDebug/Dwarf/LineProgram.h> -#include <LibELF/Loader.h> +#include <LibELF/Image.h> #include <sys/arch/i386/regs.h> namespace Debug { class DebugInfo { public: - explicit DebugInfo(NonnullRefPtr<const ELF::Loader> elf); + explicit DebugInfo(NonnullOwnPtr<const ELF::Image>); + + const ELF::Image& elf() const { return *m_elf; } struct SourcePosition { FlyString file_path; @@ -117,8 +119,8 @@ private: void parse_scopes_impl(const Dwarf::DIE& die); OwnPtr<VariableInfo> create_variable_info(const Dwarf::DIE& variable_die, const PtraceRegisters&) const; - NonnullRefPtr<const ELF::Loader> m_elf; - NonnullRefPtr<Dwarf::DwarfInfo> m_dwarf_info; + NonnullOwnPtr<const ELF::Image> m_elf; + Dwarf::DwarfInfo m_dwarf_info; Vector<VariablesScope> m_scopes; Vector<Dwarf::LineProgram::LineInfo> m_sorted_lines; diff --git a/Libraries/LibDebug/DebugSession.cpp b/Libraries/LibDebug/DebugSession.cpp index 42f1ced66e..27fb35edc9 100644 --- a/Libraries/LibDebug/DebugSession.cpp +++ b/Libraries/LibDebug/DebugSession.cpp @@ -33,8 +33,7 @@ namespace Debug { DebugSession::DebugSession(pid_t pid) : m_debuggee_pid(pid) , m_executable(map_executable_for_process(pid)) - , m_elf(ELF::Loader::create(reinterpret_cast<const u8*>(m_executable.data()), m_executable.size())) - , m_debug_info(m_elf) + , m_debug_info(make<ELF::Image>(reinterpret_cast<const u8*>(m_executable.data()), m_executable.size())) { } diff --git a/Libraries/LibDebug/DebugSession.h b/Libraries/LibDebug/DebugSession.h index 6912eb59dc..ff0c90fab5 100644 --- a/Libraries/LibDebug/DebugSession.h +++ b/Libraries/LibDebug/DebugSession.h @@ -35,7 +35,6 @@ #include <AK/String.h> #include <LibC/sys/arch/i386/regs.h> #include <LibDebug/DebugInfo.h> -#include <LibELF/Loader.h> #include <signal.h> #include <stdio.h> #include <sys/ptrace.h> @@ -99,8 +98,7 @@ public: template<typename Callback> void run(Callback callback); - const ELF::Loader& elf() const { return *m_elf; } - NonnullRefPtr<const ELF::Loader> elf_ref() const { return m_elf; } + const ELF::Image& elf() const { return m_debug_info.elf(); } const MappedFile& executable() const { return m_executable; } const DebugInfo& debug_info() const { return m_debug_info; } @@ -130,7 +128,6 @@ private: bool m_is_debuggee_dead { false }; MappedFile m_executable; - NonnullRefPtr<const ELF::Loader> m_elf; DebugInfo m_debug_info; HashMap<void*, BreakPoint> m_breakpoints; diff --git a/Libraries/LibDebug/Dwarf/DwarfInfo.cpp b/Libraries/LibDebug/Dwarf/DwarfInfo.cpp index c1bd4a39c6..09717cfc71 100644 --- a/Libraries/LibDebug/Dwarf/DwarfInfo.cpp +++ b/Libraries/LibDebug/Dwarf/DwarfInfo.cpp @@ -30,7 +30,7 @@ namespace Debug::Dwarf { -DwarfInfo::DwarfInfo(NonnullRefPtr<const ELF::Loader> elf) +DwarfInfo::DwarfInfo(const ELF::Image& elf) : m_elf(elf) { m_debug_info_data = section_data(".debug_info"); @@ -42,7 +42,7 @@ DwarfInfo::DwarfInfo(NonnullRefPtr<const ELF::Loader> elf) ReadonlyBytes DwarfInfo::section_data(const String& section_name) const { - auto section = m_elf->image().lookup_section(section_name); + auto section = m_elf.lookup_section(section_name); if (section.is_undefined()) return {}; return section.bytes(); diff --git a/Libraries/LibDebug/Dwarf/DwarfInfo.h b/Libraries/LibDebug/Dwarf/DwarfInfo.h index 0a0222a78b..59496e0e3b 100644 --- a/Libraries/LibDebug/Dwarf/DwarfInfo.h +++ b/Libraries/LibDebug/Dwarf/DwarfInfo.h @@ -32,13 +32,13 @@ #include <AK/NonnullRefPtr.h> #include <AK/RefCounted.h> #include <AK/String.h> -#include <LibELF/Loader.h> +#include <LibELF/Image.h> namespace Debug::Dwarf { -class DwarfInfo : public RefCounted<DwarfInfo> { +class DwarfInfo { public: - static NonnullRefPtr<DwarfInfo> create(NonnullRefPtr<const ELF::Loader> elf) { return adopt(*new DwarfInfo(move(elf))); } + explicit DwarfInfo(const ELF::Image&); ReadonlyBytes debug_info_data() const { return m_debug_info_data; } ReadonlyBytes abbreviation_data() const { return m_abbreviation_data; } @@ -48,12 +48,11 @@ public: void for_each_compilation_unit(Callback) const; private: - explicit DwarfInfo(NonnullRefPtr<const ELF::Loader> elf); void populate_compilation_units(); ReadonlyBytes section_data(const String& section_name) const; - NonnullRefPtr<const ELF::Loader> m_elf; + const ELF::Image& m_elf; ReadonlyBytes m_debug_info_data; ReadonlyBytes m_abbreviation_data; ReadonlyBytes m_debug_strings_data; 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 diff --git a/Libraries/LibX86/ELFSymbolProvider.h b/Libraries/LibX86/ELFSymbolProvider.h index 3a9b94a40c..f208cec0a0 100644 --- a/Libraries/LibX86/ELFSymbolProvider.h +++ b/Libraries/LibX86/ELFSymbolProvider.h @@ -26,23 +26,23 @@ #pragma once -#include <LibELF/Loader.h> +#include <LibELF/Image.h> namespace X86 { class ELFSymbolProvider final : public SymbolProvider { public: - ELFSymbolProvider(ELF::Loader& loader) - : m_loader(loader) + ELFSymbolProvider(const ELF::Image& elf) + : m_elf(elf) { } virtual String symbolicate(FlatPtr address, u32* offset = nullptr) const override { - return m_loader.symbolicate(address, offset); + return m_elf.symbolicate(address, offset); } private: - ELF::Loader& m_loader; + const ELF::Image& m_elf; }; } |