Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / tools / perf / scripts / python / libxed.py
blob2c70a5a7eb9cff643a4e3e09d4651f227f0dc4f1
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.
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
16 import sys
18 from 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
21 # XED Disassembler
23 class xed_state_t(Structure):
25 _fields_ = [
26 ("mode", c_int),
27 ("width", c_int)
30 class XEDInstruction():
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)
44 class LibXED():
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")
54 self.xed_tables_init = self.libxed.xed_tables_init
55 self.xed_tables_init.restype = None
56 self.xed_tables_init.argtypes = []
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 ]
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 ]
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 ]
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 ]
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 ]
78 self.xed_tables_init()
80 def Instruction(self):
81 return XEDInstruction(self)
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)
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