diff --git a/Libraries/LibX86/Instruction.cpp b/Libraries/LibX86/Instruction.cpp index 62af881c75..fae720f2bd 100644 --- a/Libraries/LibX86/Instruction.cpp +++ b/Libraries/LibX86/Instruction.cpp @@ -1253,7 +1253,7 @@ static String relative_address(u32 origin, bool x32, i32 imm) return String::format("%#04x", w + si); } -String Instruction::to_string(u32 origin, bool x32) const +String Instruction::to_string(u32 origin, const SymbolProvider* symbol_provider, bool x32) const { String segment_prefix; String asize_prefix; @@ -1281,11 +1281,11 @@ String Instruction::to_string(u32 origin, bool x32) const builder.append(osize_prefix); builder.append(lock_prefix); builder.append(rep_prefix); - builder.append(to_string_internal(origin, x32)); + builder.append(to_string_internal(origin, symbol_provider, x32)); return builder.to_string(); } -String Instruction::to_string_internal(u32 origin, bool x32) const +String Instruction::to_string_internal(u32 origin, const SymbolProvider* symbol_provider, bool x32) const { if (!m_descriptor) return String::format("db %#02x", m_op); @@ -1297,6 +1297,21 @@ String Instruction::to_string_internal(u32 origin, bool x32) const builder.append(mnemonic); builder.append(' '); + auto formatted_address = [&](FlatPtr origin, bool x32, auto offset) { + StringBuilder builder; + builder.append(relative_address(origin, x32, offset)); + if (symbol_provider) { + u32 symbol_offset = 0; + auto symbol = symbol_provider->symbolicate(origin + offset, &symbol_offset); + builder.append(" <"); + builder.append(symbol); + if (symbol_offset) + builder.appendf("+%u", symbol_offset); + builder.append('>'); + } + return builder.to_string(); + }; + auto append_rm8 = [&] { builder.append(m_modrm.to_string_o8()); }; auto append_rm16 = [&] { builder.append(m_modrm.to_string_o16()); }; auto append_rm32 = [&] { builder.append(m_modrm.to_string_o32()); }; @@ -1313,10 +1328,10 @@ String Instruction::to_string_internal(u32 origin, bool x32) const auto append_seg = [&] { builder.append(register_name(segment_register())); }; auto append_creg = [&] { builder.appendf("cr%u", register_index()); }; auto append_dreg = [&] { builder.appendf("dr%u", register_index()); }; - auto append_relative_addr = [&] { builder.append(relative_address(origin + (m_a32 ? 6 : 4), x32, i32(m_a32 ? imm32() : imm16()))); }; - auto append_relative_imm8 = [&] { builder.append(relative_address(origin + 2, x32, i8(imm8()))); }; - auto append_relative_imm16 = [&] { builder.append(relative_address(origin + 3, x32, i16(imm16()))); }; - auto append_relative_imm32 = [&] { builder.append(relative_address(origin + 5, x32, i32(imm32()))); }; + auto append_relative_addr = [&] { builder.append(formatted_address(origin + (m_a32 ? 6 : 4), x32, i32(m_a32 ? imm32() : imm16()))); }; + auto append_relative_imm8 = [&] { builder.append(formatted_address(origin + 2, x32, i8(imm8()))); }; + auto append_relative_imm16 = [&] { builder.append(formatted_address(origin + 3, x32, i16(imm16()))); }; + auto append_relative_imm32 = [&] { builder.append(formatted_address(origin + 5, x32, i32(imm32()))); }; auto append_mm = [&] { builder.appendf("mm%u", register_index()); }; auto append_mmrm64 = [&] { builder.append(m_modrm.to_string_mm()); }; diff --git a/Libraries/LibX86/Instruction.h b/Libraries/LibX86/Instruction.h index b1bd8098ca..7d6b8a9ba1 100644 --- a/Libraries/LibX86/Instruction.h +++ b/Libraries/LibX86/Instruction.h @@ -34,6 +34,11 @@ namespace X86 { class Instruction; struct InstructionDescriptor; +class SymbolProvider { +public: + virtual String symbolicate(FlatPtr, u32* offset = nullptr) const = 0; +}; + template struct MakeUnsigned { typedef T type; @@ -333,12 +338,12 @@ public: u8 cc() const { return m_has_sub_op ? m_sub_op & 0xf : m_op & 0xf; } - String to_string(u32 origin, bool x32 = true) const; + String to_string(u32 origin, const SymbolProvider* = nullptr, bool x32 = true) const; private: Instruction(InstructionStream&, bool o32, bool a32); - String to_string_internal(u32 origin, bool x32) const; + String to_string_internal(u32 origin, const SymbolProvider*, bool x32) const; const char* reg8_name() const; const char* reg16_name() const;