perf scripting python: exported-sql-viewer.py: Factor out libxed.py
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>
This commit is contained in:
parent
1a329b1c8e
commit
2b87386c7a
@ -113,6 +113,7 @@ import os
|
||||
import random
|
||||
import copy
|
||||
import math
|
||||
from libxed import LibXED
|
||||
|
||||
pyside_version_1 = True
|
||||
if not "--pyside-version-1" in sys.argv:
|
||||
@ -4747,94 +4748,6 @@ class MainWindow(QMainWindow):
|
||||
dialog = AboutDialog(self.glb, self)
|
||||
dialog.exec_()
|
||||
|
||||
# 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
|
||||
|
||||
def TryOpen(file_name):
|
||||
try:
|
||||
return open(file_name, "rb")
|
||||
|
107
tools/perf/scripts/python/libxed.py
Normal file
107
tools/perf/scripts/python/libxed.py
Normal file
@ -0,0 +1,107 @@
|
||||
#!/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
|
Loading…
Reference in New Issue
Block a user