Linux Audio

Check our new training course

Loading...
  1#!/usr/bin/env python
  2# SPDX-License-Identifier: GPL-2.0
  3# libxed.py: Python wrapper for libxed.so
  4# Copyright (c) 2014-2021, Intel Corporation.
  5
  6# To use Intel XED, libxed.so must be present. To build and install
  7# libxed.so:
  8#            git clone https://github.com/intelxed/mbuild.git mbuild
  9#            git clone https://github.com/intelxed/xed
 10#            cd xed
 11#            ./mfile.py --share
 12#            sudo ./mfile.py --prefix=/usr/local install
 13#            sudo ldconfig
 14#
 15
 16import sys
 17
 18from ctypes import CDLL, Structure, create_string_buffer, addressof, sizeof, \
 19		   c_void_p, c_bool, c_byte, c_char, c_int, c_uint, c_longlong, c_ulonglong
 20
 21# XED Disassembler
 22
 23class xed_state_t(Structure):
 24
 25	_fields_ = [
 26		("mode", c_int),
 27		("width", c_int)
 28	]
 29
 30class XEDInstruction():
 31
 32	def __init__(self, libxed):
 33		# Current xed_decoded_inst_t structure is 192 bytes. Use 512 to allow for future expansion
 34		xedd_t = c_byte * 512
 35		self.xedd = xedd_t()
 36		self.xedp = addressof(self.xedd)
 37		libxed.xed_decoded_inst_zero(self.xedp)
 38		self.state = xed_state_t()
 39		self.statep = addressof(self.state)
 40		# Buffer for disassembled instruction text
 41		self.buffer = create_string_buffer(256)
 42		self.bufferp = addressof(self.buffer)
 43
 44class LibXED():
 45
 46	def __init__(self):
 47		try:
 48			self.libxed = CDLL("libxed.so")
 49		except:
 50			self.libxed = None
 51		if not self.libxed:
 52			self.libxed = CDLL("/usr/local/lib/libxed.so")
 53
 54		self.xed_tables_init = self.libxed.xed_tables_init
 55		self.xed_tables_init.restype = None
 56		self.xed_tables_init.argtypes = []
 57
 58		self.xed_decoded_inst_zero = self.libxed.xed_decoded_inst_zero
 59		self.xed_decoded_inst_zero.restype = None
 60		self.xed_decoded_inst_zero.argtypes = [ c_void_p ]
 61
 62		self.xed_operand_values_set_mode = self.libxed.xed_operand_values_set_mode
 63		self.xed_operand_values_set_mode.restype = None
 64		self.xed_operand_values_set_mode.argtypes = [ c_void_p, c_void_p ]
 65
 66		self.xed_decoded_inst_zero_keep_mode = self.libxed.xed_decoded_inst_zero_keep_mode
 67		self.xed_decoded_inst_zero_keep_mode.restype = None
 68		self.xed_decoded_inst_zero_keep_mode.argtypes = [ c_void_p ]
 69
 70		self.xed_decode = self.libxed.xed_decode
 71		self.xed_decode.restype = c_int
 72		self.xed_decode.argtypes = [ c_void_p, c_void_p, c_uint ]
 73
 74		self.xed_format_context = self.libxed.xed_format_context
 75		self.xed_format_context.restype = c_uint
 76		self.xed_format_context.argtypes = [ c_int, c_void_p, c_void_p, c_int, c_ulonglong, c_void_p, c_void_p ]
 77
 78		self.xed_tables_init()
 79
 80	def Instruction(self):
 81		return XEDInstruction(self)
 82
 83	def SetMode(self, inst, mode):
 84		if mode:
 85			inst.state.mode = 4 # 32-bit
 86			inst.state.width = 4 # 4 bytes
 87		else:
 88			inst.state.mode = 1 # 64-bit
 89			inst.state.width = 8 # 8 bytes
 90		self.xed_operand_values_set_mode(inst.xedp, inst.statep)
 91
 92	def DisassembleOne(self, inst, bytes_ptr, bytes_cnt, ip):
 93		self.xed_decoded_inst_zero_keep_mode(inst.xedp)
 94		err = self.xed_decode(inst.xedp, bytes_ptr, bytes_cnt)
 95		if err:
 96			return 0, ""
 97		# Use AT&T mode (2), alternative is Intel (3)
 98		ok = self.xed_format_context(2, inst.xedp, inst.bufferp, sizeof(inst.buffer), ip, 0, 0)
 99		if not ok:
100			return 0, ""
101		if sys.version_info[0] == 2:
102			result = inst.buffer.value
103		else:
104			result = inst.buffer.value.decode()
105		# Return instruction length and the disassembled instruction text
106		# For now, assume the length is in byte 166
107		return inst.xedd[166], result