mirror of
https://github.com/SerenityOS/serenity.git
synced 2026-11-07 04:29:30 -10:00
LibDisassembly: Split existing generic interfaces from x86-specific code
InstructionStream, SymbolProvider and Disassembler are already generic interfaces, so we can separate those from the x86-specific code. The x86-specific code is moved to a new x86 subdirectory, which will be accompanied by other architecture-specific directories soon.
This commit is contained in:
1 parent
881681580a
commit
e222d2cb8e
15 files changed
+121
-91
No files matched your search
@@ -16,7 +16,7 @@
|
||||
#include <LibDebug/DebugInfo.h>
|
||||
#include <LibDebug/DebugSession.h>
|
||||
#include <LibDisassembly/Disassembler.h>
|
||||
#include <LibDisassembly/Instruction.h>
|
||||
#include <LibDisassembly/x86/Instruction.h>
|
||||
#include <LibLine/Editor.h>
|
||||
#include <LibMain/Main.h>
|
||||
#include <signal.h>
|
||||
@@ -82,8 +82,8 @@ static bool handle_disassemble_command(ByteString const& command, FlatPtr first_
|
||||
break;
|
||||
}
|
||||
|
||||
Disassembly::X86::SimpleInstructionStream stream(code.data(), code.size());
|
||||
Disassembly::X86::Disassembler disassembler(stream);
|
||||
Disassembly::SimpleInstructionStream stream(code.data(), code.size());
|
||||
Disassembly::Disassembler disassembler(stream);
|
||||
|
||||
for (size_t i = 0; i < number_of_instructions_to_disassemble; ++i) {
|
||||
auto offset = stream.offset();
|
||||
|
||||
@@ -50,9 +50,9 @@ DisassemblyModel::DisassemblyModel(Debug::DebugSession const& debug_session, Ptr
|
||||
|
||||
auto view = symbol.value().raw_data();
|
||||
|
||||
Disassembly::X86::ELFSymbolProvider symbol_provider(*elf);
|
||||
Disassembly::X86::SimpleInstructionStream stream((u8 const*)view.characters_without_null_termination(), view.length());
|
||||
Disassembly::X86::Disassembler disassembler(stream);
|
||||
Disassembly::ELFSymbolProvider symbol_provider(*elf);
|
||||
Disassembly::SimpleInstructionStream stream((u8 const*)view.characters_without_null_termination(), view.length());
|
||||
Disassembly::Disassembler disassembler(stream);
|
||||
|
||||
size_t offset_into_symbol = 0;
|
||||
for (;;) {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AK/Vector.h>
|
||||
#include <LibDisassembly/Instruction.h>
|
||||
#include <LibDisassembly/x86/Instruction.h>
|
||||
#include <LibGUI/Model.h>
|
||||
#include <sys/arch/regs.h>
|
||||
|
||||
|
||||
@@ -93,9 +93,9 @@ DisassemblyModel::DisassemblyModel(Profile& profile, ProfileNode& node)
|
||||
auto symbol_offset_from_function_start = node.address() - base_address - symbol->value();
|
||||
auto view = symbol.value().raw_data().substring_view(symbol_offset_from_function_start);
|
||||
|
||||
Disassembly::X86::ELFSymbolProvider symbol_provider(*elf, base_address);
|
||||
Disassembly::X86::SimpleInstructionStream stream((u8 const*)view.characters_without_null_termination(), view.length());
|
||||
Disassembly::X86::Disassembler disassembler(stream);
|
||||
Disassembly::ELFSymbolProvider symbol_provider(*elf, base_address);
|
||||
Disassembly::SimpleInstructionStream stream((u8 const*)view.characters_without_null_termination(), view.length());
|
||||
Disassembly::Disassembler disassembler(stream);
|
||||
|
||||
size_t offset_into_symbol = 0;
|
||||
FlatPtr last_instruction_offset = 0;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <LibDebug/DebugInfo.h>
|
||||
#include <LibDisassembly/Instruction.h>
|
||||
#include <LibDisassembly/x86/Instruction.h>
|
||||
#include <LibGUI/Model.h>
|
||||
|
||||
namespace Profiler {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
set(SOURCES
|
||||
Instruction.cpp
|
||||
x86/Instruction.cpp
|
||||
)
|
||||
|
||||
serenity_lib(LibDisassembly disassembly)
|
||||
@@ -7,9 +7,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <AK/Optional.h>
|
||||
#include <LibDisassembly/Instruction.h>
|
||||
#include <LibDisassembly/InstructionStream.h>
|
||||
#include <LibDisassembly/x86/Instruction.h>
|
||||
|
||||
namespace Disassembly::X86 {
|
||||
namespace Disassembly {
|
||||
|
||||
class Disassembler {
|
||||
public:
|
||||
@@ -18,12 +19,12 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
Optional<Instruction> next()
|
||||
Optional<X86::Instruction> next()
|
||||
{
|
||||
if (!m_stream.can_read())
|
||||
return {};
|
||||
#if ARCH(X86_64)
|
||||
return Instruction::from_stream(m_stream, ProcessorMode::Long);
|
||||
return X86::Instruction::from_stream(m_stream, X86::ProcessorMode::Long);
|
||||
#else
|
||||
dbgln("Unsupported platform");
|
||||
return {};
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibDisassembly/Instruction.h>
|
||||
#include <LibDisassembly/SymbolProvider.h>
|
||||
#include <LibDisassembly/x86/Instruction.h>
|
||||
#include <LibELF/Image.h>
|
||||
|
||||
namespace Disassembly::X86 {
|
||||
namespace Disassembly {
|
||||
|
||||
class ELFSymbolProvider final : public SymbolProvider {
|
||||
public:
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2023, kleines Filmröllchen <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Types.h>
|
||||
|
||||
namespace Disassembly {
|
||||
|
||||
class InstructionStream {
|
||||
public:
|
||||
virtual bool can_read() = 0;
|
||||
virtual u8 read8() = 0;
|
||||
virtual u16 read16() = 0;
|
||||
virtual u32 read32() = 0;
|
||||
virtual u64 read64() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~InstructionStream() = default;
|
||||
};
|
||||
|
||||
class SimpleInstructionStream final : public InstructionStream {
|
||||
public:
|
||||
SimpleInstructionStream(u8 const* data, size_t size)
|
||||
: m_data(data)
|
||||
, m_size(size)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool can_read() override { return m_offset < m_size; }
|
||||
|
||||
virtual u8 read8() override
|
||||
{
|
||||
if (!can_read())
|
||||
return 0;
|
||||
return m_data[m_offset++];
|
||||
}
|
||||
virtual u16 read16() override
|
||||
{
|
||||
u8 lsb = read8();
|
||||
u8 msb = read8();
|
||||
return ((u16)msb << 8) | (u16)lsb;
|
||||
}
|
||||
|
||||
virtual u32 read32() override
|
||||
{
|
||||
u16 lsw = read16();
|
||||
u16 msw = read16();
|
||||
return ((u32)msw << 16) | (u32)lsw;
|
||||
}
|
||||
|
||||
virtual u64 read64() override
|
||||
{
|
||||
u32 lsw = read32();
|
||||
u32 msw = read32();
|
||||
return ((u64)msw << 32) | (u64)lsw;
|
||||
}
|
||||
size_t offset() const { return m_offset; }
|
||||
|
||||
private:
|
||||
u8 const* m_data { nullptr };
|
||||
size_t m_offset { 0 };
|
||||
size_t m_size { 0 };
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2023, kleines Filmröllchen <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/ByteString.h>
|
||||
#include <AK/Types.h>
|
||||
|
||||
namespace Disassembly {
|
||||
|
||||
class SymbolProvider {
|
||||
public:
|
||||
virtual ByteString symbolicate(FlatPtr, u32* offset = nullptr) const = 0;
|
||||
|
||||
protected:
|
||||
virtual ~SymbolProvider() = default;
|
||||
};
|
||||
|
||||
}
|
||||
+2
-2
@@ -6,8 +6,8 @@
|
||||
*/
|
||||
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibDisassembly/Instruction.h>
|
||||
#include <LibDisassembly/Interpreter.h>
|
||||
#include <LibDisassembly/x86/Instruction.h>
|
||||
#include <LibDisassembly/x86/Interpreter.h>
|
||||
|
||||
#if defined(AK_COMPILER_GCC)
|
||||
# pragma GCC optimize("O3")
|
||||
+1
-64
@@ -11,6 +11,7 @@
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
#include <AK/Types.h>
|
||||
#include <LibDisassembly/SymbolProvider.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace Disassembly::X86 {
|
||||
@@ -19,14 +20,6 @@ class Instruction;
|
||||
class Interpreter;
|
||||
typedef void (Interpreter::*InstructionHandler)(Instruction const&);
|
||||
|
||||
class SymbolProvider {
|
||||
public:
|
||||
virtual ByteString symbolicate(FlatPtr, u32* offset = nullptr) const = 0;
|
||||
|
||||
protected:
|
||||
virtual ~SymbolProvider() = default;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct TypeTrivia {
|
||||
static constexpr size_t bits = sizeof(T) * 8;
|
||||
@@ -459,62 +452,6 @@ private:
|
||||
FlatPtr m_offset { 0 };
|
||||
};
|
||||
|
||||
class InstructionStream {
|
||||
public:
|
||||
virtual bool can_read() = 0;
|
||||
virtual u8 read8() = 0;
|
||||
virtual u16 read16() = 0;
|
||||
virtual u32 read32() = 0;
|
||||
virtual u64 read64() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~InstructionStream() = default;
|
||||
};
|
||||
|
||||
class SimpleInstructionStream final : public InstructionStream {
|
||||
public:
|
||||
SimpleInstructionStream(u8 const* data, size_t size)
|
||||
: m_data(data)
|
||||
, m_size(size)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool can_read() override { return m_offset < m_size; }
|
||||
|
||||
virtual u8 read8() override
|
||||
{
|
||||
if (!can_read())
|
||||
return 0;
|
||||
return m_data[m_offset++];
|
||||
}
|
||||
virtual u16 read16() override
|
||||
{
|
||||
u8 lsb = read8();
|
||||
u8 msb = read8();
|
||||
return ((u16)msb << 8) | (u16)lsb;
|
||||
}
|
||||
|
||||
virtual u32 read32() override
|
||||
{
|
||||
u16 lsw = read16();
|
||||
u16 msw = read16();
|
||||
return ((u32)msw << 16) | (u32)lsw;
|
||||
}
|
||||
|
||||
virtual u64 read64() override
|
||||
{
|
||||
u32 lsw = read32();
|
||||
u32 msw = read32();
|
||||
return ((u64)msw << 32) | (u64)lsw;
|
||||
}
|
||||
size_t offset() const { return m_offset; }
|
||||
|
||||
private:
|
||||
u8 const* m_data { nullptr };
|
||||
size_t m_offset { 0 };
|
||||
size_t m_size { 0 };
|
||||
};
|
||||
|
||||
class MemoryOrRegisterReference {
|
||||
friend class Instruction;
|
||||
|
||||
File renamed without changes.
@@ -67,12 +67,12 @@ ErrorOr<int> serenity_main(Main::Arguments args)
|
||||
Vector<Symbol> zero_size_symbols;
|
||||
|
||||
size_t file_offset = 0;
|
||||
OwnPtr<Disassembly::X86::ELFSymbolProvider> symbol_provider; // nullptr for non-ELF disassembly.
|
||||
OwnPtr<Disassembly::ELFSymbolProvider> symbol_provider; // nullptr for non-ELF disassembly.
|
||||
OwnPtr<ELF::Image> elf;
|
||||
if (asm_size >= 4 && strncmp(reinterpret_cast<char const*>(asm_data), "\u007fELF", 4) == 0) {
|
||||
elf = make<ELF::Image>(asm_data, asm_size);
|
||||
if (elf->is_valid()) {
|
||||
symbol_provider = make<Disassembly::X86::ELFSymbolProvider>(*elf);
|
||||
symbol_provider = make<Disassembly::ELFSymbolProvider>(*elf);
|
||||
elf->for_each_section_of_type(SHT_PROGBITS, [&](ELF::Image::Section const& section) {
|
||||
// FIXME: Disassemble all SHT_PROGBITS sections, not just .text.
|
||||
if (section.name() != ".text")
|
||||
@@ -116,8 +116,8 @@ ErrorOr<int> serenity_main(Main::Arguments args)
|
||||
}
|
||||
}
|
||||
|
||||
Disassembly::X86::SimpleInstructionStream stream(asm_data, asm_size);
|
||||
Disassembly::X86::Disassembler disassembler(stream);
|
||||
Disassembly::SimpleInstructionStream stream(asm_data, asm_size);
|
||||
Disassembly::Disassembler disassembler(stream);
|
||||
|
||||
Vector<Symbol>::Iterator current_ranged_symbol = ranged_symbols.begin();
|
||||
Vector<Symbol>::Iterator current_zero_size_symbol = zero_size_symbols.begin();
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <LibCore/System.h>
|
||||
#include <LibDebug/DebugSession.h>
|
||||
#include <LibDisassembly/Disassembler.h>
|
||||
#include <LibDisassembly/Instruction.h>
|
||||
#include <LibDisassembly/x86/Instruction.h>
|
||||
#include <LibELF/Image.h>
|
||||
#include <LibMain/Main.h>
|
||||
#include <signal.h>
|
||||
@@ -83,8 +83,8 @@ static NonnullOwnPtr<HashMap<FlatPtr, Disassembly::X86::Instruction>> instrument
|
||||
if (section.name() != ".text")
|
||||
return IterationDecision::Continue;
|
||||
|
||||
Disassembly::X86::SimpleInstructionStream stream((u8 const*)((uintptr_t)lib.file->data() + section.offset()), section.size());
|
||||
Disassembly::X86::Disassembler disassembler(stream);
|
||||
Disassembly::SimpleInstructionStream stream((u8 const*)((uintptr_t)lib.file->data() + section.offset()), section.size());
|
||||
Disassembly::Disassembler disassembler(stream);
|
||||
for (;;) {
|
||||
auto offset = stream.offset();
|
||||
auto instruction_address = section.address() + offset + lib.base_address;
|
||||
|
||||
Reference in new issue
Block a user