forked from mirrors/linux
		
	 2b87386c7a
			
		
	
	
		2b87386c7a
		
	
	
	
	
		
			
			Factor out libxed.py so it can be reused. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: https://lore.kernel.org/r/20210530192308.7382-13-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
		
			
				
	
	
		
			107 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			107 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/env python
 | |
| # SPDX-License-Identifier: GPL-2.0
 | |
| # libxed.py: Python wrapper for libxed.so
 | |
| # Copyright (c) 2014-2021, Intel Corporation.
 | |
| 
 | |
| # To use Intel XED, libxed.so must be present. To build and install
 | |
| # libxed.so:
 | |
| #            git clone https://github.com/intelxed/mbuild.git mbuild
 | |
| #            git clone https://github.com/intelxed/xed
 | |
| #            cd xed
 | |
| #            ./mfile.py --share
 | |
| #            sudo ./mfile.py --prefix=/usr/local install
 | |
| #            sudo ldconfig
 | |
| #
 | |
| 
 | |
| import sys
 | |
| 
 | |
| from ctypes import CDLL, Structure, create_string_buffer, addressof, sizeof, \
 | |
| 		   c_void_p, c_bool, c_byte, c_char, c_int, c_uint, c_longlong, c_ulonglong
 | |
| 
 | |
| # XED Disassembler
 | |
| 
 | |
| class xed_state_t(Structure):
 | |
| 
 | |
| 	_fields_ = [
 | |
| 		("mode", c_int),
 | |
| 		("width", c_int)
 | |
| 	]
 | |
| 
 | |
| class XEDInstruction():
 | |
| 
 | |
| 	def __init__(self, libxed):
 | |
| 		# Current xed_decoded_inst_t structure is 192 bytes. Use 512 to allow for future expansion
 | |
| 		xedd_t = c_byte * 512
 | |
| 		self.xedd = xedd_t()
 | |
| 		self.xedp = addressof(self.xedd)
 | |
| 		libxed.xed_decoded_inst_zero(self.xedp)
 | |
| 		self.state = xed_state_t()
 | |
| 		self.statep = addressof(self.state)
 | |
| 		# Buffer for disassembled instruction text
 | |
| 		self.buffer = create_string_buffer(256)
 | |
| 		self.bufferp = addressof(self.buffer)
 | |
| 
 | |
| class LibXED():
 | |
| 
 | |
| 	def __init__(self):
 | |
| 		try:
 | |
| 			self.libxed = CDLL("libxed.so")
 | |
| 		except:
 | |
| 			self.libxed = None
 | |
| 		if not self.libxed:
 | |
| 			self.libxed = CDLL("/usr/local/lib/libxed.so")
 | |
| 
 | |
| 		self.xed_tables_init = self.libxed.xed_tables_init
 | |
| 		self.xed_tables_init.restype = None
 | |
| 		self.xed_tables_init.argtypes = []
 | |
| 
 | |
| 		self.xed_decoded_inst_zero = self.libxed.xed_decoded_inst_zero
 | |
| 		self.xed_decoded_inst_zero.restype = None
 | |
| 		self.xed_decoded_inst_zero.argtypes = [ c_void_p ]
 | |
| 
 | |
| 		self.xed_operand_values_set_mode = self.libxed.xed_operand_values_set_mode
 | |
| 		self.xed_operand_values_set_mode.restype = None
 | |
| 		self.xed_operand_values_set_mode.argtypes = [ c_void_p, c_void_p ]
 | |
| 
 | |
| 		self.xed_decoded_inst_zero_keep_mode = self.libxed.xed_decoded_inst_zero_keep_mode
 | |
| 		self.xed_decoded_inst_zero_keep_mode.restype = None
 | |
| 		self.xed_decoded_inst_zero_keep_mode.argtypes = [ c_void_p ]
 | |
| 
 | |
| 		self.xed_decode = self.libxed.xed_decode
 | |
| 		self.xed_decode.restype = c_int
 | |
| 		self.xed_decode.argtypes = [ c_void_p, c_void_p, c_uint ]
 | |
| 
 | |
| 		self.xed_format_context = self.libxed.xed_format_context
 | |
| 		self.xed_format_context.restype = c_uint
 | |
| 		self.xed_format_context.argtypes = [ c_int, c_void_p, c_void_p, c_int, c_ulonglong, c_void_p, c_void_p ]
 | |
| 
 | |
| 		self.xed_tables_init()
 | |
| 
 | |
| 	def Instruction(self):
 | |
| 		return XEDInstruction(self)
 | |
| 
 | |
| 	def SetMode(self, inst, mode):
 | |
| 		if mode:
 | |
| 			inst.state.mode = 4 # 32-bit
 | |
| 			inst.state.width = 4 # 4 bytes
 | |
| 		else:
 | |
| 			inst.state.mode = 1 # 64-bit
 | |
| 			inst.state.width = 8 # 8 bytes
 | |
| 		self.xed_operand_values_set_mode(inst.xedp, inst.statep)
 | |
| 
 | |
| 	def DisassembleOne(self, inst, bytes_ptr, bytes_cnt, ip):
 | |
| 		self.xed_decoded_inst_zero_keep_mode(inst.xedp)
 | |
| 		err = self.xed_decode(inst.xedp, bytes_ptr, bytes_cnt)
 | |
| 		if err:
 | |
| 			return 0, ""
 | |
| 		# Use AT&T mode (2), alternative is Intel (3)
 | |
| 		ok = self.xed_format_context(2, inst.xedp, inst.bufferp, sizeof(inst.buffer), ip, 0, 0)
 | |
| 		if not ok:
 | |
| 			return 0, ""
 | |
| 		if sys.version_info[0] == 2:
 | |
| 			result = inst.buffer.value
 | |
| 		else:
 | |
| 			result = inst.buffer.value.decode()
 | |
| 		# Return instruction length and the disassembled instruction text
 | |
| 		# For now, assume the length is in byte 166
 | |
| 		return inst.xedd[166], result
 |