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
8 # git clone https://github.com/intelxed/mbuild.git mbuild
9 # git clone https://github.com/intelxed/xed
12 # sudo ./mfile.py --prefix=/usr/local install
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
23 class xed_state_t(Structure
):
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
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)
48 self
.libxed
= CDLL("libxed.so")
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
):
85 inst
.state
.mode
= 4 # 32-bit
86 inst
.state
.width
= 4 # 4 bytes
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
)
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)
101 if sys
.version_info
[0] == 2:
102 result
= inst
.buffer.value
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