require 'evoasm/parameter' module Evoasm module X64 # Represents an x86-64 instruction class Instruction < FFI::Pointer class Parameter < Evoasm::Parameter # Returns the parameter's name # @return [Symbol] the parameter name def name Libevoasm.enum_type(:x64_param_id).find id end end # @return [Symbol] the instruction's name attr_reader :name # @!visibility private def initialize(ptr, name) super(ptr) @name = name end # Gives a list of instruction mnemonics # @return [Array] mnemonics def mnemonics Libevoasm.x64_inst_get_mnem(self).split('/') end # Gives the preferred instruction mnemonic # @return [String] the mnemonics # @see #mnemonics def mnemonic mnemonics.first end # Gives the operand at the specified index # @return [Operand] the operand def operand(index) Operand.new Libevoasm.x64_inst_get_operand(self, index), self end # Gives the instruction's operands # @return [Array] the operands def operands n_operands = Libevoasm.x64_inst_get_n_operands self Array.new(n_operands) do |index| operand index end end # Gives this instruction's parameters # @return [Array] the parameters def parameters n_params = Libevoasm.x64_inst_get_n_params self Array.new(n_params) do |param_index| Parameter.new Libevoasm.x64_inst_get_param(self, param_index) end end # Returns whether this instruction is encodable with the basic encoder # @return [Bool] def basic? Libevoasm.x64_inst_is_basic(self) end # Encodes the instruciton with the given parameters # @param parameters [X64::Parameters] parameters # @param buffer [Buffer] the buffer to emit to # @param basic [Bool] whether the basic encoder should be used # @return [void] def encode(parameters, buffer = nil, basic: false) if basic && !basic? raise ArgumentError, 'instruction does not support basic mode' end buf_ref = Libevoasm.buf_ref_alloc if buffer Libevoasm.buf_to_buf_ref buffer, buf_ref else data = FFI::MemoryPointer.new :uint8, 32 len_ptr = FFI::MemoryPointer.new :size_t, 1 Libevoasm.buf_ref_init buf_ref, data, len_ptr end parameters = Parameters.for(parameters, basic: basic) success = if basic Libevoasm.x64_inst_enc_basic self, parameters, buf_ref else Libevoasm.x64_inst_enc self, parameters, buf_ref end Libevoasm.buf_ref_free buf_ref if success unless buffer len = len_ptr.read_size_t data.read_string len end else raise Error.last end end end end end