mirror of
https://github.com/cemu-project/idapython.git
synced 2024-11-24 01:59:18 +01:00
IDA Pro 6.5 support
What's new: - Proper multi-threaded support - Better PyObject reference counting with ref_t and newref_t helper classes - Improved the pywraps/deployment script - Added IDAViewWrapper class and example - Added idc.GetDisasmEx() - Added idc.AddSegEx() - Added idc.GetLocalTinfo() - Added idc.ApplyType() - Updated type information implementation - Introduced the idaapi.require() - see http://www.hexblog.com/?p=749 - set REMOVE_CWD_SYS_PATH=1 by default in python.cfg (remove current directory from the import search path). Various bugfixes: - fixed various memory leaks - asklong/askaddr/asksel (and corresponding idc.py functions) were returning results truncated to 32 bits in IDA64 - fix wrong documentation for idc.SizeOf - GetFloat/GetDouble functions did not take into account endianness of the processor - idaapi.NO_PROCESS was not defined, and was causing GetProcessPid() to fail - idc.py: insert escape characters to string parameter when call Eval() - idc.SaveFile/savefile were always overwriting an existing file instead of writing only the new data - PluginForm.Close() wasn't passing its arguments to the delegate function, resulting in an error.
This commit is contained in:
parent
c88a77e809
commit
78c79f85b9
@ -8,8 +8,11 @@ The IDAPython Team:
|
||||
* Hex-Rays - http://www.hex-rays.com/ - <support@hex-rays.com>
|
||||
|
||||
Hex-Rays joined the IDAPython project in September 2009 and started contributing.
|
||||
It is primarily maintained by Elias Bachaalany.
|
||||
It is primarily maintained by Arnaud Diederen.
|
||||
|
||||
* Elias Bachaalany - http://0xeb.wordpress.com/
|
||||
|
||||
Current project owner and maintainer
|
||||
|
||||
* Ero Carrera - http://dkbza.org/
|
||||
|
||||
|
91
Scripts/callstack_test.py
Normal file
91
Scripts/callstack_test.py
Normal file
@ -0,0 +1,91 @@
|
||||
import sys
|
||||
import os
|
||||
|
||||
def __sys(cmd, fmt=None, echo=True):
|
||||
"""Executes a string of OS commands and returns the a list of tuples (return code,command executed)"""
|
||||
if not fmt:
|
||||
fmt = {}
|
||||
r = []
|
||||
for cmd in [x for x in (cmd % fmt).split("\n") if len(x)]:
|
||||
if echo:
|
||||
print ">>>", cmd
|
||||
r.append((os.system(cmd), cmd))
|
||||
return r
|
||||
|
||||
body = r"""/// Autogenerated file
|
||||
#include <stdio.h>
|
||||
#include <conio.h>
|
||||
#include <ctype.h>
|
||||
#include <windows.h>
|
||||
|
||||
void want_break(int n)
|
||||
{
|
||||
printf("do you want to DebugBreak in func%d()?", n);
|
||||
char ch = _toupper(_getch());
|
||||
printf("\n");
|
||||
if (ch == 'Y')
|
||||
DebugBreak();
|
||||
else if (ch == 'X')
|
||||
ExitProcess(n);
|
||||
}
|
||||
%FUNCS%
|
||||
int main(int /*argc*/, char * /*argv[]*/)
|
||||
{
|
||||
func1();
|
||||
return 0;
|
||||
}
|
||||
"""
|
||||
|
||||
funcs_body = []
|
||||
|
||||
func_body = r"""
|
||||
void func%(n)d()
|
||||
{
|
||||
printf("%(ident)senter %(n)d\n");%(pause)s
|
||||
func%(n1)d();
|
||||
printf("%(ident)sleave %(n)d\n");
|
||||
}
|
||||
"""
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print "usage: gen nb_calls pause_frequency"
|
||||
sys.exit(0)
|
||||
|
||||
n = int(sys.argv[1])
|
||||
if n < 1:
|
||||
print "at least one call should be passed!"
|
||||
sys.exit(1)
|
||||
|
||||
m = int(sys.argv[2])
|
||||
|
||||
func_params = {'n': 0, 'n1': 0, 'ident': '', 'pause' : ''}
|
||||
|
||||
for i in xrange(1, n + 1):
|
||||
func_params['n'] = i
|
||||
func_params['n1'] = i+1
|
||||
func_params['ident'] = " " * i
|
||||
func_params['pause'] = ("\n want_break(%d);" % i) if (i % m) == 0 else ''
|
||||
|
||||
funcs_body.append(func_body % func_params)
|
||||
funcs_body.append(r"""
|
||||
void func%(n)d()
|
||||
{
|
||||
printf("that's it #%(n)d!\n");
|
||||
}
|
||||
""" % {'n':i+1})
|
||||
funcs_body.reverse()
|
||||
|
||||
# write the file
|
||||
body = body.replace('%FUNCS%', ''.join(funcs_body))
|
||||
f = file('src.cpp', 'w')
|
||||
f.write(body)
|
||||
f.close()
|
||||
|
||||
|
||||
__sys("""
|
||||
if exist src.exe del src.exe
|
||||
bcc32 src
|
||||
if exist src.exe move src.exe src_bcc.exe
|
||||
if exist src.obj del src.obj
|
||||
cl32 src.cpp /Zi /Od
|
||||
""")
|
28
build.py
28
build.py
@ -24,7 +24,7 @@ from distutils import sysconfig
|
||||
VERBOSE = True
|
||||
|
||||
IDA_MAJOR_VERSION = 6
|
||||
IDA_MINOR_VERSION = 4
|
||||
IDA_MINOR_VERSION = 5
|
||||
|
||||
if 'IDA' in os.environ:
|
||||
IDA_SDK = os.environ['IDA']
|
||||
@ -35,8 +35,8 @@ else:
|
||||
|
||||
# IDAPython version
|
||||
VERSION_MAJOR = 1
|
||||
VERSION_MINOR = 5
|
||||
VERSION_PATCH = 6
|
||||
VERSION_MINOR = 6
|
||||
VERSION_PATCH = 0
|
||||
|
||||
# Determine Python version
|
||||
PYTHON_MAJOR_VERSION = int(platform.python_version()[0])
|
||||
@ -50,7 +50,7 @@ S_WITH_HEXRAYS = 'with-hexrays'
|
||||
S_NO_OPT = 'no-opt'
|
||||
|
||||
# Swig command-line parameters
|
||||
SWIG_OPTIONS = '-modern -python -c++ -w451 -shadow -D__GNUC__ -DNO_OBSOLETE_FUNCS'
|
||||
SWIG_OPTIONS = '-modern -python -threads -c++ -w451 -shadow -D__GNUC__'
|
||||
|
||||
# Common macros for all compilations
|
||||
COMMON_MACROS = [
|
||||
@ -169,8 +169,8 @@ def parse_options(args):
|
||||
with_hexrays = '--' + S_WITH_HEXRAYS in sys.argv
|
||||
|
||||
return {
|
||||
S_EA64: ea64,
|
||||
S_WITH_HEXRAYS: with_hexrays,
|
||||
S_EA64: ea64,
|
||||
S_WITH_HEXRAYS: with_hexrays,
|
||||
S_NO_OPT: no_opt
|
||||
}
|
||||
|
||||
@ -335,9 +335,9 @@ def build_distribution(manifest, distrootdir, ea64, nukeold):
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
def build_plugin(
|
||||
platform,
|
||||
idasdkdir,
|
||||
plugin_name,
|
||||
platform,
|
||||
idasdkdir,
|
||||
plugin_name,
|
||||
options):
|
||||
|
||||
# Get the arguments
|
||||
@ -401,7 +401,7 @@ def build_plugin(
|
||||
platform_macros.append("PLUGINFIX")
|
||||
|
||||
# Turn off obsolete functions
|
||||
platform_macros.append("NO_OBSOLETE_FUNCS")
|
||||
#platform_macros.append("NO_OBSOLETE_FUNCS")
|
||||
|
||||
# Build the wrapper from the interface files
|
||||
ea64flag = ea64 and "-D__EA64__" or ""
|
||||
@ -467,17 +467,17 @@ def build_binary_package(options, nukeold):
|
||||
platform_string)
|
||||
# Build the plugin
|
||||
build_plugin(platform_string, IDA_SDK, plugin_name, options)
|
||||
|
||||
|
||||
# Build the binary distribution
|
||||
binmanifest = []
|
||||
if nukeold:
|
||||
binmanifest.extend(BINDIST_MANIFEST)
|
||||
|
||||
|
||||
if not ea64 or nukeold:
|
||||
binmanifest.extend([(x, "python") for x in "python/init.py", "python/idc.py", "python/idautils.py", "idaapi.py"])
|
||||
|
||||
|
||||
binmanifest.append((plugin_name, "plugins"))
|
||||
|
||||
|
||||
build_distribution(binmanifest, BINDISTDIR, ea64, nukeold)
|
||||
|
||||
|
||||
|
@ -15,11 +15,11 @@ def raw_main(p=True):
|
||||
|
||||
for ns in xrange(0, q.nsucc(n)):
|
||||
if p:
|
||||
print " %d->%d" % (n, q.succ(n, ns))
|
||||
print "SUCC: %d->%d" % (n, q.succ(n, ns))
|
||||
|
||||
for ns in xrange(0, q.npred(n)):
|
||||
if p:
|
||||
print " %d->%d" % (n, q.pred(n, ns))
|
||||
print "PRED: %d->%d" % (n, q.pred(n, ns))
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# Using the class
|
||||
|
114
examples/ex_idagraph.py
Normal file
114
examples/ex_idagraph.py
Normal file
@ -0,0 +1,114 @@
|
||||
# -----------------------------------------------------------------------
|
||||
# This is an example illustrating how to manipulate an existing IDA-provided
|
||||
# view (and thus its graph), in Python.
|
||||
# (c) Hex-Rays
|
||||
#
|
||||
from idaapi import IDAViewWrapper
|
||||
from time import sleep
|
||||
import threading
|
||||
|
||||
class Worker(threading.Thread):
|
||||
def __init__(self, w):
|
||||
threading.Thread.__init__(self)
|
||||
self.w = w
|
||||
|
||||
def req_SetCurrentRendererType(self, switch_to):
|
||||
w = self.w
|
||||
def f():
|
||||
print "Switching.."
|
||||
w.SetCurrentRendererType(switch_to)
|
||||
idaapi.execute_sync(f, idaapi.MFF_FAST)
|
||||
|
||||
def req_SetNodeInfo(self, node, info, flags):
|
||||
w = self.w
|
||||
def f():
|
||||
print "Setting node info.."
|
||||
w.SetNodeInfo(node, info, flags)
|
||||
idaapi.execute_sync(f, idaapi.MFF_FAST)
|
||||
|
||||
def req_DelNodesInfos(self, *nodes):
|
||||
w = self.w
|
||||
def f():
|
||||
print "Deleting nodes infos.."
|
||||
w.DelNodesInfos(*nodes)
|
||||
idaapi.execute_sync(f, idaapi.MFF_FAST)
|
||||
|
||||
def run(self):
|
||||
# Note, in order to leave the UI available
|
||||
# to the user, we'll perform UI operations
|
||||
# in this thread.
|
||||
#
|
||||
# But.
|
||||
#
|
||||
# Qt expects that all UI operations be performed from
|
||||
# the main thread. Therefore, we'll have to use
|
||||
# 'idaapi.execute_sync' to send requests to the main thread.
|
||||
|
||||
# Switch back & forth to & from graph view
|
||||
for i in xrange(3):
|
||||
self.req_SetCurrentRendererType(idaapi.TCCRT_FLAT)
|
||||
sleep(1)
|
||||
self.req_SetCurrentRendererType(idaapi.TCCRT_GRAPH)
|
||||
sleep(1)
|
||||
|
||||
# Go to graph view, and set the first node's color
|
||||
self.req_SetCurrentRendererType(idaapi.TCCRT_GRAPH)
|
||||
ni = idaapi.node_info_t()
|
||||
ni.bg_color = 0x00ff00ff
|
||||
ni.frame_color = 0x0000ff00
|
||||
self.req_SetNodeInfo(0, ni, idaapi.NIF_BG_COLOR|idaapi.NIF_FRAME_COLOR)
|
||||
sleep(3)
|
||||
|
||||
# This was fun. But let's revert it.
|
||||
self.req_DelNodesInfos(0)
|
||||
sleep(3)
|
||||
|
||||
print "Done."
|
||||
|
||||
class MyIDAViewWrapper(IDAViewWrapper):
|
||||
# A wrapper around the standard IDA view wrapper.
|
||||
# We'll react to some events and print the parameters
|
||||
# that were sent to us, that's all.
|
||||
def __init__(self, viewName):
|
||||
IDAViewWrapper.__init__(self, viewName)
|
||||
|
||||
# Helper function, to be called by "On*" event handlers.
|
||||
# This will print all the arguments that were passed!
|
||||
def printPrevFrame(self):
|
||||
import inspect
|
||||
stack = inspect.stack()
|
||||
frame, _, _, _, _, _ = stack[1]
|
||||
args, _, _, values = inspect.getargvalues(frame)
|
||||
print "EVENT: %s: args=%s" % (
|
||||
inspect.getframeinfo(frame)[2],
|
||||
[(i, values[i]) for i in args[1:]])
|
||||
|
||||
def OnViewKeydown(self, key, state):
|
||||
self.printPrevFrame()
|
||||
|
||||
def OnViewClick(self, x, y, state):
|
||||
self.printPrevFrame()
|
||||
|
||||
def OnViewDblclick(self, x, y, state):
|
||||
self.printPrevFrame()
|
||||
|
||||
def OnViewSwitched(self, rt):
|
||||
self.printPrevFrame()
|
||||
|
||||
def OnViewMouseOver(self, x, y, state, over_type, over_data):
|
||||
self.printPrevFrame()
|
||||
|
||||
|
||||
|
||||
viewName = "IDA View-A"
|
||||
w = MyIDAViewWrapper(viewName)
|
||||
if w.Bind():
|
||||
print "Succesfully bound to %s" % viewName
|
||||
|
||||
# We'll launch the sequence of operations in another thread,
|
||||
# so that sleep() calls don't freeze the UI
|
||||
worker = Worker(w)
|
||||
worker.start()
|
||||
|
||||
else:
|
||||
print "Couldn't bind to view %s. Is it available?" % viewName
|
@ -1,27 +1,27 @@
|
||||
import idaapi
|
||||
|
||||
def main():
|
||||
if not idaapi.init_hexrays_plugin():
|
||||
return False
|
||||
if not idaapi.init_hexrays_plugin():
|
||||
return False
|
||||
|
||||
print "Hex-rays version %s has been detected" % idaapi.get_hexrays_version()
|
||||
print "Hex-rays version %s has been detected" % idaapi.get_hexrays_version()
|
||||
|
||||
f = idaapi.get_func(idaapi.get_screen_ea());
|
||||
if f is None:
|
||||
print "Please position the cursor within a function"
|
||||
return True
|
||||
|
||||
cfunc = idaapi.decompile(f);
|
||||
if cfunc is None:
|
||||
print "Failed to decompile!"
|
||||
return True
|
||||
|
||||
sv = cfunc.get_pseudocode();
|
||||
for i in xrange(0, sv.size()):
|
||||
line = idaapi.tag_remove(str(sv[i]));
|
||||
print line
|
||||
|
||||
f = idaapi.get_func(idaapi.get_screen_ea());
|
||||
if f is None:
|
||||
print "Please position the cursor within a function"
|
||||
return True
|
||||
|
||||
cfunc = idaapi.decompile(f);
|
||||
if cfunc is None:
|
||||
print "Failed to decompile!"
|
||||
return True
|
||||
|
||||
sv = cfunc.get_pseudocode();
|
||||
for i in xrange(0, sv.size()):
|
||||
line = idaapi.tag_remove(str(sv[i]));
|
||||
print line
|
||||
|
||||
return True
|
||||
|
||||
if main():
|
||||
idaapi.term_hexrays_plugin();
|
||||
idaapi.term_hexrays_plugin();
|
||||
|
@ -5,9 +5,9 @@ Author: EiNSTeiN_ <einstein@g3nius.org>
|
||||
This is a rewrite in Python of the vds3 example that comes with hexrays sdk.
|
||||
|
||||
|
||||
The main difference with the original C code is that when we create the inverted
|
||||
condition object, the newly created cexpr_t instance is given to the hexrays and
|
||||
must not be freed by swig. To achieve this, we have to change the 'thisown' flag
|
||||
The main difference with the original C code is that when we create the inverted
|
||||
condition object, the newly created cexpr_t instance is given to the hexrays and
|
||||
must not be freed by swig. To achieve this, we have to change the 'thisown' flag
|
||||
when appropriate. See http://www.swig.org/Doc1.3/Python.html#Python_nn35
|
||||
|
||||
"""
|
||||
@ -21,23 +21,23 @@ import traceback
|
||||
NETNODE_NAME = '$ hexrays-inverted-if'
|
||||
|
||||
class hexrays_callback_info(object):
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.vu = None
|
||||
|
||||
|
||||
self.node = idaapi.netnode()
|
||||
if not self.node.create(NETNODE_NAME):
|
||||
# node exists
|
||||
self.load()
|
||||
else:
|
||||
self.stored = []
|
||||
|
||||
|
||||
return
|
||||
|
||||
|
||||
def load(self):
|
||||
|
||||
|
||||
self.stored = []
|
||||
|
||||
|
||||
try:
|
||||
data = self.node.getblob(0, 'I')
|
||||
if data:
|
||||
@ -47,39 +47,39 @@ class hexrays_callback_info(object):
|
||||
print 'Failed to load invert-if locations'
|
||||
traceback.print_exc()
|
||||
return
|
||||
|
||||
|
||||
return
|
||||
|
||||
|
||||
def save(self):
|
||||
|
||||
|
||||
try:
|
||||
self.node.setblob(repr(self.stored), 0, 'I')
|
||||
except:
|
||||
print 'Failed to save invert-if locations'
|
||||
traceback.print_exc()
|
||||
return
|
||||
|
||||
|
||||
return
|
||||
|
||||
|
||||
def invert_if(self, cfunc, insn):
|
||||
|
||||
|
||||
if insn.opname != 'if':
|
||||
return False
|
||||
|
||||
|
||||
cif = insn.details
|
||||
|
||||
|
||||
if not cif.ithen or not cif.ielse:
|
||||
return False
|
||||
|
||||
|
||||
idaapi.qswap(cif.ithen, cif.ielse)
|
||||
cond = idaapi.cexpr_t(cif.expr)
|
||||
notcond = idaapi.lnot(cond)
|
||||
cond.thisown = 0 # the new wrapper 'notcond' now holds the reference to the cexpr_t
|
||||
|
||||
|
||||
cif.expr.swap(notcond)
|
||||
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def add_location(self, ea):
|
||||
if ea in self.stored:
|
||||
self.stored.remove(ea)
|
||||
@ -87,15 +87,15 @@ class hexrays_callback_info(object):
|
||||
self.stored.append(ea)
|
||||
self.save()
|
||||
return
|
||||
|
||||
|
||||
def find_if_statement(self, vu):
|
||||
|
||||
|
||||
vu.get_current_item(idaapi.USE_KEYBOARD)
|
||||
item = vu.item
|
||||
|
||||
|
||||
if item.is_citem() and item.it.op == idaapi.cit_if and item.it.to_specific_type.cif.ielse is not None:
|
||||
return item.it.to_specific_type
|
||||
|
||||
|
||||
if vu.tail.citype == idaapi.VDI_TAIL and vu.tail.loc.itp == idaapi.ITP_ELSE:
|
||||
# for tail marks, we know only the corresponding ea,
|
||||
# not the pointer to if-statement
|
||||
@ -103,48 +103,48 @@ class hexrays_callback_info(object):
|
||||
class if_finder_t(idaapi.ctree_visitor_t):
|
||||
def __init__(self, ea):
|
||||
idaapi.ctree_visitor_t.__init__(self, idaapi.CV_FAST | idaapi.CV_INSNS)
|
||||
|
||||
|
||||
self.ea = ea
|
||||
self.found = None
|
||||
return
|
||||
|
||||
|
||||
def visit_insn(self, i):
|
||||
if i.op == idaapi.cit_if and i.ea == self.ea:
|
||||
self.found = i
|
||||
return 1 # stop enumeration
|
||||
return 0
|
||||
|
||||
|
||||
iff = if_finder_t(vu.tail.loc.ea)
|
||||
if iff.apply_to(vu.cfunc.body, None):
|
||||
return iff.found
|
||||
|
||||
|
||||
return
|
||||
|
||||
|
||||
def invert_if_event(self, vu):
|
||||
|
||||
|
||||
cfunc = vu.cfunc.__deref__()
|
||||
|
||||
|
||||
i = self.find_if_statement(vu)
|
||||
if not i:
|
||||
return False
|
||||
|
||||
|
||||
if self.invert_if(cfunc, i):
|
||||
vu.refresh_ctext()
|
||||
|
||||
|
||||
self.add_location(i.ea)
|
||||
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def restore(self, cfunc):
|
||||
|
||||
|
||||
class visitor(idaapi.ctree_visitor_t):
|
||||
|
||||
|
||||
def __init__(self, inverter, cfunc):
|
||||
idaapi.ctree_visitor_t.__init__(self, idaapi.CV_FAST | idaapi.CV_INSNS)
|
||||
self.inverter = inverter
|
||||
self.cfunc = cfunc
|
||||
return
|
||||
|
||||
|
||||
def visit_insn(self, i):
|
||||
try:
|
||||
if i.op == idaapi.cit_if and i.ea in self.inverter.stored:
|
||||
@ -152,40 +152,40 @@ class hexrays_callback_info(object):
|
||||
except:
|
||||
traceback.print_exc()
|
||||
return 0 # continue enumeration
|
||||
|
||||
|
||||
visitor(self, cfunc).apply_to(cfunc.body, None)
|
||||
|
||||
|
||||
return
|
||||
|
||||
|
||||
def menu_callback(self):
|
||||
try:
|
||||
self.invert_if_event(self.vu)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
return 0
|
||||
|
||||
|
||||
def event_callback(self, event, *args):
|
||||
|
||||
|
||||
try:
|
||||
if event == idaapi.hxe_keyboard:
|
||||
vu, keycode, shift = args
|
||||
|
||||
|
||||
if idaapi.lookup_key_code(keycode, shift, True) == idaapi.get_key_code("I") and shift == 0:
|
||||
if self.invert_if_event(vu):
|
||||
return 1
|
||||
|
||||
|
||||
elif event == idaapi.hxe_right_click:
|
||||
self.vu, = args
|
||||
idaapi.add_custom_viewer_popup_item(self.vu.ct, "Invert then/else", "I", self.menu_callback)
|
||||
|
||||
|
||||
elif event == idaapi.hxe_maturity:
|
||||
cfunc, maturity = args
|
||||
|
||||
|
||||
if maturity == idaapi.CMAT_FINAL:
|
||||
self.restore(cfunc)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
return 0
|
||||
|
||||
if idaapi.init_hexrays_plugin():
|
||||
@ -193,3 +193,4 @@ if idaapi.init_hexrays_plugin():
|
||||
idaapi.install_hexrays_callback(i.event_callback)
|
||||
else:
|
||||
print 'invert-if: hexrays is not available.'
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
ALERT_AUTO_SCRIPTS = 1
|
||||
|
||||
// Remove current directory from import search path
|
||||
REMOVE_CWD_SYS_PATH = 0
|
||||
REMOVE_CWD_SYS_PATH = 1
|
||||
|
||||
// Script timeout (in seconds)
|
||||
// (A value of 0 disables the timeout)
|
||||
|
606
python.cpp
606
python.cpp
File diff suppressed because it is too large
Load Diff
177
python/idc.py
177
python/idc.py
@ -260,6 +260,9 @@ NEF_FLAT = idaapi.NEF_FLAT # Autocreated FLAT group (PE)
|
||||
def IsString(var): raise NotImplementedError, "this function is not needed in Python"
|
||||
def IsLong(var): raise NotImplementedError, "this function is not needed in Python"
|
||||
def IsFloat(var): raise NotImplementedError, "this function is not needed in Python"
|
||||
def IsFunc(var): raise NotImplementedError, "this function is not needed in Python"
|
||||
def IsPvoid(var): raise NotImplementedError, "this function is not needed in Python"
|
||||
def IsInt64(var): raise NotImplementedError, "this function is not needed in Python"
|
||||
|
||||
def MK_FP(seg, off):
|
||||
"""
|
||||
@ -1159,7 +1162,11 @@ REFINFO_NOBASE = 0x80 # offset base is a number
|
||||
# that base have be any value
|
||||
# nb: base xrefs are created only if base
|
||||
# points to the middle of a segment
|
||||
|
||||
REFINFO_SUBTRACT = 0x0100 # the reference value is subtracted from
|
||||
# the base value instead of (as usual)
|
||||
# being added to it
|
||||
REFINFO_SIGNEDOP = 0x0200 # the operand value is sign-extended (only
|
||||
# supported for REF_OFF8/16/32/64)
|
||||
|
||||
def OpSeg(ea, n):
|
||||
"""
|
||||
@ -1865,24 +1872,28 @@ def Qword(ea):
|
||||
def GetFloat(ea):
|
||||
"""
|
||||
Get value of a floating point number (4 bytes)
|
||||
|
||||
This function assumes number stored using IEEE format
|
||||
and in the same endianness as integers.
|
||||
|
||||
@param ea: linear address
|
||||
|
||||
@return: float
|
||||
"""
|
||||
tmp = idaapi.get_many_bytes(ea, 4)
|
||||
tmp = struct.pack("I", Dword(ea))
|
||||
return struct.unpack("f", tmp)[0]
|
||||
|
||||
|
||||
def GetDouble(ea):
|
||||
"""
|
||||
Get value of a floating point number (8 bytes)
|
||||
This function assumes number stored using IEEE format
|
||||
and in the same endianness as integers.
|
||||
|
||||
@param ea: linear address
|
||||
|
||||
@return: double
|
||||
"""
|
||||
tmp = idaapi.get_many_bytes(ea, 8)
|
||||
tmp = struct.pack("Q", Qword(ea))
|
||||
return struct.unpack("d", tmp)[0]
|
||||
|
||||
|
||||
@ -2165,23 +2176,46 @@ def Demangle(name, disable_mask):
|
||||
return idaapi.demangle_name(name, disable_mask)
|
||||
|
||||
|
||||
def GetDisasmEx(ea, flags):
|
||||
"""
|
||||
Get disassembly line
|
||||
|
||||
@param ea: linear address of instruction
|
||||
|
||||
@param flags: combination of the GENDSM_ flags, or 0
|
||||
|
||||
@return: "" - could not decode instruction at the specified location
|
||||
|
||||
@note: this function may not return exactly the same mnemonics
|
||||
as you see on the screen.
|
||||
"""
|
||||
text = idaapi.generate_disasm_line(ea, flags)
|
||||
if text:
|
||||
return idaapi.tag_remove(text)
|
||||
else:
|
||||
return ""
|
||||
|
||||
# flags for GetDisasmEx
|
||||
# generate a disassembly line as if
|
||||
# there is an instruction at 'ea'
|
||||
GENDSM_FORCE_CODE = idaapi.GENDSM_FORCE_CODE
|
||||
|
||||
# if the instruction consists of several lines,
|
||||
# produce all of them (useful for parallel instructions)
|
||||
GENDSM_MULTI_LINE = idaapi.GENDSM_MULTI_LINE
|
||||
|
||||
def GetDisasm(ea):
|
||||
"""
|
||||
Get disassembly line
|
||||
|
||||
@param ea: linear address of instruction
|
||||
|
||||
@return: "" - no instruction at the specified location
|
||||
@return: "" - could not decode instruction at the specified location
|
||||
|
||||
@note: this function may not return exactly the same mnemonics
|
||||
as you see on the screen.
|
||||
"""
|
||||
text = idaapi.generate_disasm_line(ea)
|
||||
if text:
|
||||
return idaapi.tag_remove(text)
|
||||
else:
|
||||
return ""
|
||||
|
||||
return GetDisasmEx(ea, 0)
|
||||
|
||||
def GetMnem(ea):
|
||||
"""
|
||||
@ -2475,9 +2509,9 @@ def ChangeConfig(directive):
|
||||
@param directive: directives to process, for example: PACK_DATABASE=2
|
||||
|
||||
@note: If the directives are erroneous, a fatal error will be generated.
|
||||
The changes will be effective only for the current session.
|
||||
The settings are permanent: effective for the current session and the next ones
|
||||
"""
|
||||
return Eval('ChangeConfig("%s")' % directive)
|
||||
return Eval('ChangeConfig("%s")' % idaapi.str2user(directive))
|
||||
|
||||
|
||||
# The following functions allow you to set/get common parameters.
|
||||
@ -3279,7 +3313,7 @@ def SegName(ea):
|
||||
return name
|
||||
|
||||
|
||||
def AddSeg(startea, endea, base, use32, align, comb):
|
||||
def AddSegEx(startea, endea, base, use32, align, comb, flags):
|
||||
"""
|
||||
Create a new segment
|
||||
|
||||
@ -3294,6 +3328,7 @@ def AddSeg(startea, endea, base, use32, align, comb):
|
||||
@param use32: 0: 16bit segment, 1: 32bit segment, 2: 64bit segment
|
||||
@param align: segment alignment. see below for alignment values
|
||||
@param comb: segment combination. see below for combination values.
|
||||
@param flags: combination of ADDSEG_... bits
|
||||
|
||||
@return: 0-failed, 1-ok
|
||||
"""
|
||||
@ -3304,8 +3339,27 @@ def AddSeg(startea, endea, base, use32, align, comb):
|
||||
s.bitness = use32
|
||||
s.align = align
|
||||
s.comb = comb
|
||||
return idaapi.add_segm_ex(s, "", "", idaapi.ADDSEG_NOSREG)
|
||||
return idaapi.add_segm_ex(s, "", "", flags)
|
||||
|
||||
ADDSEG_NOSREG = idaapi.ADDSEG_NOSREG # set all default segment register values
|
||||
# to BADSELs
|
||||
# (undefine all default segment registers)
|
||||
ADDSEG_OR_DIE = idaapi. ADDSEG_OR_DIE # qexit() if can't add a segment
|
||||
ADDSEG_NOTRUNC = idaapi.ADDSEG_NOTRUNC # don't truncate the new segment at the beginning
|
||||
# of the next segment if they overlap.
|
||||
# destroy/truncate old segments instead.
|
||||
ADDSEG_QUIET = idaapi.ADDSEG_QUIET # silent mode, no "Adding segment..." in the messages window
|
||||
ADDSEG_FILLGAP = idaapi.ADDSEG_FILLGAP # If there is a gap between the new segment
|
||||
# and the previous one, and this gap is less
|
||||
# than 64K, then fill the gap by extending the
|
||||
# previous segment and adding .align directive
|
||||
# to it. This way we avoid gaps between segments.
|
||||
# Too many gaps lead to a virtual array failure.
|
||||
# It can not hold more than ~1000 gaps.
|
||||
ADDSEG_SPARSE = idaapi.ADDSEG_SPARSE # Use sparse storage method for the new segment
|
||||
|
||||
def AddSeg(startea, endea, base, use32, align, comb):
|
||||
return AddSegEx(startea, endea, base, use32, align, comb, ADDSEG_NOSREG)
|
||||
|
||||
def DelSeg(ea, flags):
|
||||
"""
|
||||
@ -3889,7 +3943,7 @@ def SaveFile(filepath, pos, ea, size):
|
||||
|
||||
@return: 0 - error, 1 - ok
|
||||
"""
|
||||
of = idaapi.fopenWB(filepath)
|
||||
of = idaapi.fopenM(filepath)
|
||||
|
||||
if of:
|
||||
retval = idaapi.base2file(of, pos, ea, ea+size)
|
||||
@ -5369,10 +5423,10 @@ def AddStrucMember(sid, name, offset, flag, typeid, nbytes, target=-1, tdelta=0,
|
||||
|
||||
"""
|
||||
if isOff0(flag):
|
||||
return Eval('AddStrucMember(%d, "%s", %d, %d, %d, %d, %d, %d, %d);' % (sid, name, offset, flag, typeid, nbytes,
|
||||
return Eval('AddStrucMember(%d, "%s", %d, %d, %d, %d, %d, %d, %d);' % (sid, idaapi.str2user(name), offset, flag, typeid, nbytes,
|
||||
target, tdelta, reftype))
|
||||
else:
|
||||
return Eval('AddStrucMember(%d, "%s", %d, %d, %d, %d);' % (sid, name, offset, flag, typeid, nbytes))
|
||||
return Eval('AddStrucMember(%d, "%s", %d, %d, %d, %d);' % (sid, idaapi.str2user(name), offset, flag, typeid, nbytes))
|
||||
|
||||
|
||||
STRUC_ERROR_MEMBER_NAME = -1 # already has member with this name (bad name)
|
||||
@ -6799,10 +6853,10 @@ def GetType(ea):
|
||||
def SizeOf(typestr):
|
||||
"""
|
||||
Returns the size of the type. It is equivalent to IDC's sizeof().
|
||||
Use name, tp, fld = idc.ParseType() ; Sizeof(fld) to retrieve the size
|
||||
Use name, tp, fld = idc.ParseType() ; SizeOf(tp) to retrieve the size
|
||||
@return: -1 if typestring is not valid otherwise the size of the type
|
||||
"""
|
||||
return idaapi.get_type_size0(idaapi.cvar.idati, typestr)
|
||||
return idaapi.calc_type_size(idaapi.cvar.idati, typestr)
|
||||
|
||||
def GetTinfo(ea):
|
||||
"""
|
||||
@ -6813,6 +6867,15 @@ def GetTinfo(ea):
|
||||
"""
|
||||
return idaapi.idc_get_type_raw(ea)
|
||||
|
||||
def GetLocalTinfo(ordinal):
|
||||
"""
|
||||
Get local type information as 'typeinfo' object
|
||||
|
||||
@param ordinal: slot number (1...NumberOfLocalTypes)
|
||||
@return: None on failure, or (type, fields, name) tuple.
|
||||
"""
|
||||
return idaapi.idc_get_local_type_raw(ordinal)
|
||||
|
||||
def GuessType(ea):
|
||||
"""
|
||||
Guess type of function/variable
|
||||
@ -6823,6 +6886,37 @@ def GuessType(ea):
|
||||
"""
|
||||
return idaapi.idc_guess_type(ea)
|
||||
|
||||
TINFO_GUESSED = 0x0000 # this is a guessed type
|
||||
TINFO_DEFINITE = 0x0001 # this is a definite type
|
||||
TINFO_DELAYFUNC = 0x0002 # if type is a function and no function exists at ea,
|
||||
# schedule its creation and argument renaming to
|
||||
# auto-analysis otherwise try to create it immediately
|
||||
|
||||
def ApplyType(ea, py_type, flags = TINFO_DEFINITE):
|
||||
"""
|
||||
Apply the specified type to the address
|
||||
|
||||
@param ti: Type info. 'idaapi.cvar.idati' can be passed.
|
||||
@param py_type: typeinfo tuple (type, fields) as GetTinfo() returns
|
||||
or tuple (name, type, fields) as ParseType() returns
|
||||
or None
|
||||
if specified as None, then the
|
||||
item associated with 'ea' will be deleted.
|
||||
@param ea: the address of the object
|
||||
@param flags: combination of TINFO_... constants or 0
|
||||
@return: Boolean
|
||||
"""
|
||||
|
||||
if py_type != None:
|
||||
if len(py_type) == 3:
|
||||
pt = py_type[1:] # skip name component
|
||||
else:
|
||||
pt = py_type
|
||||
return idaapi.apply_type(idaapi.cvar.idati, pt[0], pt[1], ea, flags)
|
||||
if idaapi.has_ti(ea):
|
||||
idaapi.del_tinfo(ea)
|
||||
return True
|
||||
return False
|
||||
|
||||
def SetType(ea, newtype):
|
||||
"""
|
||||
@ -6837,11 +6931,10 @@ def SetType(ea, newtype):
|
||||
@return: 1-ok, 0-failed.
|
||||
"""
|
||||
if newtype is not '':
|
||||
return idaapi.apply_cdecl2(idaapi.cvar.idati, ea, newtype)
|
||||
if idaapi.has_ti(ea):
|
||||
idaapi.del_tinfo(ea)
|
||||
return True
|
||||
return False
|
||||
pt = ParseType(newtype, 0)[1:]
|
||||
else:
|
||||
pt = None
|
||||
return ApplyType(ea, pt, TINFO_DEFINITE)
|
||||
|
||||
def ParseType(inputtype, flags):
|
||||
"""
|
||||
@ -6852,6 +6945,8 @@ def ParseType(inputtype, flags):
|
||||
|
||||
@return: None on failure or (name, type, fields) tuple
|
||||
"""
|
||||
if len(inputtype) != 0 and inputtype[-1] != ';':
|
||||
inputtype = inputtype + ';'
|
||||
return idaapi.idc_parse_decl(idaapi.cvar.idati, inputtype, flags)
|
||||
|
||||
def ParseTypes(inputtype, flags = 0):
|
||||
@ -6874,6 +6969,9 @@ PT_PAK2 = 0x0020 # #pragma pack(2)
|
||||
PT_PAK4 = 0x0030 # #pragma pack(4)
|
||||
PT_PAK8 = 0x0040 # #pragma pack(8)
|
||||
PT_PAK16 = 0x0050 # #pragma pack(16)
|
||||
PT_HIGH = 0x0080 # assume high level prototypes
|
||||
# (with hidden args, etc)
|
||||
PT_LOWER = 0x0100 # lower the function prototypes
|
||||
|
||||
|
||||
def GetMaxLocalType():
|
||||
@ -6903,17 +7001,14 @@ def SetLocalType(ordinal, input, flags):
|
||||
def GetLocalType(ordinal, flags):
|
||||
"""
|
||||
Retrieve a local type declaration
|
||||
|
||||
@param ordinal: slot number (1...NumberOfLocalTypes)
|
||||
@param flags: any of PRTYPE_* constants
|
||||
|
||||
@return: local type as a C declaration or ""
|
||||
|
||||
@note: This function can return types strings up to 64KiB. Use idaapi.idc_get_local_type()
|
||||
for larger types.
|
||||
"""
|
||||
res,str = idaapi.idc_get_local_type(ordinal, flags, 2**16)
|
||||
return str
|
||||
(type, fields) = GetLocalTinfo(ordinal)
|
||||
if type:
|
||||
name = GetLocalTypeName(ordinal)
|
||||
return idaapi.idc_print_type(type, fields, name, flags)
|
||||
return ""
|
||||
|
||||
PRTYPE_1LINE = 0x0000 # print to one line
|
||||
PRTYPE_MULTI = 0x0001 # print to many lines
|
||||
@ -7313,7 +7408,7 @@ def SendDbgCommand(cmd):
|
||||
An exception will be raised if the debugger is not running or the current debugger does not export
|
||||
the 'SendDbgCommand' IDC command.
|
||||
"""
|
||||
s = Eval('SendDbgCommand("%s");' % cmd)
|
||||
s = Eval('SendDbgCommand("%s");' % idaapi.str2user(cmd))
|
||||
if s.startswith("IDC_FAILURE"):
|
||||
raise Exception, "Debugger command is available only when the debugger is active!"
|
||||
return s
|
||||
@ -7806,10 +7901,11 @@ BPTATTR_SIZE = 2 # size of the breakpoint (undefined for software breakpoint
|
||||
BPTATTR_TYPE = 3
|
||||
|
||||
# Breakpoint types:
|
||||
BPT_EXEC = 0 # Hardware: Execute instruction
|
||||
BPT_WRITE = 1 # Hardware: Write access
|
||||
BPT_RDWR = 3 # Hardware: Read/write access
|
||||
BPT_SOFT = 4 # Software breakpoint
|
||||
BPT_WRITE = 1 # Hardware: Write access
|
||||
BPT_RDWR = 3 # Hardware: Read/write access
|
||||
BPT_SOFT = 4 # Software breakpoint
|
||||
BPT_EXEC = 8 # Hardware: Execute instruction
|
||||
BPT_DEFAULT = (BPT_SOFT|BPT_EXEC); # Choose bpt type automaticaly
|
||||
|
||||
BPTATTR_COUNT = 4
|
||||
BPTATTR_FLAGS = 5
|
||||
@ -7921,7 +8017,7 @@ def AddBptEx(ea, size, bpttype):
|
||||
|
||||
|
||||
def AddBpt(ea):
|
||||
return AddBptEx(ea, 0, BPT_SOFT)
|
||||
return AddBptEx(ea, 0, BPT_DEFAULT)
|
||||
|
||||
|
||||
def DelBpt(ea):
|
||||
@ -8019,12 +8115,13 @@ def LoadTraceFile(filename):
|
||||
Load a previously recorded binary trace file
|
||||
@param filename: trace file
|
||||
"""
|
||||
return idaapi.load_trace_file(filename, None)
|
||||
return idaapi.load_trace_file(filename)
|
||||
|
||||
def SaveTraceFile(filename, description):
|
||||
"""
|
||||
Save current trace to a binary trace file
|
||||
@param filename: trace file
|
||||
@param description: trace description
|
||||
"""
|
||||
return idaapi.save_trace_file(filename, description)
|
||||
|
||||
|
222
pywraps.hpp
222
pywraps.hpp
@ -29,10 +29,8 @@
|
||||
#define S_IDAAPI_EXECSCRIPT "IDAPython_ExecScript"
|
||||
#define S_IDAAPI_COMPLETION "IDAPython_Completion"
|
||||
#define S_IDAAPI_FORMATEXC "IDAPython_FormatExc"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Vector of PyObject*
|
||||
typedef qvector<PyObject *> ppyobject_vec_t;
|
||||
#define S_IDAAPI_LOADPROCMOD "IDAPython_LoadProcMod"
|
||||
#define S_IDAAPI_UNLOADPROCMOD "IDAPython_UnLoadProcMod"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// PyIdc conversion object IDs
|
||||
@ -58,7 +56,7 @@ typedef qvector<PyObject *> ppyobject_vec_t;
|
||||
#define CIP_FAILED -1 // Conversion error
|
||||
#define CIP_IMMUTABLE 0 // Immutable object passed. Will not update the object but no error occured
|
||||
#define CIP_OK 1 // Success
|
||||
#define CIP_OK_NODECREF 2 // Success but do not decrement its reference
|
||||
#define CIP_OK_OPAQUE 2 // Success, but the data pointed to by the PyObject* is an opaque object.
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Helper macro to create C counterparts of Python py_clinked_object_t object
|
||||
@ -66,10 +64,12 @@ typedef qvector<PyObject *> ppyobject_vec_t;
|
||||
#define DECLARE_PY_CLINKED_OBJECT(type) \
|
||||
static PyObject *type##_create() \
|
||||
{ \
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE(); \
|
||||
return PyCObject_FromVoidPtr(new type(), NULL); \
|
||||
} \
|
||||
static bool type##_destroy(PyObject *py_obj) \
|
||||
{ \
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE(); \
|
||||
if ( !PyCObject_Check(py_obj) ) \
|
||||
return false; \
|
||||
delete (type *)PyCObject_AsVoidPtr(py_obj); \
|
||||
@ -77,10 +77,12 @@ typedef qvector<PyObject *> ppyobject_vec_t;
|
||||
} \
|
||||
static type *type##_get_clink(PyObject *self) \
|
||||
{ \
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE(); \
|
||||
return (type *)pyobj_get_clink(self); \
|
||||
} \
|
||||
static PyObject *type##_get_clink_ptr(PyObject *self) \
|
||||
{ \
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE(); \
|
||||
return PyLong_FromUnsignedLongLong( \
|
||||
(unsigned PY_LONG_LONG)pyobj_get_clink(self)); \
|
||||
}
|
||||
@ -91,47 +93,183 @@ typedef qvector<PyObject *> ppyobject_vec_t;
|
||||
#endif // __PYWRAPS__
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
class CGilStateAuto
|
||||
class gil_lock_t
|
||||
{
|
||||
private:
|
||||
PyGILState_STATE state;
|
||||
public:
|
||||
CGilStateAuto()
|
||||
gil_lock_t()
|
||||
{
|
||||
state = PyGILState_Ensure();
|
||||
}
|
||||
|
||||
~CGilStateAuto()
|
||||
~gil_lock_t()
|
||||
{
|
||||
PyGILState_Release(state);
|
||||
}
|
||||
};
|
||||
// Declare a variable to acquire/release the GIL
|
||||
#define PYW_GIL_AUTO_ENSURE CGilStateAuto GIL_STATE_AUTO
|
||||
#define PYW_GIL_GET gil_lock_t lock;
|
||||
|
||||
// Macros to acquire/release GIL in a given scope
|
||||
#define PYW_GIL_ENSURE_N(name) PyGILState_STATE gil_state##name = PyGILState_Ensure()
|
||||
#define PYW_GIL_RELEASE_N(name) PyGILState_Release(gil_state##name)
|
||||
#ifdef _DEBUG
|
||||
#define GIL_CHKCONDFAIL (PyGILState_GetThisThreadState() != _PyThreadState_Current)
|
||||
#else
|
||||
#define GIL_CHKCONDFAIL (((debug & IDA_DEBUG_PLUGIN) == IDA_DEBUG_PLUGIN) \
|
||||
&& PyGILState_GetThisThreadState() != _PyThreadState_Current)
|
||||
#endif
|
||||
|
||||
#define PYW_GIL_CHECK_LOCKED_SCOPE() \
|
||||
do \
|
||||
{ \
|
||||
if ( GIL_CHKCONDFAIL ) \
|
||||
{ \
|
||||
msg("*** WARNING: Code at %s:%d should have the GIL, but apparently doesn't ***\n", \
|
||||
__FILE__, __LINE__); \
|
||||
if ( under_debugger ) \
|
||||
BPT; \
|
||||
} \
|
||||
} while ( false )
|
||||
|
||||
#define PYW_GIL_ENSURE PYW_GIL_ENSURE_N(_)
|
||||
#define PYW_GIL_RELEASE PYW_GIL_RELEASE_N(_)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// All the exported functions from PyWraps are forward declared here
|
||||
insn_t *insn_t_get_clink(PyObject *self);
|
||||
op_t *op_t_get_clink(PyObject *self);
|
||||
|
||||
// Returns a reference to a class
|
||||
PyObject *get_idaapi_attr(const char *attr);
|
||||
//-------------------------------------------------------------------------
|
||||
// The base for a reference. Will automatically increase the reference
|
||||
// counter for the object when it is assigned from another ref_t,
|
||||
// and decrease the reference counter when destroyed.
|
||||
// This is meant to be used whenever possible, in order to prevent
|
||||
// situations where, e.g., a given code path is taken and we return from
|
||||
// a function without first decreasing the reference counter.
|
||||
//
|
||||
// Note: You should never, ever have to Py_[INCREF|DECREF] the 'o' object yourself.
|
||||
// Note: These simple ref_t cannot be created with a PyObject* directly
|
||||
// (that would be the role of 'newref_t'/'borref_t' below.)
|
||||
// In other words: simple 'ref_t' instances are never created from the
|
||||
// result of calling the CPython API. They are only used when in
|
||||
// idapython land.
|
||||
// In yet other words: the CPython API only deals in terms of
|
||||
// 'New references' and 'Borrowed references'. Those are implemented,
|
||||
// respectively, by the 'newref_t' and 'borref_t' classes below.
|
||||
// This 'ref_t' is only used for internal handling.
|
||||
struct ref_t
|
||||
{
|
||||
PyObject *o;
|
||||
|
||||
// Returns a reference to a class by its ID
|
||||
PyObject *get_idaapi_attr_by_id(const int class_id);
|
||||
ref_t() : o(NULL) {}
|
||||
ref_t(const ref_t &other) : o(other.o) { incref(); }
|
||||
~ref_t() { decref(); }
|
||||
ref_t &operator=(const ref_t &other)
|
||||
{
|
||||
decref();
|
||||
o = other.o;
|
||||
incref();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void incref() const { if ( o != NULL ) Py_INCREF(o); }
|
||||
void decref() const { if ( o != NULL ) Py_DECREF(o); }
|
||||
|
||||
bool operator==(PyObject *other) const { return o == other; }
|
||||
bool operator!=(PyObject *other) const { return ! ((*this) == other); }
|
||||
|
||||
bool operator==(const ref_t &other) const { return o == other.o; }
|
||||
bool operator!=(const ref_t &other) const { return ! ((*this) == other); }
|
||||
|
||||
// operator PyObject *() const { return o; }
|
||||
// PyObject *operator ->() const { return o; }
|
||||
// PyObject &operator *() const { return *o; }
|
||||
//protected:
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// A 'new' reference. Typically used when the CPython implementation returns
|
||||
// a PyObject* whose refcnt was already increased, and that the caller is
|
||||
// responsible for releasing.
|
||||
//
|
||||
// This implements the 'New reference' idea at http://docs.python.org/2/c-api/intro.html:
|
||||
// ---
|
||||
// "When a function passes ownership of a reference on to its caller,
|
||||
// the caller is said to receive a new reference"
|
||||
// ---
|
||||
// E.g., from "PyObject_GetAttrString"'s doc:
|
||||
// ---
|
||||
// "Return value: New reference.
|
||||
// Retrieve an attribute named attr_name from object o[...]"
|
||||
// ---
|
||||
struct newref_t : public ref_t
|
||||
{
|
||||
newref_t(); // No.
|
||||
newref_t(const newref_t &other); // No.
|
||||
newref_t &operator=(const newref_t &other); // No.
|
||||
newref_t(PyObject *_o)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
QASSERT(30409, _o == NULL || _o->ob_refcnt >= 1);
|
||||
#endif
|
||||
o = _o;
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// A 'borrowed' reference. Typically used when the CPython implementation returns
|
||||
// a PyObject* whose ownership is _not_ transferred to the caller.
|
||||
// Therefore, and since the caller wants to make sure the object is not
|
||||
// released while it is using it, it must first increase the reference count,
|
||||
// and then decrease it.
|
||||
//
|
||||
// This is similar to the simpler 'ref_t' in that it first increases, and then
|
||||
// decreases the reference count. The difference is that 'borref_t' instances
|
||||
// can be created with a PyObject*, while 'ref_t' instances cannot (by design).
|
||||
//
|
||||
// This implements the 'Borrowed reference' idea at http://docs.python.org/2/c-api/intro.html:
|
||||
// ---
|
||||
// "When no ownership is transferred, the caller is said to borrow the reference.
|
||||
// Nothing needs to be done for a borrowed reference."
|
||||
// ---
|
||||
struct borref_t : public ref_t
|
||||
{
|
||||
borref_t(); // No.
|
||||
borref_t(const newref_t &other); // No.
|
||||
borref_t &operator=(const newref_t &other); // No.
|
||||
borref_t(PyObject *_o)
|
||||
{
|
||||
o = _o;
|
||||
incref(); // ~ref_t() will decref(), so we need to incref.
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Vector of ref_t
|
||||
struct ref_vec_t : public qvector<ref_t>
|
||||
{
|
||||
void to_pyobject_pointers(qvector<PyObject*> *out)
|
||||
{
|
||||
size_t n = size();
|
||||
out->resize(n);
|
||||
for ( size_t i = 0; i < n; ++i )
|
||||
out->at(i) = at(i).o;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Returns a new reference to a class
|
||||
// Return value: New reference.
|
||||
ref_t get_idaapi_attr(const char *attr);
|
||||
|
||||
// Returns a new reference to a class by its ID
|
||||
// Return value: New reference.
|
||||
ref_t get_idaapi_attr_by_id(const int class_id);
|
||||
|
||||
// Tries to import a module and swallows the exception if it fails and returns NULL
|
||||
PyObject *PyW_TryImportModule(const char *name);
|
||||
// Return value: New reference.
|
||||
ref_t PyW_TryImportModule(const char *name);
|
||||
|
||||
// Tries to get an attribute and swallows the exception if it fails and returns NULL
|
||||
PyObject *PyW_TryGetAttrString(PyObject *py_var, const char *attr);
|
||||
ref_t PyW_TryGetAttrString(PyObject *py_var, const char *attr);
|
||||
|
||||
// Returns the linked object (void *) from a PyObject
|
||||
void *pyobj_get_clink(PyObject *pyobj);
|
||||
@ -160,17 +298,17 @@ bool PyW_GetError(char *buf, size_t bufsz, bool clear_err = true);
|
||||
bool PyW_ShowCbErr(const char *cb_name);
|
||||
|
||||
// Utility function to create a class instance whose constructor takes zero arguments
|
||||
PyObject *create_idaapi_class_instance0(const char *clsname);
|
||||
ref_t create_idaapi_class_instance0(const char *clsname);
|
||||
|
||||
// Utility function to create linked class instances
|
||||
PyObject *create_idaapi_linked_class_instance(const char *clsname, void *lnk);
|
||||
ref_t create_idaapi_linked_class_instance(const char *clsname, void *lnk);
|
||||
|
||||
// Returns the string representation of a PyObject
|
||||
bool PyW_ObjectToString(PyObject *obj, qstring *out);
|
||||
|
||||
// Utility function to convert a python object to an IDC object
|
||||
// and sets a python exception on failure.
|
||||
bool convert_pyobj_to_idc_exc(PyObject *py_obj, idc_value_t *idc_obj);
|
||||
bool pyvar_to_idcvar_or_error(const ref_t &py_obj, idc_value_t *idc_obj);
|
||||
|
||||
// Creates and initializes an IDC exception
|
||||
error_t PyW_CreateIdcException(idc_value_t *res, const char *msg);
|
||||
@ -179,38 +317,38 @@ error_t PyW_CreateIdcException(idc_value_t *res, const char *msg);
|
||||
// Conversion functions
|
||||
//
|
||||
bool pyw_convert_idc_args(
|
||||
const idc_value_t args[],
|
||||
int nargs,
|
||||
ppyobject_vec_t &pargs,
|
||||
boolvec_t *decref,
|
||||
char *errbuf = NULL,
|
||||
size_t errbufsize = 0);
|
||||
|
||||
void pyw_free_idc_args(
|
||||
ppyobject_vec_t &pargs,
|
||||
boolvec_t *decref = NULL);
|
||||
const idc_value_t args[],
|
||||
int nargs,
|
||||
ref_vec_t &pargs,
|
||||
bool as_tupple,
|
||||
char *errbuf = NULL,
|
||||
size_t errbufsize = 0);
|
||||
|
||||
// Converts Python variable to IDC variable
|
||||
// gvar_sn is used in case the Python object was a created from a call to idcvar_to_pyvar and the IDC object was a VT_REF
|
||||
int pyvar_to_idcvar(
|
||||
PyObject *py_var,
|
||||
idc_value_t *idc_var,
|
||||
int *gvar_sn = NULL);
|
||||
const ref_t &py_var,
|
||||
idc_value_t *idc_var,
|
||||
int *gvar_sn = NULL);
|
||||
|
||||
// Converts from IDC to Python
|
||||
// We support converting VT_REF IDC variable types
|
||||
int idcvar_to_pyvar(
|
||||
const idc_value_t &idc_var,
|
||||
PyObject **py_var);
|
||||
ref_t *py_var);
|
||||
|
||||
// Walks a Python list or Sequence and calls the callback
|
||||
Py_ssize_t pyvar_walk_list(
|
||||
PyObject *py_list,
|
||||
int (idaapi *cb)(PyObject *py_item, Py_ssize_t index, void *ud) = NULL,
|
||||
void *ud = NULL);
|
||||
const ref_t &py_list,
|
||||
int (idaapi *cb)(const ref_t &py_item, Py_ssize_t index, void *ud) = NULL,
|
||||
void *ud = NULL);
|
||||
Py_ssize_t pyvar_walk_list(
|
||||
PyObject *py_list,
|
||||
int (idaapi *cb)(const ref_t &py_item, Py_ssize_t index, void *ud) = NULL,
|
||||
void *ud = NULL);
|
||||
|
||||
// Converts an intvec_t to a Python list object
|
||||
PyObject *PyW_IntVecToPyList(const intvec_t &intvec);
|
||||
ref_t PyW_IntVecToPyList(const intvec_t &intvec);
|
||||
|
||||
// Converts an Python list to an intvec
|
||||
bool PyW_PyListToIntVec(PyObject *py_list, intvec_t &intvec);
|
||||
@ -233,4 +371,4 @@ bool pywraps_check_autoscripts(char *buf, size_t bufsize);
|
||||
bool init_pywraps();
|
||||
void deinit_pywraps();
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,125 +1,2 @@
|
||||
@echo off
|
||||
|
||||
rem Please use the same tag for the same .i file
|
||||
rem That means if many insertions are going to happen in one given .i file then don't use more than code marking tag
|
||||
|
||||
set PY=c:\python27\python.exe
|
||||
|
||||
echo.
|
||||
echo -------- DEPLOY started --------------------------------------------------
|
||||
echo.
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying idaapi (common functions, notifywhen)
|
||||
%PY% deploy.py py_idaapi py_cvt.hpp,py_idaapi.hpp,py_idaapi.py,py_notifywhen.hpp,py_notifywhen.py ..\swig\idaapi.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying Graph
|
||||
%PY% deploy.py py_graph py_graph.hpp,py_graph.py ..\swig\graph.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying custview
|
||||
%PY% deploy.py py_custviewer py_custview.py,py_custview.hpp ..\swig\kernwin.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying plgform
|
||||
%PY% deploy.py py_plgform py_plgform.hpp,py_plgform.py ..\swig\kernwin.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying expr
|
||||
%PY% deploy.py py_expr py_expr.hpp,py_expr.py ..\swig\expr.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying cli
|
||||
%PY% deploy.py py_cli py_cli.py,py_cli.hpp ..\swig\kernwin.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying Loader
|
||||
%PY% deploy.py py_loader py_loader.hpp ..\swig\loader.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying kernwin, choose2, askusingform
|
||||
%PY% deploy.py py_kernwin py_kernwin.hpp,py_kernwin.py,py_choose.hpp,py_choose2.hpp,py_choose2.py,py_askusingform.hpp,py_askusingform.py ..\swig\kernwin.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying idd
|
||||
%PY% deploy.py py_idd py_dbg.hpp,py_appcall.py ..\swig\idd.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying nalt
|
||||
%PY% deploy.py py_nalt py_nalt.hpp,py_nalt.py ..\swig\nalt.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying dbg
|
||||
%PY% deploy.py py_dbg py_dbg.hpp ..\swig\dbg.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying linput/diskio
|
||||
%PY% deploy.py py_diskio py_linput.hpp,py_diskio.hpp,py_diskio.py ..\swig\diskio.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying name
|
||||
%PY% deploy.py py_name py_name.hpp,py_name.py ..\swig\name.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying qfile
|
||||
%PY% deploy.py py_qfile py_qfile.hpp ..\swig\fpro.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying bytes
|
||||
%PY% deploy.py py_bytes py_bytes.hpp,py_custdata.py,py_custdata.hpp ..\swig\bytes.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying typeinf
|
||||
%PY% deploy.py py_typeinf py_typeinf.hpp ..\swig\typeinf.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying gdl
|
||||
%PY% deploy.py py_gdl py_gdl.py ..\swig\gdl.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying ua
|
||||
%PY% deploy.py py_ua py_ua.hpp,py_ua.py ..\swig\ua.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying idp
|
||||
%PY% deploy.py py_idp py_idp.hpp ..\swig\idp.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying lines
|
||||
%PY% deploy.py py_lines py_lines.hpp,py_lines.py ..\swig\lines.i
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying pc_win32_appcall
|
||||
%PY% deploy.py appcalltest py_appcall.py ..\..\..\tests\input\pc_win32_appcall.pe.hints
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying ex_custdata example
|
||||
%PY% deploy.py ex_custdata ..\examples\ex_custdata.py ..\..\..\tests\input\pc_win32_custdata1.pe.hints
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying ex_formchooser
|
||||
%PY% deploy.py ex_formchooser py_askusingform.py ..\..\formchooser\formchooser.py
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying ex_askusingform
|
||||
%PY% deploy.py ex_askusingform py_askusingform.py ..\examples\ex_askusingform.py
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying ex_cli example
|
||||
%PY% deploy.py ex_cli_ex1 py_cli.py ..\examples\ex_cli.py
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying ex_expr example
|
||||
%PY% deploy.py ex_expr py_expr.py ..\examples\ex_expr.py
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo Deploying ex_custview.py example
|
||||
%PY% deploy.py py_custviewerex1 py_custview.py ..\examples\ex_custview.py
|
||||
|
||||
rem --------------------------------------------------------------------------
|
||||
echo.
|
||||
echo -------- DEPLOY finished -------------------------------------------------
|
||||
echo.
|
||||
|
||||
:end
|
||||
c:\python27\python.exe deploy_all.py
|
||||
|
@ -13,7 +13,13 @@ def make_re(tag, mod_name, prefix):
|
||||
s = '%(p)s<%(tag)s\(%(m)s\)>(.+?)%(p)s</%(tag)s\(%(m)s\)>' % {'m': mod_name, 'tag': tag, 'p': prefix}
|
||||
return (s, re.compile(s, re.DOTALL))
|
||||
|
||||
def convert_path(path_in):
|
||||
parts = path_in.split('/')
|
||||
return os.sep.join(parts)
|
||||
|
||||
def deploy(mod_name, src_files, dest_file, silent = True):
|
||||
dest_file = convert_path(dest_file)
|
||||
src_files = map(convert_path, src_files)
|
||||
# create regular expressions
|
||||
templates = (
|
||||
('pycode', make_re('pycode', mod_name, '#')),
|
||||
@ -88,4 +94,5 @@ def main(argv = None):
|
||||
deploy(mod_name, src_files, dest_file)
|
||||
|
||||
#main(['', 'py_graph', 'py_graph.hpp,py_graph.py', 'graph.i'])
|
||||
main()
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
194
pywraps/deploy_all.py
Normal file
194
pywraps/deploy_all.py
Normal file
@ -0,0 +1,194 @@
|
||||
# Please use the same tag for the same .i file
|
||||
# That means if many insertions are going to happen in one
|
||||
# given .i file then don't use more than code marking tag
|
||||
|
||||
print "\n-------- DEPLOY started --------------------------------------------------\n"
|
||||
|
||||
deploys = {
|
||||
"idaapi (common functions, notifywhen)" : {
|
||||
"tag" : "py_idaapi",
|
||||
"src" : ["py_cvt.hpp", "py_idaapi.hpp", "py_idaapi.py", "py_notifywhen.hpp", "py_notifywhen.py"],
|
||||
"tgt" : "../swig/idaapi.i"
|
||||
},
|
||||
|
||||
"View (common)" : {
|
||||
"tag" : "py_view_base",
|
||||
"src" : ["py_view_base.hpp", "py_view_base.py"],
|
||||
"tgt" : "../swig/view.i"
|
||||
},
|
||||
|
||||
"IDAView" : {
|
||||
"tag" : "py_idaview",
|
||||
"src" : ["py_idaview.hpp", "py_idaview.py"],
|
||||
"tgt" : "../swig/view.i"
|
||||
},
|
||||
|
||||
"Graph" : {
|
||||
"tag" : "py_graph",
|
||||
"src" : ["py_graph.hpp", "py_graph.py"],
|
||||
"tgt" : "../swig/graph.i"
|
||||
},
|
||||
|
||||
"custview" : {
|
||||
"tag" : "py_custviewer",
|
||||
"src" : ["py_custview.py","py_custview.hpp"],
|
||||
"tgt" : "../swig/kernwin.i"
|
||||
},
|
||||
|
||||
"plgform" : {
|
||||
"tag" : "py_plgform",
|
||||
"src" : ["py_plgform.hpp","py_plgform.py"],
|
||||
"tgt" : "../swig/kernwin.i"
|
||||
},
|
||||
|
||||
"expr" : {
|
||||
"tag" : "py_expr",
|
||||
"src" : ["py_expr.hpp","py_expr.py"],
|
||||
"tgt" : "../swig/expr.i"
|
||||
},
|
||||
|
||||
"cli" : {
|
||||
"tag" : "py_cli",
|
||||
"src" : ["py_cli.py","py_cli.hpp"],
|
||||
"tgt" : "../swig/kernwin.i"
|
||||
},
|
||||
|
||||
"Loader" : {
|
||||
"tag" : "py_loader",
|
||||
"src" : ["py_loader.hpp"],
|
||||
"tgt" : "../swig/loader.i"
|
||||
},
|
||||
|
||||
"kernwin, choose2, askusingform" : {
|
||||
"tag" : "py_kernwin",
|
||||
"src" : ["py_kernwin.hpp","py_kernwin.py","py_choose.hpp","py_choose2.hpp","py_choose2.py","py_askusingform.hpp","py_askusingform.py"],
|
||||
"tgt" : "../swig/kernwin.i"
|
||||
},
|
||||
|
||||
"idd" : {
|
||||
"tag" : "py_idd",
|
||||
"src" : ["py_dbg.hpp","py_appcall.py"],
|
||||
"tgt" : "../swig/idd.i"
|
||||
},
|
||||
|
||||
"idd (python)" : {
|
||||
"tag" : "py_idd_2",
|
||||
"src" : ["py_dbg.py"],
|
||||
"tgt" : "../swig/idd.i"
|
||||
},
|
||||
|
||||
"nalt" : {
|
||||
"tag" : "py_nalt",
|
||||
"src" : ["py_nalt.hpp","py_nalt.py"],
|
||||
"tgt" : "../swig/nalt.i"
|
||||
},
|
||||
|
||||
"dbg" : {
|
||||
"tag" : "py_dbg",
|
||||
"src" : ["py_dbg.hpp"],
|
||||
"tgt" : "../swig/dbg.i"
|
||||
},
|
||||
|
||||
"linput/diskio" : {
|
||||
"tag" : "py_diskio",
|
||||
"src" : ["py_linput.hpp","py_diskio.hpp","py_diskio.py"],
|
||||
"tgt" : "../swig/diskio.i"
|
||||
},
|
||||
|
||||
"name" : {
|
||||
"tag" : "py_name",
|
||||
"src" : ["py_name.hpp","py_name.py"],
|
||||
"tgt" : "../swig/name.i"
|
||||
},
|
||||
|
||||
"qfile" : {
|
||||
"tag" : "py_qfile",
|
||||
"src" : ["py_qfile.hpp"],
|
||||
"tgt" : "../swig/fpro.i"
|
||||
},
|
||||
|
||||
"bytes" : {
|
||||
"tag" : "py_bytes",
|
||||
"src" : ["py_bytes.hpp","py_custdata.py","py_custdata.hpp"],
|
||||
"tgt" : "../swig/bytes.i"
|
||||
},
|
||||
|
||||
"typeinf" : {
|
||||
"tag" : "py_typeinf",
|
||||
"src" : ["py_typeinf.hpp","py_typeinf.py"],
|
||||
"tgt" : "../swig/typeinf.i"
|
||||
},
|
||||
|
||||
"gdl" : {
|
||||
"tag" : "py_gdl",
|
||||
"src" : ["py_gdl.py"],
|
||||
"tgt" : "../swig/gdl.i"
|
||||
},
|
||||
|
||||
"ua" : {
|
||||
"tag" : "py_ua",
|
||||
"src" : ["py_ua.hpp","py_ua.py"],
|
||||
"tgt" : "../swig/ua.i"
|
||||
},
|
||||
|
||||
"idp" : {
|
||||
"tag" : "py_idp",
|
||||
"src" : ["py_idp.hpp"],
|
||||
"tgt" : "../swig/idp.i"
|
||||
},
|
||||
|
||||
"lines" : {
|
||||
"tag" : "py_lines",
|
||||
"src" : ["py_lines.hpp","py_lines.py"],
|
||||
"tgt" : "../swig/lines.i"
|
||||
},
|
||||
|
||||
"pc_win32_appcall" : {
|
||||
"tag" : "appcalltest",
|
||||
"src" : ["py_appcall.py"],
|
||||
"tgt" : "../../../tests/input/pc_win32_appcall.pe.hints"
|
||||
},
|
||||
|
||||
"ex_custdata example" : {
|
||||
"tag" : "ex_custdata",
|
||||
"src" : ["../examples/ex_custdata.py"],
|
||||
"tgt" : "../../../tests/input/pc_win32_custdata1.pe.hints"
|
||||
},
|
||||
|
||||
"ex_formchooser" : {
|
||||
"tag" : "ex_formchooser",
|
||||
"src" : ["py_askusingform.py"],
|
||||
"tgt" : "../../formchooser/formchooser.py"
|
||||
},
|
||||
|
||||
"ex_askusingform" : {
|
||||
"tag" : "ex_askusingform",
|
||||
"src" : ["py_askusingform.py"],
|
||||
"tgt" : "../examples/ex_askusingform.py"
|
||||
},
|
||||
|
||||
"ex_cli example" : {
|
||||
"tag" : "ex_cli_ex1",
|
||||
"src" : ["py_cli.py"],
|
||||
"tgt" : "../examples/ex_cli.py"
|
||||
},
|
||||
|
||||
"ex_expr example" : {
|
||||
"tag" : "ex_expr",
|
||||
"src" : ["py_expr.py"],
|
||||
"tgt" : "../examples/ex_expr.py"
|
||||
},
|
||||
|
||||
"ex_custview.py example" : {
|
||||
"tag" : "py_custviewerex1",
|
||||
"src" : ["py_custview.py"],
|
||||
"tgt" : "../examples/ex_custview.py"
|
||||
}
|
||||
}
|
||||
|
||||
import deploy
|
||||
for name in deploys:
|
||||
data = deploys[name]
|
||||
print "Deploying %s" % name
|
||||
deploy.deploy(data["tag"], data["src"], data["tgt"])
|
||||
|
@ -58,7 +58,8 @@ static PyObject *ex_pytoidc(
|
||||
return NULL;
|
||||
idc_value_t v;
|
||||
int sn = 0;
|
||||
if ( pyvar_to_idcvar(self, &v, &sn) < CIP_OK )
|
||||
borref_t self_ref(self);
|
||||
if ( pyvar_to_idcvar(self_ref, &v, &sn) < CIP_OK )
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_TRUE;
|
||||
}
|
||||
@ -75,4 +76,4 @@ static PyMethodDef py_methods_dbg[] =
|
||||
{"pytoidc", ex_pytoidc, METH_VARARGS, ""},
|
||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||
};
|
||||
DRIVER_INIT_METHODS(dbg);
|
||||
DRIVER_INIT_METHODS(dbg);
|
||||
|
@ -162,7 +162,7 @@ class Appcall_callable__(object):
|
||||
def __get_size(self):
|
||||
if self.__type == None:
|
||||
return -1
|
||||
r = _idaapi.get_type_size0(_idaapi.cvar.idati, self.__type)
|
||||
r = _idaapi.calc_type_size(_idaapi.cvar.idati, self.__type)
|
||||
if not r:
|
||||
return -1
|
||||
return r
|
||||
@ -658,6 +658,46 @@ def test_pck_bv():
|
||||
return 1
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
def test_local_types():
|
||||
(type, fields) = GetLocalTinfo(1)
|
||||
if not type:
|
||||
return -1
|
||||
decl = GetLocalType(1, PRTYPE_MULTI)
|
||||
if decl != "enum\n"\
|
||||
+ "{\n"\
|
||||
+ " FEATURE_OBJECT_CACHING = 0x0,\n"\
|
||||
+ " FEATURE_ZONE_ELEVATION = 0x1,\n"\
|
||||
+ " FEATURE_MIME_HANDLING = 0x2,\n"\
|
||||
+ " FEATURE_MIME_SNIFFING = 0x3,\n"\
|
||||
+ " FEATURE_WINDOW_RESTRICTIONS = 0x4,\n"\
|
||||
+ " FEATURE_WEBOC_POPUPMANAGEMENT = 0x5,\n"\
|
||||
+ " FEATURE_BEHAVIORS = 0x6,\n"\
|
||||
+ " FEATURE_DISABLE_MK_PROTOCOL = 0x7,\n"\
|
||||
+ " FEATURE_LOCALMACHINE_LOCKDOWN = 0x8,\n"\
|
||||
+ " FEATURE_SECURITYBAND = 0x9,\n"\
|
||||
+ " FEATURE_RESTRICT_ACTIVEXINSTALL = 0xA,\n"\
|
||||
+ " FEATURE_VALIDATE_NAVIGATE_URL = 0xB,\n"\
|
||||
+ " FEATURE_RESTRICT_FILEDOWNLOAD = 0xC,\n"\
|
||||
+ " FEATURE_ADDON_MANAGEMENT = 0xD,\n"\
|
||||
+ " FEATURE_PROTOCOL_LOCKDOWN = 0xE,\n"\
|
||||
+ " FEATURE_HTTP_USERNAME_PASSWORD_DISABLE = 0xF,\n"\
|
||||
+ " FEATURE_SAFE_BINDTOOBJECT = 0x10,\n"\
|
||||
+ " FEATURE_UNC_SAVEDFILECHECK = 0x11,\n"\
|
||||
+ " FEATURE_GET_URL_DOM_FILEPATH_UNENCODED = 0x12,\n"\
|
||||
+ " FEATURE_TABBED_BROWSING = 0x13,\n"\
|
||||
+ " FEATURE_SSLUX = 0x14,\n"\
|
||||
+ " FEATURE_DISABLE_NAVIGATION_SOUNDS = 0x15,\n"\
|
||||
+ " FEATURE_DISABLE_LEGACY_COMPRESSION = 0x16,\n"\
|
||||
+ " FEATURE_FORCE_ADDR_AND_STATUS = 0x17,\n"\
|
||||
+ " FEATURE_XMLHTTP = 0x18,\n"\
|
||||
+ " FEATURE_DISABLE_TELNET_PROTOCOL = 0x19,\n"\
|
||||
+ " FEATURE_FEEDS = 0x1A,\n"\
|
||||
+ " FEATURE_BLOCK_INPUT_PROMPTS = 0x1B,\n"\
|
||||
+ " FEATURE_ENTRY_COUNT = 0x1C,\n"\
|
||||
+ "} _tagINTERNETFEATURELIST\n":
|
||||
print "decl = " + decl
|
||||
return -2
|
||||
return 1
|
||||
# various tests
|
||||
def test1(stage):
|
||||
# call a method that takes a string buffer and appends a dot to its end
|
||||
@ -891,7 +931,7 @@ def test_exec_throw():
|
||||
# -----------------------------------------------------------------------
|
||||
# all the tests that take zero parameters
|
||||
tests0 = (test_gpa, test_pck_idb_raw, test_pck_bv_raw,
|
||||
test_unpack_raw, test_pck_idb, test_pck_bv,
|
||||
test_unpack_raw, test_pck_idb, test_pck_bv, test_local_types,
|
||||
test_enum_files, test2, test_exec_throw, test_loaddll)
|
||||
test_log = None # test log file
|
||||
|
||||
|
@ -142,6 +142,7 @@ static PyObject *formchgcbfa_get_field_value(
|
||||
size_t sz)
|
||||
{
|
||||
DECLARE_FORM_ACTIONS;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
switch ( ft )
|
||||
{
|
||||
case 8:
|
||||
@ -213,7 +214,9 @@ static PyObject *formchgcbfa_get_field_value(
|
||||
for ( intvec_t::iterator it=intvec.begin(); it != intvec.end(); ++it)
|
||||
(*it)--;
|
||||
|
||||
return PyW_IntVecToPyList(intvec);
|
||||
ref_t l(PyW_IntVecToPyList(intvec));
|
||||
l.incref();
|
||||
return l.o;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -276,6 +279,7 @@ static bool formchgcbfa_set_field_value(
|
||||
PyObject *py_val)
|
||||
{
|
||||
DECLARE_FORM_ACTIONS;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
switch ( ft )
|
||||
{
|
||||
|
@ -5,20 +5,17 @@
|
||||
//------------------------------------------------------------------------
|
||||
static bool idaapi py_testf_cb(flags_t flags, void *ud)
|
||||
{
|
||||
PyObject *py_flags = PyLong_FromUnsignedLong(flags);
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *result = PyObject_CallFunctionObjArgs((PyObject *) ud, py_flags, NULL);
|
||||
PYW_GIL_RELEASE;
|
||||
bool ret = result != NULL && PyObject_IsTrue(result);
|
||||
Py_XDECREF(result);
|
||||
Py_XDECREF(py_flags);
|
||||
return ret;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t py_flags(PyLong_FromUnsignedLong(flags));
|
||||
newref_t result(PyObject_CallFunctionObjArgs((PyObject *) ud, py_flags.o, NULL));
|
||||
return result != NULL && PyObject_IsTrue(result.o);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Wraps the (next|prev)that()
|
||||
static ea_t py_npthat(ea_t ea, ea_t bound, PyObject *py_callable, bool next)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyCallable_Check(py_callable) )
|
||||
return BADADDR;
|
||||
else
|
||||
@ -33,20 +30,17 @@ static int idaapi py_visit_patched_bytes_cb(
|
||||
uint32 v,
|
||||
void *ud)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallFunction(
|
||||
(PyObject *)ud,
|
||||
PY_FMT64 "iII",
|
||||
pyul_t(ea),
|
||||
fpos,
|
||||
o,
|
||||
v);
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t py_result(
|
||||
PyObject_CallFunction(
|
||||
(PyObject *)ud,
|
||||
PY_FMT64 "iII",
|
||||
pyul_t(ea),
|
||||
fpos,
|
||||
o,
|
||||
v));
|
||||
PyW_ShowCbErr("visit_patched_bytes");
|
||||
int ret = (py_result != NULL && PyInt_Check(py_result)) ? PyInt_AsLong(py_result) : 0;
|
||||
Py_XDECREF(py_result);
|
||||
return ret;
|
||||
return (py_result != NULL && PyInt_Check(py_result.o)) ? PyInt_AsLong(py_result.o) : 0;
|
||||
}
|
||||
//</code(py_bytes)>
|
||||
//------------------------------------------------------------------------
|
||||
@ -74,6 +68,7 @@ def visit_patched_bytes(ea1, ea2, callable):
|
||||
*/
|
||||
static int py_visit_patched_bytes(ea_t ea1, ea_t ea2, PyObject *py_callable)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyCallable_Check(py_callable) )
|
||||
return 0;
|
||||
else
|
||||
@ -122,29 +117,23 @@ def get_many_bytes(ea, size):
|
||||
*/
|
||||
static PyObject *py_get_many_bytes(ea_t ea, unsigned int size)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
do
|
||||
{
|
||||
if ( size <= 0 )
|
||||
break;
|
||||
|
||||
// Allocate memory via Python
|
||||
PyObject *py_buf = PyString_FromStringAndSize(NULL, Py_ssize_t(size));
|
||||
newref_t py_buf(PyString_FromStringAndSize(NULL, Py_ssize_t(size)));
|
||||
if ( py_buf == NULL )
|
||||
break;
|
||||
|
||||
// Read bytes
|
||||
bool ok = get_many_bytes(ea, PyString_AsString(py_buf), size);
|
||||
if ( !get_many_bytes(ea, PyString_AsString(py_buf.o), size) )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
// If failed, dispose the Python string
|
||||
if ( !ok )
|
||||
{
|
||||
Py_DECREF(py_buf);
|
||||
|
||||
py_buf = Py_None;
|
||||
Py_INCREF(py_buf);
|
||||
}
|
||||
|
||||
return py_buf;
|
||||
py_buf.incref();
|
||||
return py_buf.o;
|
||||
} while ( false );
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
@ -195,9 +184,11 @@ static PyObject *py_get_ascii_contents2(
|
||||
}
|
||||
if ( type == ASCSTR_C && used_size > 0 && buf[used_size-1] == '\0' )
|
||||
used_size--;
|
||||
PyObject *py_buf = PyString_FromStringAndSize((const char *)buf, used_size);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t py_buf(PyString_FromStringAndSize((const char *)buf, used_size));
|
||||
qfree(buf);
|
||||
return py_buf;
|
||||
py_buf.incref();
|
||||
return py_buf.o;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
/*
|
||||
|
@ -6,45 +6,35 @@
|
||||
//---------------------------------------------------------------------------
|
||||
uint32 idaapi choose_sizer(void *self)
|
||||
{
|
||||
PyObject *pyres;
|
||||
uint32 res;
|
||||
|
||||
PYW_GIL_ENSURE;
|
||||
pyres = PyObject_CallMethod((PyObject *)self, "sizer", "");
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
res = PyInt_AsLong(pyres);
|
||||
Py_DECREF(pyres);
|
||||
return res;
|
||||
PYW_GIL_GET;
|
||||
newref_t pyres(PyObject_CallMethod((PyObject *)self, "sizer", ""));
|
||||
return PyInt_AsLong(pyres.o);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
char *idaapi choose_getl(void *self, uint32 n, char *buf)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *pyres = PyObject_CallMethod(
|
||||
(PyObject *)self,
|
||||
"getl",
|
||||
"l",
|
||||
n);
|
||||
PYW_GIL_RELEASE;
|
||||
PYW_GIL_GET;
|
||||
newref_t pyres(
|
||||
PyObject_CallMethod(
|
||||
(PyObject *)self,
|
||||
"getl",
|
||||
"l",
|
||||
n));
|
||||
|
||||
const char *res;
|
||||
if (pyres == NULL || (res = PyString_AsString(pyres)) == NULL )
|
||||
if (pyres == NULL || (res = PyString_AsString(pyres.o)) == NULL )
|
||||
qstrncpy(buf, "<Empty>", MAXSTR);
|
||||
else
|
||||
qstrncpy(buf, res, MAXSTR);
|
||||
|
||||
Py_XDECREF(pyres);
|
||||
return buf;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void idaapi choose_enter(void *self, uint32 n)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
Py_XDECREF(PyObject_CallMethod((PyObject *)self, "enter", "l", n));
|
||||
PYW_GIL_RELEASE;
|
||||
PYW_GIL_GET;
|
||||
newref_t res(PyObject_CallMethod((PyObject *)self, "enter", "l", n));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@ -57,8 +47,9 @@ uint32 choose_choose(
|
||||
int deflt,
|
||||
int icon)
|
||||
{
|
||||
PyObject *pytitle = PyObject_GetAttrString((PyObject *)self, "title");
|
||||
const char *title = pytitle != NULL ? PyString_AsString(pytitle) : "Choose";
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t pytitle(PyObject_GetAttrString((PyObject *)self, "title"));
|
||||
const char *title = pytitle != NULL ? PyString_AsString(pytitle.o) : "Choose";
|
||||
|
||||
int r = choose(
|
||||
flags,
|
||||
@ -79,9 +70,9 @@ uint32 choose_choose(
|
||||
NULL, /* destroy */
|
||||
NULL, /* popup_names */
|
||||
NULL);/* get_icon */
|
||||
Py_XDECREF(pytitle);
|
||||
|
||||
return r;
|
||||
}
|
||||
//</inline(py_kernwin)>
|
||||
|
||||
#endif // __PY_CHOOSE__
|
||||
#endif // __PY_CHOOSE__
|
||||
|
@ -11,8 +11,8 @@
|
||||
#define thisdecl py_choose2_t *_this = thisobj
|
||||
#define MENU_COMMAND_CB(id) \
|
||||
static uint32 idaapi s_menu_command_##id(void *obj, uint32 n) \
|
||||
{ \
|
||||
return thisobj->on_command(id, int(n)); \
|
||||
{ \
|
||||
return thisobj->on_command(id, int(n)); \
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
@ -100,6 +100,9 @@ private:
|
||||
//------------------------------------------------------------------------
|
||||
static int idaapi ui_cb(void *obj, int notification_code, va_list va)
|
||||
{
|
||||
// This hook gets called from the kernel. Ensure we hold the GIL.
|
||||
PYW_GIL_GET;
|
||||
|
||||
// UI callback to handle chooser items with attributes
|
||||
if ( notification_code != ui_get_chooser_item_attrs )
|
||||
return 0;
|
||||
@ -209,6 +212,9 @@ private:
|
||||
|
||||
void on_get_line(int lineno, char * const *line_arr)
|
||||
{
|
||||
// Called from s_getl, which itself can be called from the kernel. Ensure GIL
|
||||
PYW_GIL_GET;
|
||||
|
||||
// Get headers?
|
||||
if ( lineno == 0 )
|
||||
{
|
||||
@ -224,64 +230,51 @@ private:
|
||||
line_arr[i][0] = '\0';
|
||||
|
||||
// Call Python
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *list = PyObject_CallMethod(self, (char *)S_ON_GET_LINE, "i", lineno - 1);
|
||||
PYW_GIL_RELEASE;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t list(PyObject_CallMethod(self, (char *)S_ON_GET_LINE, "i", lineno - 1));
|
||||
if ( list == NULL )
|
||||
return;
|
||||
|
||||
// Go over the List returned by Python and convert to C strings
|
||||
for ( int i=ncols-1; i>=0; i-- )
|
||||
{
|
||||
PyObject *item = PyList_GetItem(list, Py_ssize_t(i));
|
||||
borref_t item(PyList_GetItem(list.o, Py_ssize_t(i)));
|
||||
if ( item == NULL )
|
||||
continue;
|
||||
|
||||
const char *str = PyString_AsString(item);
|
||||
const char *str = PyString_AsString(item.o);
|
||||
if ( str != NULL )
|
||||
qstrncpy(line_arr[i], str, MAXSTR);
|
||||
}
|
||||
Py_DECREF(list);
|
||||
}
|
||||
|
||||
size_t on_get_size()
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_GET_SIZE, NULL);
|
||||
PYW_GIL_RELEASE;
|
||||
PYW_GIL_GET;
|
||||
newref_t pyres(PyObject_CallMethod(self, (char *)S_ON_GET_SIZE, NULL));
|
||||
if ( pyres == NULL )
|
||||
return 0;
|
||||
|
||||
size_t res = PyInt_AsLong(pyres);
|
||||
Py_DECREF(pyres);
|
||||
return res;
|
||||
return PyInt_AsLong(pyres.o);
|
||||
}
|
||||
|
||||
void on_refreshed()
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_REFRESHED, NULL);
|
||||
PYW_GIL_RELEASE;
|
||||
Py_XDECREF(pyres);
|
||||
PYW_GIL_GET;
|
||||
newref_t pyres(PyObject_CallMethod(self, (char *)S_ON_REFRESHED, NULL));
|
||||
}
|
||||
|
||||
void on_select(const intvec_t &intvec)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_list = PyW_IntVecToPyList(intvec);
|
||||
PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_SELECT, "O", py_list);
|
||||
PYW_GIL_RELEASE;
|
||||
Py_XDECREF(pyres);
|
||||
Py_XDECREF(py_list);
|
||||
PYW_GIL_GET;
|
||||
ref_t py_list(PyW_IntVecToPyList(intvec));
|
||||
newref_t pyres(PyObject_CallMethod(self, (char *)S_ON_SELECT, "O", py_list.o));
|
||||
}
|
||||
|
||||
void on_close()
|
||||
{
|
||||
// Call Python
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_CLOSE, NULL);
|
||||
PYW_GIL_RELEASE;
|
||||
Py_XDECREF(pyres);
|
||||
PYW_GIL_GET;
|
||||
newref_t pyres(PyObject_CallMethod(self, (char *)S_ON_CLOSE, NULL));
|
||||
|
||||
// Delete this instance if none modal and not embedded
|
||||
if ( !is_modal() && get_embedded() == NULL )
|
||||
@ -290,123 +283,96 @@ private:
|
||||
|
||||
int on_delete_line(int lineno)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *pyres = PyObject_CallMethod(
|
||||
self,
|
||||
(char *)S_ON_DELETE_LINE,
|
||||
"i",
|
||||
lineno - 1);
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
if ( pyres == NULL )
|
||||
return lineno;
|
||||
|
||||
size_t res = PyInt_AsLong(pyres);
|
||||
Py_DECREF(pyres);
|
||||
return res + 1;
|
||||
PYW_GIL_GET;
|
||||
newref_t pyres(
|
||||
PyObject_CallMethod(
|
||||
self,
|
||||
(char *)S_ON_DELETE_LINE,
|
||||
"i",
|
||||
lineno - 1));
|
||||
return pyres == NULL ? lineno : PyInt_AsLong(pyres.o) + 1;
|
||||
}
|
||||
|
||||
int on_refresh(int lineno)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *pyres = PyObject_CallMethod(
|
||||
self,
|
||||
(char *)S_ON_REFRESH,
|
||||
"i",
|
||||
lineno - 1);
|
||||
PYW_GIL_RELEASE;
|
||||
if ( pyres == NULL )
|
||||
return lineno;
|
||||
|
||||
size_t res = PyInt_AsLong(pyres);
|
||||
Py_DECREF(pyres);
|
||||
return res + 1;
|
||||
PYW_GIL_GET;
|
||||
newref_t pyres(
|
||||
PyObject_CallMethod(
|
||||
self,
|
||||
(char *)S_ON_REFRESH,
|
||||
"i",
|
||||
lineno - 1));
|
||||
return pyres == NULL ? lineno : PyInt_AsLong(pyres.o) + 1;
|
||||
}
|
||||
|
||||
void on_insert_line()
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_INSERT_LINE, NULL);
|
||||
PYW_GIL_RELEASE;
|
||||
Py_XDECREF(pyres);
|
||||
PYW_GIL_GET;
|
||||
newref_t pyres(PyObject_CallMethod(self, (char *)S_ON_INSERT_LINE, NULL));
|
||||
}
|
||||
|
||||
void on_enter(int lineno)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *pyres = PyObject_CallMethod(
|
||||
self,
|
||||
(char *)S_ON_SELECT_LINE,
|
||||
"i",
|
||||
lineno - 1);
|
||||
PYW_GIL_RELEASE;
|
||||
Py_XDECREF(pyres);
|
||||
PYW_GIL_GET;
|
||||
newref_t pyres(
|
||||
PyObject_CallMethod(
|
||||
self,
|
||||
(char *)S_ON_SELECT_LINE,
|
||||
"i",
|
||||
lineno - 1));
|
||||
}
|
||||
|
||||
void on_edit_line(int lineno)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *pyres = PyObject_CallMethod(
|
||||
self,
|
||||
(char *)S_ON_EDIT_LINE,
|
||||
"i",
|
||||
lineno - 1);
|
||||
PYW_GIL_RELEASE;
|
||||
Py_XDECREF(pyres);
|
||||
PYW_GIL_GET;
|
||||
newref_t pyres(
|
||||
PyObject_CallMethod(
|
||||
self,
|
||||
(char *)S_ON_EDIT_LINE,
|
||||
"i",
|
||||
lineno - 1));
|
||||
}
|
||||
|
||||
int on_command(int cmd_id, int lineno)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *pyres = PyObject_CallMethod(
|
||||
self,
|
||||
(char *)S_ON_COMMAND,
|
||||
"ii",
|
||||
lineno - 1,
|
||||
cmd_id);
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
if ( pyres==NULL )
|
||||
return lineno;
|
||||
|
||||
size_t res = PyInt_AsLong(pyres);
|
||||
Py_XDECREF(pyres);
|
||||
return res;
|
||||
PYW_GIL_GET;
|
||||
newref_t pyres(
|
||||
PyObject_CallMethod(
|
||||
self,
|
||||
(char *)S_ON_COMMAND,
|
||||
"ii",
|
||||
lineno - 1,
|
||||
cmd_id));
|
||||
return pyres == NULL ? lineno : PyInt_AsLong(pyres.o);
|
||||
}
|
||||
|
||||
int on_get_icon(int lineno)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *pyres = PyObject_CallMethod(
|
||||
self,
|
||||
(char *)S_ON_GET_ICON,
|
||||
"i",
|
||||
lineno - 1);
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
size_t res = PyInt_AsLong(pyres);
|
||||
Py_XDECREF(pyres);
|
||||
return res;
|
||||
PYW_GIL_GET;
|
||||
newref_t pyres(
|
||||
PyObject_CallMethod(
|
||||
self,
|
||||
(char *)S_ON_GET_ICON,
|
||||
"i",
|
||||
lineno - 1));
|
||||
return PyInt_AsLong(pyres.o);
|
||||
}
|
||||
|
||||
void on_get_line_attr(int lineno, chooser_item_attrs_t *attr)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_GET_LINE_ATTR, "i", lineno - 1);
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
if ( pyres == NULL )
|
||||
return;
|
||||
|
||||
if ( PyList_Check(pyres) )
|
||||
PYW_GIL_GET;
|
||||
newref_t pyres(PyObject_CallMethod(self, (char *)S_ON_GET_LINE_ATTR, "i", lineno - 1));
|
||||
if ( pyres != NULL )
|
||||
{
|
||||
PyObject *item;
|
||||
if ( (item = PyList_GetItem(pyres, 0)) != NULL )
|
||||
attr->color = PyInt_AsLong(item);
|
||||
if ( (item = PyList_GetItem(pyres, 1)) != NULL )
|
||||
attr->flags = PyInt_AsLong(item);
|
||||
if ( PyList_Check(pyres.o) )
|
||||
{
|
||||
PyObject *item;
|
||||
if ( (item = PyList_GetItem(pyres.o, 0)) != NULL )
|
||||
attr->color = PyInt_AsLong(item);
|
||||
if ( (item = PyList_GetItem(pyres.o, 1)) != NULL )
|
||||
attr->flags = PyInt_AsLong(item);
|
||||
}
|
||||
}
|
||||
Py_XDECREF(pyres);
|
||||
}
|
||||
|
||||
public:
|
||||
@ -496,7 +462,7 @@ public:
|
||||
|
||||
// Adjust the title
|
||||
ptitle = title_buf;
|
||||
|
||||
|
||||
// Adjust the caption
|
||||
p = strtok(NULL, delimiter);
|
||||
caption += (p - temp);
|
||||
@ -507,12 +473,12 @@ public:
|
||||
}
|
||||
|
||||
if ( !add_chooser_command(
|
||||
ptitle,
|
||||
caption,
|
||||
menu_cbs[menu_cb_idx],
|
||||
menu_index,
|
||||
icon,
|
||||
flags))
|
||||
ptitle,
|
||||
caption,
|
||||
menu_cbs[menu_cb_idx],
|
||||
menu_index,
|
||||
icon,
|
||||
flags))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@ -525,83 +491,71 @@ public:
|
||||
// Otherwise the chooser window is created and displayed
|
||||
int create(PyObject *self)
|
||||
{
|
||||
PyObject *attr;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
// Get flags
|
||||
attr = PyW_TryGetAttrString(self, S_FLAGS);
|
||||
if ( attr == NULL )
|
||||
ref_t flags_attr(PyW_TryGetAttrString(self, S_FLAGS));
|
||||
if ( flags_attr == NULL )
|
||||
return -1;
|
||||
|
||||
flags = PyInt_Check(attr) != 0 ? PyInt_AsLong(attr) : 0;
|
||||
Py_DECREF(attr);
|
||||
flags = PyInt_Check(flags_attr.o) != 0 ? PyInt_AsLong(flags_attr.o) : 0;
|
||||
|
||||
// Get the title
|
||||
if ( !PyW_GetStringAttr(self, S_TITLE, &title) )
|
||||
return -1;
|
||||
|
||||
// Get columns
|
||||
attr = PyW_TryGetAttrString(self, "cols");
|
||||
if ( attr == NULL )
|
||||
ref_t cols_attr(PyW_TryGetAttrString(self, "cols"));
|
||||
if ( cols_attr == NULL )
|
||||
return -1;
|
||||
|
||||
// Get col count
|
||||
int ncols = int(PyList_Size(attr));
|
||||
int ncols = int(PyList_Size(cols_attr.o));
|
||||
|
||||
// Get cols caption and widthes
|
||||
cols.qclear();
|
||||
for ( int i=0; i<ncols; i++ )
|
||||
{
|
||||
// get list item: [name, width]
|
||||
PyObject *list = PyList_GetItem(attr, i);
|
||||
PyObject *v = PyList_GetItem(list, 0);
|
||||
borref_t list(PyList_GetItem(cols_attr.o, i));
|
||||
borref_t v(PyList_GetItem(list.o, 0));
|
||||
|
||||
// Extract string
|
||||
const char *str = v == NULL ? "" : PyString_AsString(v);
|
||||
const char *str = v == NULL ? "" : PyString_AsString(v.o);
|
||||
cols.push_back(str);
|
||||
|
||||
// Extract width
|
||||
int width;
|
||||
v = PyList_GetItem(list, 1);
|
||||
borref_t v2(PyList_GetItem(list.o, 1));
|
||||
// No width? Guess width from column title
|
||||
if ( v == NULL )
|
||||
if ( v2 == NULL )
|
||||
width = strlen(str);
|
||||
else
|
||||
width = PyInt_AsLong(v);
|
||||
width = PyInt_AsLong(v2.o);
|
||||
widths.push_back(width);
|
||||
}
|
||||
Py_DECREF(attr);
|
||||
|
||||
// Get *deflt
|
||||
int deflt = -1;
|
||||
attr = PyW_TryGetAttrString(self, "deflt");
|
||||
if ( attr != NULL )
|
||||
{
|
||||
deflt = PyInt_AsLong(attr);
|
||||
Py_DECREF(attr);
|
||||
}
|
||||
ref_t deflt_attr(PyW_TryGetAttrString(self, "deflt"));
|
||||
if ( deflt_attr != NULL )
|
||||
deflt = PyInt_AsLong(deflt_attr.o);
|
||||
|
||||
// Get *icon
|
||||
int icon = -1;
|
||||
if ( (attr = PyW_TryGetAttrString(self, "icon")) != NULL )
|
||||
{
|
||||
icon = PyInt_AsLong(attr);
|
||||
Py_DECREF(attr);
|
||||
}
|
||||
ref_t icon_attr(PyW_TryGetAttrString(self, "icon"));
|
||||
if ( icon_attr != NULL )
|
||||
icon = PyInt_AsLong(icon_attr.o);
|
||||
|
||||
// Get *x1,y1,x2,y2
|
||||
int pts[4];
|
||||
static const char *pt_attrs[qnumber(pts)] = {"x1", "y1", "x2", "y2"};
|
||||
for ( size_t i=0; i < qnumber(pts); i++ )
|
||||
{
|
||||
if ( (attr = PyW_TryGetAttrString(self, pt_attrs[i])) == NULL )
|
||||
{
|
||||
ref_t pt_attr(PyW_TryGetAttrString(self, pt_attrs[i]));
|
||||
if ( pt_attr == NULL )
|
||||
pts[i] = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pts[i] = PyInt_AsLong(attr);
|
||||
Py_DECREF(attr);
|
||||
}
|
||||
pts[i] = PyInt_AsLong(pt_attr.o);
|
||||
}
|
||||
|
||||
// Check what callbacks we have
|
||||
@ -628,10 +582,8 @@ public:
|
||||
cb_flags = 0;
|
||||
for ( int i=0; i<qnumber(callbacks); i++ )
|
||||
{
|
||||
attr = attr = PyW_TryGetAttrString(self, callbacks[i].name);
|
||||
bool have_cb = attr != NULL && PyCallable_Check(attr) != 0;
|
||||
Py_XDECREF(attr);
|
||||
|
||||
ref_t cb_attr(PyW_TryGetAttrString(self, callbacks[i].name));
|
||||
bool have_cb = cb_attr != NULL && PyCallable_Check(cb_attr.o) != 0;
|
||||
if ( have_cb )
|
||||
{
|
||||
cb_flags |= callbacks[i].have;
|
||||
@ -646,19 +598,18 @@ public:
|
||||
|
||||
// Get *popup names
|
||||
// An array of 4 strings: ("Insert", "Delete", "Edit", "Refresh"
|
||||
attr = PyW_TryGetAttrString(self, S_POPUP_NAMES);
|
||||
if ( (attr != NULL)
|
||||
&& PyList_Check(attr)
|
||||
&& PyList_Size(attr) == POPUP_NAMES_COUNT )
|
||||
ref_t pn_attr(PyW_TryGetAttrString(self, S_POPUP_NAMES));
|
||||
if ( (pn_attr != NULL)
|
||||
&& PyList_Check(pn_attr.o)
|
||||
&& PyList_Size(pn_attr.o) == POPUP_NAMES_COUNT )
|
||||
{
|
||||
popup_names = new const char *[POPUP_NAMES_COUNT];
|
||||
for ( int i=0; i<POPUP_NAMES_COUNT; i++ )
|
||||
{
|
||||
const char *str = PyString_AsString(PyList_GetItem(attr, i));
|
||||
const char *str = PyString_AsString(PyList_GetItem(pn_attr.o, i));
|
||||
popup_names[i] = qstrdup(str);
|
||||
}
|
||||
}
|
||||
Py_XDECREF(attr);
|
||||
|
||||
// Adjust flags (if needed)
|
||||
if ( (cb_flags & CHOOSE2_HAVE_GETATTR) != 0 )
|
||||
@ -672,8 +623,8 @@ public:
|
||||
install_hooks(true);
|
||||
|
||||
// Check if *embedded
|
||||
attr = PyW_TryGetAttrString(self, S_EMBEDDED);
|
||||
if ( attr != NULL && PyObject_IsTrue(attr) == 1 )
|
||||
ref_t emb_attr(PyW_TryGetAttrString(self, S_EMBEDDED));
|
||||
if ( emb_attr != NULL && PyObject_IsTrue(emb_attr.o) == 1 )
|
||||
{
|
||||
// Create an embedded chooser structure
|
||||
embedded = new chooser_info_t();
|
||||
@ -710,7 +661,6 @@ public:
|
||||
embedded->refresh = NULL;
|
||||
}
|
||||
}
|
||||
Py_XDECREF(attr);
|
||||
|
||||
// Create the chooser (if not embedded)
|
||||
int r;
|
||||
@ -873,6 +823,8 @@ void choose2_activate(PyObject *self)
|
||||
//------------------------------------------------------------------------
|
||||
PyObject *choose2_get_embedded_selection(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
py_choose2_t *c2 = choose2_find_instance(self);
|
||||
chooser_info_t *embedded;
|
||||
|
||||
@ -886,13 +838,17 @@ PyObject *choose2_get_embedded_selection(PyObject *self)
|
||||
for ( intvec_t::iterator it=intvec.begin(); it != intvec.end(); ++it)
|
||||
(*it)--;
|
||||
|
||||
return PyW_IntVecToPyList(intvec);
|
||||
ref_t ret(PyW_IntVecToPyList(intvec));
|
||||
ret.incref();
|
||||
return ret.o;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Return the C instances as 64bit numbers
|
||||
PyObject *choose2_get_embedded(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
py_choose2_t *c2 = choose2_find_instance(self);
|
||||
chooser_info_t *embedded;
|
||||
|
||||
@ -945,12 +901,12 @@ PyObject *choose2_get_embedded_selection(PyObject *self);
|
||||
|
||||
static void NT_CDECL choose2_test_embedded(chooser_info_t *embedded)
|
||||
{
|
||||
msg("cb=%d -> looks %valid\n",
|
||||
embedded->cb,
|
||||
msg("cb=%d -> looks %valid\n",
|
||||
embedded->cb,
|
||||
embedded->cb == sizeof(chooser_info_t) ? "" : "in");
|
||||
}
|
||||
static size_t choose2_get_test_embedded()
|
||||
{
|
||||
return (size_t)choose2_test_embedded;
|
||||
}
|
||||
#endif // __PY_CHOOSE2__
|
||||
#endif // __PY_CHOOSE2__
|
||||
|
@ -37,17 +37,17 @@ private:
|
||||
static py_cli_t *py_clis[MAX_PY_CLI];
|
||||
static const py_cli_cbs_t py_cli_cbs[MAX_PY_CLI];
|
||||
//--------------------------------------------------------------------------
|
||||
#define IMPL_PY_CLI_CB(CBN) \
|
||||
#define IMPL_PY_CLI_CB(CBN) \
|
||||
static bool idaapi s_keydown##CBN(qstring *line, int *p_x, int *p_sellen, int *vk_key, int shift) \
|
||||
{ \
|
||||
{ \
|
||||
return py_clis[CBN]->on_keydown(line, p_x, p_sellen, vk_key, shift); \
|
||||
} \
|
||||
static bool idaapi s_execute_line##CBN(const char *line) \
|
||||
{ \
|
||||
return py_clis[CBN]->on_execute_line(line); \
|
||||
} \
|
||||
} \
|
||||
static bool idaapi s_execute_line##CBN(const char *line) \
|
||||
{ \
|
||||
return py_clis[CBN]->on_execute_line(line); \
|
||||
} \
|
||||
static bool idaapi s_complete_line##CBN(qstring *completion, const char *prefix, int n, const char *line, int x) \
|
||||
{ \
|
||||
{ \
|
||||
return py_clis[CBN]->on_complete_line(completion, prefix, n, line, x); \
|
||||
}
|
||||
|
||||
@ -62,18 +62,15 @@ private:
|
||||
// Returns: true-executed line, false-ask for more lines
|
||||
bool on_execute_line(const char *line)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *result = PyObject_CallMethod(
|
||||
self,
|
||||
(char *)S_ON_EXECUTE_LINE,
|
||||
"s",
|
||||
line);
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
bool ok = result != NULL && PyObject_IsTrue(result);
|
||||
PYW_GIL_GET;
|
||||
newref_t result(
|
||||
PyObject_CallMethod(
|
||||
self,
|
||||
(char *)S_ON_EXECUTE_LINE,
|
||||
"s",
|
||||
line));
|
||||
PyW_ShowCbErr(S_ON_EXECUTE_LINE);
|
||||
Py_XDECREF(result);
|
||||
return ok;
|
||||
return result != NULL && PyObject_IsTrue(result.o);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@ -95,41 +92,45 @@ private:
|
||||
int *vk_key,
|
||||
int shift)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *result = PyObject_CallMethod(
|
||||
self,
|
||||
(char *)S_ON_KEYDOWN,
|
||||
"siiHi",
|
||||
line->c_str(),
|
||||
*p_x,
|
||||
*p_sellen,
|
||||
*vk_key,
|
||||
shift);
|
||||
PYW_GIL_RELEASE;
|
||||
PYW_GIL_GET;
|
||||
newref_t result(
|
||||
PyObject_CallMethod(
|
||||
self,
|
||||
(char *)S_ON_KEYDOWN,
|
||||
"siiHi",
|
||||
line->c_str(),
|
||||
*p_x,
|
||||
*p_sellen,
|
||||
*vk_key,
|
||||
shift));
|
||||
|
||||
bool ok = result != NULL && PyTuple_Check(result);
|
||||
bool ok = result != NULL && PyTuple_Check(result.o);
|
||||
|
||||
PyW_ShowCbErr(S_ON_KEYDOWN);
|
||||
|
||||
if ( ok )
|
||||
{
|
||||
Py_ssize_t sz = PyTuple_Size(result);
|
||||
Py_ssize_t sz = PyTuple_Size(result.o);
|
||||
PyObject *item;
|
||||
|
||||
if ( sz > 0 && (item = PyTuple_GetItem(result, 0)) != NULL && PyString_Check(item) )
|
||||
*line = PyString_AsString(item);
|
||||
|
||||
if ( sz > 1 && (item = PyTuple_GetItem(result, 1)) != NULL && PyInt_Check(item) )
|
||||
*p_x = PyInt_AsLong(item);
|
||||
|
||||
if ( sz > 2 && (item = PyTuple_GetItem(result, 2)) != NULL && PyInt_Check(item) )
|
||||
*p_sellen = PyInt_AsLong(item);
|
||||
|
||||
if ( sz > 3 && (item = PyTuple_GetItem(result, 3)) != NULL && PyInt_Check(item) )
|
||||
*vk_key = PyInt_AsLong(item) & 0xffff;
|
||||
#define GET_TUPLE_ENTRY(col, PyThingy, AsThingy, out) \
|
||||
do \
|
||||
{ \
|
||||
if ( sz > col ) \
|
||||
{ \
|
||||
borref_t _r(PyTuple_GetItem(result.o, col)); \
|
||||
if ( _r != NULL && PyThingy##_Check(_r.o) ) \
|
||||
*out = PyThingy##_##AsThingy(_r.o); \
|
||||
} \
|
||||
} while ( false )
|
||||
|
||||
GET_TUPLE_ENTRY(0, PyString, AsString, line);
|
||||
GET_TUPLE_ENTRY(1, PyInt, AsLong, p_x);
|
||||
GET_TUPLE_ENTRY(2, PyInt, AsLong, p_sellen);
|
||||
GET_TUPLE_ENTRY(3, PyInt, AsLong, vk_key);
|
||||
*vk_key &= 0xffff;
|
||||
#undef GET_TUPLE_ENTRY
|
||||
}
|
||||
|
||||
Py_XDECREF(result);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -140,41 +141,41 @@ private:
|
||||
// Returns: true if generated a new completion
|
||||
// This callback is optional
|
||||
bool on_complete_line(
|
||||
qstring *completion,
|
||||
const char *prefix,
|
||||
int n,
|
||||
const char *line,
|
||||
int x)
|
||||
qstring *completion,
|
||||
const char *prefix,
|
||||
int n,
|
||||
const char *line,
|
||||
int x)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *result = PyObject_CallMethod(
|
||||
self,
|
||||
(char *)S_ON_COMPLETE_LINE,
|
||||
"sisi",
|
||||
prefix,
|
||||
n,
|
||||
line,
|
||||
x);
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
bool ok = result != NULL && PyString_Check(result);
|
||||
PYW_GIL_GET;
|
||||
newref_t result(
|
||||
PyObject_CallMethod(
|
||||
self,
|
||||
(char *)S_ON_COMPLETE_LINE,
|
||||
"sisi",
|
||||
prefix,
|
||||
n,
|
||||
line,
|
||||
x));
|
||||
|
||||
bool ok = result != NULL && PyString_Check(result.o);
|
||||
PyW_ShowCbErr(S_ON_COMPLETE_LINE);
|
||||
if ( ok )
|
||||
*completion = PyString_AsString(result);
|
||||
|
||||
Py_XDECREF(result);
|
||||
*completion = PyString_AsString(result.o);
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Private ctor (use bind())
|
||||
py_cli_t()
|
||||
{
|
||||
py_cli_t()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
//---------------------------------------------------------------------------
|
||||
static int bind(PyObject *py_obj)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
int cli_idx;
|
||||
// Find an empty slot
|
||||
for ( cli_idx = 0; cli_idx < MAX_PY_CLI; ++cli_idx )
|
||||
@ -183,7 +184,7 @@ public:
|
||||
break;
|
||||
}
|
||||
py_cli_t *py_cli = NULL;
|
||||
do
|
||||
do
|
||||
{
|
||||
// No free slots?
|
||||
if ( cli_idx >= MAX_PY_CLI )
|
||||
@ -197,14 +198,12 @@ public:
|
||||
py_cli->cli.size = sizeof(cli_t);
|
||||
|
||||
// Store 'flags'
|
||||
if ( (attr = PyW_TryGetAttrString(py_obj, S_FLAGS)) == NULL )
|
||||
{
|
||||
py_cli->cli.flags = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
py_cli->cli.flags = PyLong_AsLong(attr);
|
||||
Py_DECREF(attr);
|
||||
ref_t flags_attr(PyW_TryGetAttrString(py_obj, S_FLAGS));
|
||||
if ( flags_attr == NULL )
|
||||
py_cli->cli.flags = 0;
|
||||
else
|
||||
py_cli->cli.flags = PyLong_AsLong(flags_attr.o);
|
||||
}
|
||||
|
||||
// Store 'sname'
|
||||
@ -256,9 +255,12 @@ public:
|
||||
|
||||
py_cli_t *py_cli = py_clis[cli_idx];
|
||||
remove_command_interpreter(&py_cli->cli);
|
||||
|
||||
Py_DECREF(py_cli->self);
|
||||
delete py_cli;
|
||||
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
Py_DECREF(py_cli->self);
|
||||
delete py_cli;
|
||||
}
|
||||
|
||||
py_clis[cli_idx] = NULL;
|
||||
|
||||
@ -280,12 +282,12 @@ const py_cli_cbs_t py_cli_t::py_cli_cbs[MAX_PY_CLI] =
|
||||
|
||||
//<inline(py_cli)>
|
||||
static int py_install_command_interpreter(PyObject *py_obj)
|
||||
{
|
||||
{
|
||||
return py_cli_t::bind(py_obj);
|
||||
}
|
||||
|
||||
static void py_remove_command_interpreter(int cli_idx)
|
||||
{
|
||||
{
|
||||
py_cli_t::unbind(cli_idx);
|
||||
}
|
||||
//</inline(py_cli)>
|
||||
|
@ -18,20 +18,18 @@ class py_custom_data_type_t
|
||||
size_t nbytes) // size of the future item
|
||||
{
|
||||
py_custom_data_type_t *_this = (py_custom_data_type_t *)ud;
|
||||
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_MAY_CREATE_AT,
|
||||
PY_FMT64 PY_FMT64,
|
||||
pyul_t(ea),
|
||||
pyul_t(nbytes));
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
PYW_GIL_GET;
|
||||
newref_t py_result(
|
||||
PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_MAY_CREATE_AT,
|
||||
PY_FMT64 PY_FMT64,
|
||||
pyul_t(ea),
|
||||
pyul_t(nbytes)));
|
||||
|
||||
PyW_ShowCbErr(S_MAY_CREATE_AT);
|
||||
bool ok = py_result != NULL && PyObject_IsTrue(py_result);
|
||||
Py_XDECREF(py_result);
|
||||
return ok;
|
||||
return py_result != NULL && PyObject_IsTrue(py_result.o);
|
||||
}
|
||||
|
||||
// !=NULL means variable size datatype
|
||||
@ -42,24 +40,23 @@ class py_custom_data_type_t
|
||||
ea_t ea, // address of the item
|
||||
asize_t maxsize) // maximal size of the item
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
// Returns: 0-no such item can be created/displayed
|
||||
// this callback is required only for varsize datatypes
|
||||
py_custom_data_type_t *_this = (py_custom_data_type_t *)ud;
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_CALC_ITEM_SIZE,
|
||||
PY_FMT64 PY_FMT64,
|
||||
pyul_t(ea),
|
||||
pyul_t(maxsize));
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
newref_t py_result(
|
||||
PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_CALC_ITEM_SIZE,
|
||||
PY_FMT64 PY_FMT64,
|
||||
pyul_t(ea),
|
||||
pyul_t(maxsize)));
|
||||
|
||||
if ( PyW_ShowCbErr(S_CALC_ITEM_SIZE) || py_result == NULL )
|
||||
return 0;
|
||||
|
||||
|
||||
uint64 num = 0;
|
||||
PyW_GetNumber(py_result, &num);
|
||||
Py_XDECREF(py_result);
|
||||
PyW_GetNumber(py_result.o, &num);
|
||||
return asize_t(num);
|
||||
}
|
||||
|
||||
@ -77,6 +74,8 @@ public:
|
||||
|
||||
int register_dt(PyObject *py_obj)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
// Already registered?
|
||||
if ( dtid >= 0 )
|
||||
return dtid;
|
||||
@ -85,9 +84,10 @@ public:
|
||||
dt.cbsize = sizeof(dt);
|
||||
dt.ud = this;
|
||||
|
||||
PyObject *py_attr = NULL;
|
||||
do
|
||||
{
|
||||
ref_t py_attr;
|
||||
|
||||
// name
|
||||
if ( !PyW_GetStringAttr(py_obj, S_NAME, &dt_name) )
|
||||
break;
|
||||
@ -108,30 +108,27 @@ public:
|
||||
|
||||
// value_size
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_VALUE_SIZE);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr) )
|
||||
dt.value_size = PyInt_AsLong(py_attr);
|
||||
Py_XDECREF(py_attr);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr.o) )
|
||||
dt.value_size = PyInt_AsLong(py_attr.o);
|
||||
py_attr = ref_t();
|
||||
|
||||
// props
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_PROPS);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr) )
|
||||
dt.props = PyInt_AsLong(py_attr);
|
||||
Py_XDECREF(py_attr);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr.o) )
|
||||
dt.props = PyInt_AsLong(py_attr.o);
|
||||
py_attr = ref_t();
|
||||
|
||||
// may_create_at
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_MAY_CREATE_AT);
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr) )
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr.o) )
|
||||
dt.may_create_at = s_may_create_at;
|
||||
Py_XDECREF(py_attr);
|
||||
py_attr = ref_t();
|
||||
|
||||
// calc_item_size
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_CALC_ITEM_SIZE);
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr) )
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr.o) )
|
||||
dt.calc_item_size = s_calc_item_size;
|
||||
Py_XDECREF(py_attr);
|
||||
|
||||
// Clear attribute
|
||||
py_attr = NULL;
|
||||
py_attr = ref_t();
|
||||
|
||||
// Now try to register
|
||||
dtid = register_custom_data_type(&dt);
|
||||
@ -142,20 +139,16 @@ public:
|
||||
Py_INCREF(py_obj);
|
||||
py_self = py_obj;
|
||||
|
||||
py_attr = PyInt_FromLong(dtid);
|
||||
PyObject_SetAttrString(py_obj, S_ID, py_attr);
|
||||
Py_DECREF(py_attr);
|
||||
|
||||
// Done with attribute
|
||||
py_attr = NULL;
|
||||
py_attr = newref_t(PyInt_FromLong(dtid));
|
||||
PyObject_SetAttrString(py_obj, S_ID, py_attr.o);
|
||||
} while ( false );
|
||||
|
||||
Py_XDECREF(py_attr);
|
||||
return dtid;
|
||||
}
|
||||
|
||||
bool unregister_dt()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
if ( dtid < 0 )
|
||||
return true;
|
||||
|
||||
@ -195,44 +188,41 @@ private:
|
||||
int operand_num, // current operand number
|
||||
int dtid) // custom data type id
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
|
||||
// Build a string from the buffer
|
||||
PyObject *py_value = PyString_FromStringAndSize(
|
||||
(const char *)value,
|
||||
Py_ssize_t(size));
|
||||
newref_t py_value(PyString_FromStringAndSize(
|
||||
(const char *)value,
|
||||
Py_ssize_t(size)));
|
||||
if ( py_value == NULL )
|
||||
return false;
|
||||
|
||||
py_custom_data_format_t *_this = (py_custom_data_format_t *) ud;
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_PRINTF,
|
||||
"O" PY_FMT64 "ii",
|
||||
py_value,
|
||||
pyul_t(current_ea),
|
||||
operand_num,
|
||||
dtid);
|
||||
PYW_GIL_RELEASE;
|
||||
// Done with the string
|
||||
Py_DECREF(py_value);
|
||||
newref_t py_result(PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_PRINTF,
|
||||
"O" PY_FMT64 "ii",
|
||||
py_value.o,
|
||||
pyul_t(current_ea),
|
||||
operand_num,
|
||||
dtid));
|
||||
|
||||
// Error while calling the function?
|
||||
if ( PyW_ShowCbErr(S_PRINTF) || py_result == NULL )
|
||||
return false;
|
||||
|
||||
bool ok = false;
|
||||
if ( PyString_Check(py_result) )
|
||||
if ( PyString_Check(py_result.o) )
|
||||
{
|
||||
Py_ssize_t len;
|
||||
char *buf;
|
||||
if ( out != NULL && PyString_AsStringAndSize(py_result, &buf, &len) != -1 )
|
||||
if ( out != NULL && PyString_AsStringAndSize(py_result.o, &buf, &len) != -1 )
|
||||
{
|
||||
out->qclear();
|
||||
out->append(buf, len);
|
||||
}
|
||||
ok = true;
|
||||
}
|
||||
Py_DECREF(py_result);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -244,16 +234,17 @@ private:
|
||||
int operand_num, // current operand number (-1 if unknown)
|
||||
qstring *errstr) // buffer for error message
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
|
||||
py_custom_data_format_t *_this = (py_custom_data_format_t *) ud;
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_SCAN,
|
||||
"s" PY_FMT64,
|
||||
input,
|
||||
pyul_t(current_ea),
|
||||
operand_num);
|
||||
PYW_GIL_RELEASE;
|
||||
newref_t py_result(
|
||||
PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_SCAN,
|
||||
"s" PY_FMT64,
|
||||
input,
|
||||
pyul_t(current_ea),
|
||||
operand_num));
|
||||
|
||||
// Error while calling the function?
|
||||
if ( PyW_ShowCbErr(S_SCAN) || py_result == NULL)
|
||||
@ -263,15 +254,14 @@ private:
|
||||
do
|
||||
{
|
||||
// We expect a tuple(bool, string|None)
|
||||
if ( !PyTuple_Check(py_result) || PyTuple_Size(py_result) != 2 )
|
||||
if ( !PyTuple_Check(py_result.o) || PyTuple_Size(py_result.o) != 2 )
|
||||
break;
|
||||
|
||||
// Borrow references
|
||||
PyObject *py_bool = PyTuple_GetItem(py_result, 0);
|
||||
PyObject *py_val = PyTuple_GetItem(py_result, 1);
|
||||
borref_t py_bool(PyTuple_GetItem(py_result.o, 0));
|
||||
borref_t py_val(PyTuple_GetItem(py_result.o, 1));
|
||||
|
||||
// Get return code from Python
|
||||
ok = PyObject_IsTrue(py_bool);
|
||||
ok = PyObject_IsTrue(py_bool.o);
|
||||
|
||||
// We expect None or the value (depending on probe)
|
||||
if ( ok )
|
||||
@ -282,7 +272,7 @@ private:
|
||||
|
||||
Py_ssize_t len;
|
||||
char *buf;
|
||||
if ( PyString_AsStringAndSize(py_val, &buf, &len) != -1 )
|
||||
if ( PyString_AsStringAndSize(py_val.o, &buf, &len) != -1 )
|
||||
{
|
||||
value->qclear();
|
||||
value->append(buf, len);
|
||||
@ -292,16 +282,15 @@ private:
|
||||
else
|
||||
{
|
||||
// Make sure the user returned (False, String)
|
||||
if ( py_bool != Py_False || !PyString_Check(py_val) )
|
||||
if ( py_bool.o != Py_False || !PyString_Check(py_val.o) )
|
||||
{
|
||||
*errstr = "Invalid return value returned from the Python callback!";
|
||||
break;
|
||||
}
|
||||
// Get the error message
|
||||
*errstr = PyString_AsString(py_val);
|
||||
*errstr = PyString_AsString(py_val.o);
|
||||
}
|
||||
} while ( false );
|
||||
Py_DECREF(py_result);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -313,19 +302,18 @@ private:
|
||||
// xrefs from the current item.
|
||||
// this callback may be missing.
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
|
||||
py_custom_data_format_t *_this = (py_custom_data_format_t *) ud;
|
||||
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_ANALYZE,
|
||||
PY_FMT64 "i",
|
||||
pyul_t(current_ea),
|
||||
operand_num);
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
newref_t py_result(
|
||||
PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_ANALYZE,
|
||||
PY_FMT64 "i",
|
||||
pyul_t(current_ea),
|
||||
operand_num));
|
||||
|
||||
PyW_ShowCbErr(S_ANALYZE);
|
||||
Py_XDECREF(py_result);
|
||||
}
|
||||
public:
|
||||
py_custom_data_format_t()
|
||||
@ -334,9 +322,9 @@ public:
|
||||
py_self = NULL;
|
||||
}
|
||||
|
||||
const char *get_name() const
|
||||
{
|
||||
return df_name.c_str();
|
||||
const char *get_name() const
|
||||
{
|
||||
return df_name.c_str();
|
||||
}
|
||||
|
||||
int register_df(int dtid, PyObject *py_obj)
|
||||
@ -348,10 +336,12 @@ public:
|
||||
memset(&df, 0, sizeof(df));
|
||||
df.cbsize = sizeof(df);
|
||||
df.ud = this;
|
||||
PyObject *py_attr = NULL;
|
||||
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
do
|
||||
{
|
||||
ref_t py_attr;
|
||||
|
||||
// name
|
||||
if ( !PyW_GetStringAttr(py_obj, S_NAME, &df_name) )
|
||||
break;
|
||||
@ -363,9 +353,8 @@ public:
|
||||
|
||||
// props
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_PROPS);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr) )
|
||||
df.props = PyInt_AsLong(py_attr);
|
||||
Py_XDECREF(py_attr);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr.o) )
|
||||
df.props = PyInt_AsLong(py_attr.o);
|
||||
|
||||
// hotkey
|
||||
if ( PyW_GetStringAttr(py_obj, S_HOTKEY, &df_hotkey) )
|
||||
@ -373,36 +362,28 @@ public:
|
||||
|
||||
// value_size
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_VALUE_SIZE);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr) )
|
||||
df.value_size = PyInt_AsLong(py_attr);
|
||||
Py_XDECREF(py_attr);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr.o) )
|
||||
df.value_size = PyInt_AsLong(py_attr.o);
|
||||
|
||||
// text_width
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_TEXT_WIDTH);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr) )
|
||||
df.text_width = PyInt_AsLong(py_attr);
|
||||
Py_XDECREF(py_attr);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr.o) )
|
||||
df.text_width = PyInt_AsLong(py_attr.o);
|
||||
|
||||
// print cb
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_PRINTF);
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr) )
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr.o) )
|
||||
df.print = s_print;
|
||||
Py_XDECREF(py_attr);
|
||||
|
||||
// scan cb
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_SCAN);
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr) )
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr.o) )
|
||||
df.scan = s_scan;
|
||||
Py_XDECREF(py_attr);
|
||||
|
||||
// analyze cb
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_ANALYZE);
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr) )
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr.o) )
|
||||
df.analyze = s_analyze;
|
||||
Py_XDECREF(py_attr);
|
||||
|
||||
// Done with attribute
|
||||
py_attr = NULL;
|
||||
|
||||
// Now try to register
|
||||
dfid = register_custom_data_format(dtid, &df);
|
||||
@ -414,19 +395,16 @@ public:
|
||||
py_self = py_obj;
|
||||
|
||||
// Update the format ID
|
||||
py_attr = PyInt_FromLong(dfid);
|
||||
PyObject_SetAttrString(py_obj, S_ID, py_attr);
|
||||
Py_DECREF(py_attr);
|
||||
|
||||
py_attr = NULL;
|
||||
py_attr = newref_t(PyInt_FromLong(dfid));
|
||||
PyObject_SetAttrString(py_obj, S_ID, py_attr.o);
|
||||
} while ( false );
|
||||
|
||||
Py_XDECREF(py_attr);
|
||||
return dfid;
|
||||
}
|
||||
|
||||
bool unregister_df(int dtid)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
// Never registered?
|
||||
if ( dfid < 0 )
|
||||
return true;
|
||||
@ -490,6 +468,8 @@ static py_custom_data_format_list_t py_df_list;
|
||||
//------------------------------------------------------------------------
|
||||
static PyObject *py_data_type_to_py_dict(const data_type_t *dt)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
return Py_BuildValue("{s:" PY_FMT64 ",s:i,s:i,s:s,s:s,s:s,s:s}",
|
||||
S_VALUE_SIZE, pyul_t(dt->value_size),
|
||||
S_PROPS, dt->props,
|
||||
@ -503,6 +483,8 @@ static PyObject *py_data_type_to_py_dict(const data_type_t *dt)
|
||||
//------------------------------------------------------------------------
|
||||
static PyObject *py_data_format_to_py_dict(const data_format_t *df)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
return Py_BuildValue("{s:i,s:i,s:i,s:" PY_FMT64 ",s:s,s:s,s:s}",
|
||||
S_PROPS, df->props,
|
||||
S_CBSIZE, df->cbsize,
|
||||
@ -668,6 +650,7 @@ def get_custom_data_format(dtid, dfid):
|
||||
// Get definition of a registered custom data format and returns a dictionary
|
||||
static PyObject *py_get_custom_data_format(int dtid, int fid)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
const data_format_t *df = get_custom_data_format(dtid, fid);
|
||||
if ( df == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -688,6 +671,7 @@ def get_custom_data_type(dtid):
|
||||
// Get definition of a registered custom data format and returns a dictionary
|
||||
static PyObject *py_get_custom_data_type(int dtid)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
const data_type_t *dt = get_custom_data_type(dtid);
|
||||
if ( dt == NULL )
|
||||
Py_RETURN_NONE;
|
||||
|
@ -168,6 +168,7 @@ private:
|
||||
|
||||
static bool idaapi s_popup_cb(void *ud)
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
customviewer_t *_this = (customviewer_t *)ud;
|
||||
return _this->on_popup();
|
||||
}
|
||||
@ -179,6 +180,7 @@ private:
|
||||
if ( it == _global_popup_map.end() )
|
||||
return false;
|
||||
|
||||
PYW_GIL_GET;
|
||||
return it->second.cv->on_popup_menu(it->second.menu_id);
|
||||
}
|
||||
|
||||
@ -188,6 +190,7 @@ private:
|
||||
int shift,
|
||||
void *ud)
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
customviewer_t *_this = (customviewer_t *)ud;
|
||||
return _this->on_keydown(vk_key, shift);
|
||||
}
|
||||
@ -195,6 +198,7 @@ private:
|
||||
// The popup menu is being constructed
|
||||
static void idaapi s_cv_popup(TCustomControl * /*cv*/, void *ud)
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
customviewer_t *_this = (customviewer_t *)ud;
|
||||
_this->on_popup();
|
||||
}
|
||||
@ -202,6 +206,7 @@ private:
|
||||
// The user clicked
|
||||
static bool idaapi s_cv_click(TCustomControl * /*cv*/, int shift, void *ud)
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
customviewer_t *_this = (customviewer_t *)ud;
|
||||
return _this->on_click(shift);
|
||||
}
|
||||
@ -209,6 +214,7 @@ private:
|
||||
// The user double clicked
|
||||
static bool idaapi s_cv_dblclick(TCustomControl * /*cv*/, int shift, void *ud)
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
customviewer_t *_this = (customviewer_t *)ud;
|
||||
return _this->on_dblclick(shift);
|
||||
}
|
||||
@ -216,6 +222,7 @@ private:
|
||||
// Cursor position has been changed
|
||||
static void idaapi s_cv_curpos(TCustomControl * /*cv*/, void *ud)
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
customviewer_t *_this = (customviewer_t *)ud;
|
||||
_this->on_curpos_changed();
|
||||
}
|
||||
@ -223,6 +230,8 @@ private:
|
||||
//--------------------------------------------------------------------------
|
||||
static int idaapi s_ui_cb(void *ud, int code, va_list va)
|
||||
{
|
||||
// This hook gets called from the kernel. Ensure we hold the GIL.
|
||||
PYW_GIL_GET;
|
||||
customviewer_t *_this = (customviewer_t *)ud;
|
||||
switch ( code )
|
||||
{
|
||||
@ -243,11 +252,12 @@ private:
|
||||
TForm *form = va_arg(va, TForm *);
|
||||
if ( _this->_form != form )
|
||||
break;
|
||||
|
||||
unhook_from_notification_point(HT_UI, s_ui_cb, _this);
|
||||
_this->on_close();
|
||||
_this->on_post_close();
|
||||
}
|
||||
// fallthrough...
|
||||
case ui_term:
|
||||
unhook_from_notification_point(HT_UI, s_ui_cb, _this);
|
||||
_this->on_close();
|
||||
_this->on_post_close();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -541,6 +551,8 @@ private:
|
||||
// Convert a tuple (String, [color, [bgcolor]]) to a simpleline_t
|
||||
static bool py_to_simpleline(PyObject *py, simpleline_t &sl)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
if ( PyString_Check(py) )
|
||||
{
|
||||
sl.line = PyString_AsString(py);
|
||||
@ -570,37 +582,29 @@ private:
|
||||
//
|
||||
virtual bool on_click(int shift)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(py_self, (char *)S_ON_CLICK, "i", shift);
|
||||
PYW_GIL_RELEASE;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t py_result(PyObject_CallMethod(py_self, (char *)S_ON_CLICK, "i", shift));
|
||||
PyW_ShowCbErr(S_ON_CLICK);
|
||||
bool ok = py_result != NULL && PyObject_IsTrue(py_result);
|
||||
Py_XDECREF(py_result);
|
||||
return ok;
|
||||
return py_result != NULL && PyObject_IsTrue(py_result.o);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// OnDblClick
|
||||
virtual bool on_dblclick(int shift)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(py_self, (char *)S_ON_DBL_CLICK, "i", shift);
|
||||
PYW_GIL_RELEASE;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t py_result(PyObject_CallMethod(py_self, (char *)S_ON_DBL_CLICK, "i", shift));
|
||||
PyW_ShowCbErr(S_ON_DBL_CLICK);
|
||||
bool ok = py_result != NULL && PyObject_IsTrue(py_result);
|
||||
Py_XDECREF(py_result);
|
||||
return ok;
|
||||
return py_result != NULL && PyObject_IsTrue(py_result.o);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// OnCurorPositionChanged
|
||||
virtual void on_curpos_changed()
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(py_self, (char *)S_ON_CURSOR_POS_CHANGED, NULL);
|
||||
PYW_GIL_RELEASE;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t py_result(PyObject_CallMethod(py_self, (char *)S_ON_CURSOR_POS_CHANGED, NULL));
|
||||
PyW_ShowCbErr(S_ON_CURSOR_POS_CHANGED);
|
||||
Py_XDECREF(py_result);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@ -610,12 +614,9 @@ private:
|
||||
// Call the close method if it is there and the object is still bound
|
||||
if ( (features & HAVE_CLOSE) != 0 && py_self != NULL )
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(py_self, (char *)S_ON_CLOSE, NULL);
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t py_result(PyObject_CallMethod(py_self, (char *)S_ON_CLOSE, NULL));
|
||||
PyW_ShowCbErr(S_ON_CLOSE);
|
||||
Py_XDECREF(py_result);
|
||||
|
||||
// Cleanup
|
||||
Py_DECREF(py_self);
|
||||
@ -627,36 +628,31 @@ private:
|
||||
// OnKeyDown
|
||||
virtual bool on_keydown(int vk_key, int shift)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(
|
||||
py_self,
|
||||
(char *)S_ON_KEYDOWN,
|
||||
"ii",
|
||||
vk_key,
|
||||
shift);
|
||||
PYW_GIL_RELEASE;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t py_result(
|
||||
PyObject_CallMethod(
|
||||
py_self,
|
||||
(char *)S_ON_KEYDOWN,
|
||||
"ii",
|
||||
vk_key,
|
||||
shift));
|
||||
|
||||
PyW_ShowCbErr(S_ON_KEYDOWN);
|
||||
bool ok = py_result != NULL && PyObject_IsTrue(py_result);
|
||||
Py_XDECREF(py_result);
|
||||
return ok;
|
||||
return py_result != NULL && PyObject_IsTrue(py_result.o);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// OnPopupShow
|
||||
virtual bool on_popup()
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(
|
||||
py_self,
|
||||
(char *)S_ON_POPUP,
|
||||
NULL);
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t py_result(
|
||||
PyObject_CallMethod(
|
||||
py_self,
|
||||
(char *)S_ON_POPUP,
|
||||
NULL));
|
||||
PyW_ShowCbErr(S_ON_POPUP);
|
||||
bool ok = py_result != NULL && PyObject_IsTrue(py_result);
|
||||
Py_XDECREF(py_result);
|
||||
return ok;
|
||||
return py_result != NULL && PyObject_IsTrue(py_result.o);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@ -664,28 +660,22 @@ private:
|
||||
virtual bool on_hint(place_t *place, int *important_lines, qstring &hint)
|
||||
{
|
||||
size_t ln = data.to_lineno(place);
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(
|
||||
py_self,
|
||||
(char *)S_ON_HINT,
|
||||
PY_FMT64,
|
||||
pyul_t(ln));
|
||||
PYW_GIL_RELEASE;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t py_result(
|
||||
PyObject_CallMethod(
|
||||
py_self,
|
||||
(char *)S_ON_HINT,
|
||||
PY_FMT64,
|
||||
pyul_t(ln)));
|
||||
|
||||
PyW_ShowCbErr(S_ON_HINT);
|
||||
bool ok = py_result != NULL && PyTuple_Check(py_result) && PyTuple_Size(py_result) == 2;
|
||||
bool ok = py_result != NULL && PyTuple_Check(py_result.o) && PyTuple_Size(py_result.o) == 2;
|
||||
if ( ok )
|
||||
{
|
||||
// Borrow references
|
||||
PyObject *py_nlines = PyTuple_GetItem(py_result, 0);
|
||||
PyObject *py_hint = PyTuple_GetItem(py_result, 1);
|
||||
|
||||
if ( important_lines != NULL )
|
||||
*important_lines = PyInt_AsLong(py_nlines);
|
||||
|
||||
hint = PyString_AsString(py_hint);
|
||||
*important_lines = PyInt_AsLong(PyTuple_GetItem(py_result.o, 0));
|
||||
hint = PyString_AsString(PyTuple_GetItem(py_result.o, 1));
|
||||
}
|
||||
Py_XDECREF(py_result);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -693,18 +683,15 @@ private:
|
||||
// OnPopupMenuClick
|
||||
virtual bool on_popup_menu(size_t menu_id)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(
|
||||
py_self,
|
||||
(char *)S_ON_POPUP_MENU,
|
||||
PY_FMT64,
|
||||
pyul_t(menu_id));
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t py_result(
|
||||
PyObject_CallMethod(
|
||||
py_self,
|
||||
(char *)S_ON_POPUP_MENU,
|
||||
PY_FMT64,
|
||||
pyul_t(menu_id)));
|
||||
PyW_ShowCbErr(S_ON_POPUP_MENU);
|
||||
bool ok = py_result != NULL && PyObject_IsTrue(py_result);
|
||||
Py_XDECREF(py_result);
|
||||
return ok;
|
||||
return py_result != NULL && PyObject_IsTrue(py_result.o);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@ -776,6 +763,7 @@ public:
|
||||
place_t *pl;
|
||||
int x, y;
|
||||
pl = get_place(mouse, &x, &y);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( pl == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("(" PY_FMT64 "ii)", pyul_t(data.to_lineno(pl)), x, y);
|
||||
@ -786,6 +774,7 @@ public:
|
||||
PyObject *get_line(size_t nline)
|
||||
{
|
||||
simpleline_t *r = data.get_line(nline);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( r == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("(sII)", r->line.c_str(), (unsigned int)r->color, (unsigned int)r->bgcolor);
|
||||
@ -835,6 +824,8 @@ public:
|
||||
{S_ON_DBL_CLICK, HAVE_DBLCLICK},
|
||||
{S_ON_CURSOR_POS_CHANGED, HAVE_CURPOS}
|
||||
};
|
||||
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
for ( size_t i=0; i<qnumber(cbtable); i++ )
|
||||
{
|
||||
if ( PyObject_HasAttrString(py_link, cbtable[i].cb_name) )
|
||||
@ -892,6 +883,7 @@ public:
|
||||
PyObject *py_get_selection()
|
||||
{
|
||||
size_t x1, y1, x2, y2;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !get_selection(&x1, &y1, &x2, &y2) )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("(" PY_FMT64 PY_FMT64 PY_FMT64 PY_FMT64 ")", pyul_t(x1), pyul_t(y1), pyul_t(x2), pyul_t(y2));
|
||||
@ -899,6 +891,7 @@ public:
|
||||
|
||||
static py_simplecustview_t *get_this(PyObject *py_this)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return PyCObject_Check(py_this) ? (py_simplecustview_t *) PyCObject_AsVoidPtr(py_this) : NULL;
|
||||
}
|
||||
|
||||
@ -920,6 +913,7 @@ public:
|
||||
//
|
||||
PyObject *pyscv_init(PyObject *py_link, const char *title)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
py_simplecustview_t *_this = new py_simplecustview_t();
|
||||
bool ok = _this->init(py_link, title);
|
||||
if ( !ok )
|
||||
@ -964,6 +958,7 @@ bool pyscv_refresh_current(PyObject *py_this)
|
||||
PyObject *pyscv_get_current_line(PyObject *py_this, bool mouse, bool notags)
|
||||
{
|
||||
DECL_THIS;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
const char *line;
|
||||
if ( _this == NULL || (line = _this->get_current_line(mouse, notags)) == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -1024,7 +1019,10 @@ PyObject *pyscv_get_line(PyObject *py_this, size_t nline)
|
||||
{
|
||||
DECL_THIS;
|
||||
if ( _this == NULL )
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
return _this->get_line(nline);
|
||||
}
|
||||
|
||||
@ -1034,7 +1032,10 @@ PyObject *pyscv_get_pos(PyObject *py_this, bool mouse)
|
||||
{
|
||||
DECL_THIS;
|
||||
if ( _this == NULL )
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
return _this->get_pos(mouse);
|
||||
}
|
||||
|
||||
@ -1044,6 +1045,7 @@ PyObject *pyscv_clear_lines(PyObject *py_this)
|
||||
DECL_THIS;
|
||||
if ( _this != NULL )
|
||||
_this->clear();
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
@ -1081,7 +1083,10 @@ PyObject *pyscv_get_selection(PyObject *py_this)
|
||||
{
|
||||
DECL_THIS;
|
||||
if ( _this == NULL )
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
return _this->py_get_selection();
|
||||
}
|
||||
|
||||
@ -1089,6 +1094,7 @@ PyObject *pyscv_get_selection(PyObject *py_this)
|
||||
PyObject *pyscv_get_current_word(PyObject *py_this, bool mouse)
|
||||
{
|
||||
DECL_THIS;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( _this != NULL )
|
||||
{
|
||||
qstring word;
|
||||
|
1022
pywraps/py_cvt.hpp
1022
pywraps/py_cvt.hpp
File diff suppressed because it is too large
Load Diff
@ -14,6 +14,8 @@ static bool dbg_can_query()
|
||||
//-------------------------------------------------------------------------
|
||||
static PyObject *meminfo_vec_t_to_py(meminfo_vec_t &areas)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
PyObject *py_list = PyList_New(areas.size());
|
||||
meminfo_vec_t::const_iterator it, it_end(areas.end());
|
||||
Py_ssize_t i = 0;
|
||||
@ -42,6 +44,8 @@ PyObject *py_appcall(
|
||||
PyObject *py_fields,
|
||||
PyObject *arg_list)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
if ( !PyList_Check(arg_list) )
|
||||
return NULL;
|
||||
|
||||
@ -57,11 +61,11 @@ PyObject *py_appcall(
|
||||
for ( Py_ssize_t i=0; i<nargs; i++ )
|
||||
{
|
||||
// Get argument
|
||||
PyObject *py_item = PyList_GetItem(arg_list, i);
|
||||
borref_t py_item(PyList_GetItem(arg_list, i));
|
||||
if ( (debug & IDA_DEBUG_APPCALL) != 0 )
|
||||
{
|
||||
qstring s;
|
||||
PyW_ObjectToString(py_item, &s);
|
||||
PyW_ObjectToString(py_item.o, &s);
|
||||
msg("obj[%d]->%s\n", int(i), s.c_str());
|
||||
}
|
||||
// Convert it
|
||||
@ -81,6 +85,10 @@ PyObject *py_appcall(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
error_t ret;
|
||||
idc_value_t idc_result;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
|
||||
if ( (debug & IDA_DEBUG_APPCALL) != 0 )
|
||||
{
|
||||
msg("input variables:\n"
|
||||
@ -96,8 +104,7 @@ PyObject *py_appcall(
|
||||
}
|
||||
|
||||
// Do Appcall
|
||||
idc_value_t idc_result;
|
||||
error_t ret = appcall(
|
||||
ret = appcall(
|
||||
func_ea,
|
||||
tid,
|
||||
(type_t *)type,
|
||||
@ -106,16 +113,17 @@ PyObject *py_appcall(
|
||||
idc_args.begin(),
|
||||
&idc_result);
|
||||
|
||||
Py_END_ALLOW_THREADS;
|
||||
|
||||
if ( ret != eOk )
|
||||
{
|
||||
// An exception was thrown?
|
||||
if ( ret == eExecThrow )
|
||||
{
|
||||
// Convert the result (which is a debug_event) into a Python object
|
||||
PyObject *py_appcall_exc(NULL);
|
||||
ref_t py_appcall_exc;
|
||||
idcvar_to_pyvar(idc_result, &py_appcall_exc);
|
||||
PyErr_SetObject(PyExc_OSError, py_appcall_exc);
|
||||
Py_DECREF(py_appcall_exc);
|
||||
PyErr_SetObject(PyExc_OSError, py_appcall_exc.o);
|
||||
return NULL;
|
||||
}
|
||||
// An error in the Appcall? (or an exception but AppCallOptions/DEBEV is not set)
|
||||
@ -145,7 +153,7 @@ PyObject *py_appcall(
|
||||
for ( Py_ssize_t i=0; i<nargs; i++ )
|
||||
{
|
||||
// Get argument
|
||||
PyObject *py_item = PyList_GetItem(arg_list, i);
|
||||
borref_t py_item(PyList_GetItem(arg_list, i));
|
||||
// We convert arguments but fail only on fatal errors
|
||||
// (we ignore failure because of immutable objects)
|
||||
if ( idcvar_to_pyvar(idc_args[i], &py_item) == CIP_FAILED )
|
||||
@ -155,13 +163,13 @@ PyObject *py_appcall(
|
||||
}
|
||||
}
|
||||
// Convert the result from IDC back to Python
|
||||
PyObject *py_result(NULL);
|
||||
ref_t py_result;
|
||||
if ( idcvar_to_pyvar(idc_result, &py_result) <= CIP_IMMUTABLE )
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "PyAppCall: Failed while converting IDC return value to Python return value");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QASSERT(30413, py_result.o->ob_refcnt == 1);
|
||||
if ( (debug & IDA_DEBUG_APPCALL) != 0 )
|
||||
{
|
||||
msg("return var:\n"
|
||||
@ -170,7 +178,8 @@ PyObject *py_appcall(
|
||||
VarPrint(&s, &idc_result);
|
||||
msg("%s\n-----------\n", s.c_str());
|
||||
}
|
||||
return py_result;
|
||||
py_result.incref();
|
||||
return py_result.o;
|
||||
}
|
||||
//</code(py_idd)>
|
||||
|
||||
@ -193,6 +202,8 @@ def dbg_get_registers():
|
||||
*/
|
||||
static PyObject *dbg_get_registers()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
if ( dbg == NULL )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
@ -251,6 +262,8 @@ def dbg_get_thread_sreg_base(tid, sreg_value):
|
||||
*/
|
||||
static PyObject *dbg_get_thread_sreg_base(PyObject *py_tid, PyObject *py_sreg_value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
if ( !dbg_can_query() || !PyInt_Check(py_tid) || !PyInt_Check(py_sreg_value) )
|
||||
Py_RETURN_NONE;
|
||||
ea_t answer;
|
||||
@ -277,6 +290,8 @@ def dbg_read_memory(ea, sz):
|
||||
*/
|
||||
static PyObject *dbg_read_memory(PyObject *py_ea, PyObject *py_sz)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
uint64 ea, sz;
|
||||
if ( !dbg_can_query() || !PyW_GetNumber(py_ea, &ea) || !PyW_GetNumber(py_sz, &sz) )
|
||||
Py_RETURN_NONE;
|
||||
@ -314,6 +329,8 @@ def dbg_write_memory(ea, buffer):
|
||||
*/
|
||||
static PyObject *dbg_write_memory(PyObject *py_ea, PyObject *py_buf)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
uint64 ea;
|
||||
if ( !dbg_can_query() || !PyString_Check(py_buf) || !PyW_GetNumber(py_ea, &ea) )
|
||||
Py_RETURN_NONE;
|
||||
@ -338,6 +355,8 @@ def dbg_get_name():
|
||||
*/
|
||||
static PyObject *dbg_get_name()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
if ( dbg == NULL )
|
||||
Py_RETURN_NONE;
|
||||
else
|
||||
@ -359,15 +378,19 @@ def dbg_get_memory_info():
|
||||
*/
|
||||
static PyObject *dbg_get_memory_info()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
if ( !dbg_can_query() )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
// Invalidate memory
|
||||
meminfo_vec_t areas;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
invalidate_dbgmem_config();
|
||||
invalidate_dbgmem_contents(BADADDR, BADADDR);
|
||||
|
||||
meminfo_vec_t areas;
|
||||
get_dbg_memory_info(&areas);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return meminfo_vec_t_to_py(areas);
|
||||
}
|
||||
|
||||
@ -459,6 +482,7 @@ static PyObject *refresh_debugger_memory()
|
||||
// Invalidate the cache
|
||||
isEnabled(0);
|
||||
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
@ -466,74 +490,78 @@ int idaapi DBG_Callback(void *ud, int notification_code, va_list va);
|
||||
class DBG_Hooks
|
||||
{
|
||||
public:
|
||||
virtual ~DBG_Hooks() { unhook(); };
|
||||
virtual ~DBG_Hooks() { unhook(); }
|
||||
|
||||
bool hook() { return hook_to_notification_point(HT_DBG, DBG_Callback, this); };
|
||||
bool unhook() { return unhook_from_notification_point(HT_DBG, DBG_Callback, this); };
|
||||
bool hook() { return hook_to_notification_point(HT_DBG, DBG_Callback, this); }
|
||||
bool unhook() { return unhook_from_notification_point(HT_DBG, DBG_Callback, this); }
|
||||
/* Hook functions to be overridden in Python */
|
||||
virtual void dbg_process_start(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea,
|
||||
char *name,
|
||||
ea_t base,
|
||||
asize_t size) { };
|
||||
asize_t size) {}
|
||||
virtual void dbg_process_exit(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea,
|
||||
int exit_code) { };
|
||||
int exit_code) {}
|
||||
virtual void dbg_process_attach(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea,
|
||||
char *name,
|
||||
ea_t base,
|
||||
asize_t size) { };
|
||||
asize_t size) {}
|
||||
virtual void dbg_process_detach(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea) { };
|
||||
ea_t ea) {}
|
||||
virtual void dbg_thread_start(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea) { };
|
||||
ea_t ea) {}
|
||||
virtual void dbg_thread_exit(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea,
|
||||
int exit_code) { };
|
||||
int exit_code) {}
|
||||
virtual void dbg_library_load(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea,
|
||||
char *name,
|
||||
ea_t base,
|
||||
asize_t size) { };
|
||||
asize_t size) {}
|
||||
virtual void dbg_library_unload(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea,
|
||||
char *libname) { };
|
||||
char *libname) {}
|
||||
virtual void dbg_information(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea,
|
||||
char *info) { };
|
||||
char *info) {}
|
||||
virtual int dbg_exception(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea,
|
||||
int code,
|
||||
bool can_cont,
|
||||
ea_t exc_ea,
|
||||
char *info) { return 0; };
|
||||
virtual void dbg_suspend_process(void) { };
|
||||
virtual int dbg_bpt(thid_t tid, ea_t breakpoint_ea) { return 0; };
|
||||
virtual int dbg_trace(thid_t tid, ea_t ip) { return 0; };
|
||||
char *info) { return 0; }
|
||||
virtual void dbg_suspend_process(void) {}
|
||||
virtual int dbg_bpt(thid_t tid, ea_t breakpoint_ea) { return 0; }
|
||||
virtual int dbg_trace(thid_t tid, ea_t ip) { return 0; }
|
||||
virtual void dbg_request_error(int failed_command,
|
||||
int failed_dbg_notification) { };
|
||||
virtual void dbg_step_into(void) { };
|
||||
virtual void dbg_step_over(void) { };
|
||||
virtual void dbg_run_to(pid_t pid, thid_t tid, ea_t ea) { };
|
||||
virtual void dbg_step_until_ret(void) { };
|
||||
int failed_dbg_notification) {}
|
||||
virtual void dbg_step_into(void) {}
|
||||
virtual void dbg_step_over(void) {}
|
||||
virtual void dbg_run_to(pid_t pid, thid_t tid, ea_t ea) {}
|
||||
virtual void dbg_step_until_ret(void) {}
|
||||
};
|
||||
|
||||
int idaapi DBG_Callback(void *ud, int notification_code, va_list va)
|
||||
{
|
||||
// This hook gets called from the kernel. Ensure we hold the GIL.
|
||||
PYW_GIL_GET;
|
||||
|
||||
class DBG_Hooks *proxy = (class DBG_Hooks *)ud;
|
||||
debug_event_t *event;
|
||||
int code = 0;
|
||||
|
||||
try
|
||||
{
|
||||
switch (notification_code)
|
||||
|
7
pywraps/py_dbg.py
Normal file
7
pywraps/py_dbg.py
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
#<pycode(py_idd_2)>
|
||||
NO_PROCESS = 0xFFFFFFFF
|
||||
NO_THREAD = 0
|
||||
#</pycode(py_idd_2)>
|
||||
|
||||
|
@ -5,17 +5,17 @@
|
||||
//--------------------------------------------------------------------------
|
||||
int idaapi py_enumerate_files_cb(const char *file, void *ud)
|
||||
{
|
||||
PyObject *py_file = PyString_FromString(file);
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_ret = PyObject_CallFunctionObjArgs(
|
||||
(PyObject *)ud,
|
||||
py_file,
|
||||
NULL);
|
||||
PYW_GIL_RELEASE;
|
||||
int r = (py_ret == NULL || !PyNumber_Check(py_ret)) ? 1 /* stop enumeration on failure */ : PyInt_AsLong(py_ret);
|
||||
Py_XDECREF(py_file);
|
||||
Py_XDECREF(py_ret);
|
||||
return r;
|
||||
// No need to 'PYW_GIL_GET' here, as this is called synchronously
|
||||
// and from the same thread as the one that executes
|
||||
// 'py_enumerate_files'.
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t py_file(PyString_FromString(file));
|
||||
newref_t py_ret(
|
||||
PyObject_CallFunctionObjArgs(
|
||||
(PyObject *)ud,
|
||||
py_file.o,
|
||||
NULL));
|
||||
return (py_ret == NULL || !PyNumber_Check(py_ret.o)) ? 1 /* stop enum on failure */ : PyInt_AsLong(py_ret.o);
|
||||
}
|
||||
//</code(py_diskio)>
|
||||
|
||||
@ -31,7 +31,7 @@ def enumerate_files(path, fname, callback):
|
||||
@param callback: a callable object that takes the filename as
|
||||
its first argument and it returns 0 to continue
|
||||
enumeration or non-zero to stop enumeration.
|
||||
@return:
|
||||
@return:
|
||||
None in case of script errors
|
||||
tuple(code, fname) : If the callback returns non-zero
|
||||
"""
|
||||
@ -40,6 +40,8 @@ def enumerate_files(path, fname, callback):
|
||||
*/
|
||||
PyObject *py_enumerate_files(PyObject *path, PyObject *fname, PyObject *callback)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
do
|
||||
{
|
||||
if ( !PyString_Check(path) || !PyString_Check(fname) || !PyCallable_Check(callback) )
|
||||
|
@ -9,10 +9,12 @@ struct py_idcfunc_ctx_t
|
||||
int nargs;
|
||||
py_idcfunc_ctx_t(PyObject *py_func, const char *name, int nargs): py_func(py_func), name(name), nargs(nargs)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
Py_INCREF(py_func);
|
||||
}
|
||||
~py_idcfunc_ctx_t()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
Py_DECREF(py_func);
|
||||
}
|
||||
};
|
||||
@ -26,25 +28,25 @@ static error_t py_call_idc_func(
|
||||
// Convert IDC arguments to Python list
|
||||
py_idcfunc_ctx_t *ctx = (py_idcfunc_ctx_t *)_ctx;
|
||||
int cvt;
|
||||
ppyobject_vec_t pargs;
|
||||
char errbuf[MAXSTR];
|
||||
if ( !pyw_convert_idc_args(argv, ctx->nargs, pargs, NULL, errbuf, sizeof(errbuf)) )
|
||||
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
ref_vec_t pargs;
|
||||
if ( !pyw_convert_idc_args(argv, ctx->nargs, pargs, true, errbuf, sizeof(errbuf)) )
|
||||
{
|
||||
// Error during conversion? Create an IDC exception
|
||||
return PyW_CreateIdcException(r, errbuf);
|
||||
}
|
||||
|
||||
// Call the Python function
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallObject(
|
||||
ctx->py_func,
|
||||
pargs.empty() ? NULL : pargs[0]);
|
||||
|
||||
newref_t py_result(PyObject_CallObject(
|
||||
ctx->py_func,
|
||||
pargs.empty() ? NULL : pargs[0].o));
|
||||
|
||||
error_t err;
|
||||
if ( PyW_GetError(errbuf, sizeof(errbuf)) )
|
||||
{
|
||||
err = PyW_CreateIdcException(r, errbuf);
|
||||
Py_XDECREF(py_result);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -55,13 +57,7 @@ static error_t py_call_idc_func(
|
||||
err = PyW_CreateIdcException(r, "ERROR: bad return value");
|
||||
else
|
||||
err = eOk;
|
||||
if ( cvt != CIP_OK_NODECREF )
|
||||
Py_XDECREF(py_result);
|
||||
}
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
// Free the converted args
|
||||
pyw_free_idc_args(pargs);
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -153,4 +149,4 @@ bool CompileLine_wrap(const char *line, char *errbuf, size_t errbufsize)
|
||||
}
|
||||
|
||||
//</inline(py_expr)>
|
||||
#endif
|
||||
#endif
|
||||
|
1051
pywraps/py_graph.hpp
1051
pywraps/py_graph.hpp
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
#<pycode(py_graph)>
|
||||
class GraphViewer(object):
|
||||
class GraphViewer(CustomIDAMemo):
|
||||
"""This class wraps the user graphing facility provided by the graph.hpp file"""
|
||||
def __init__(self, title, close_open = False):
|
||||
"""
|
||||
@ -52,12 +52,6 @@ class GraphViewer(object):
|
||||
"""
|
||||
_idaapi.pyg_close(self)
|
||||
|
||||
def Refresh(self):
|
||||
"""
|
||||
Refreshes the graph. This causes the OnRefresh() to be called
|
||||
"""
|
||||
_idaapi.pyg_refresh(self)
|
||||
|
||||
def Show(self):
|
||||
"""
|
||||
Shows an existing graph or creates a new one
|
||||
@ -166,4 +160,4 @@ class GraphViewer(object):
|
||||
# """
|
||||
# print "command:", cmd_id
|
||||
#</pydoc>
|
||||
#</pycode(py_graph)>
|
||||
#</pycode(py_graph)>
|
||||
|
@ -53,11 +53,23 @@ static const char S_ON_GETTEXT[] = "OnGetText";
|
||||
static const char S_ON_ACTIVATE[] = "OnActivate";
|
||||
static const char S_ON_DEACTIVATE[] = "OnDeactivate";
|
||||
static const char S_ON_SELECT[] = "OnSelect";
|
||||
static const char S_ON_CREATING_GROUP[] = "OnCreatingGroup";
|
||||
static const char S_ON_DELETING_GROUP[] = "OnDeletingGroup";
|
||||
static const char S_ON_GROUP_VISIBILITY[] = "OnGroupVisibility";
|
||||
static const char S_M_EDGES[] = "_edges";
|
||||
static const char S_M_NODES[] = "_nodes";
|
||||
static const char S_M_THIS[] = "_this";
|
||||
static const char S_M_TITLE[] = "_title";
|
||||
static const char S_CLINK_NAME[] = "__clink__";
|
||||
static const char S_ON_VIEW_ACTIVATED[] = "OnViewActivated";
|
||||
static const char S_ON_VIEW_DEACTIVATED[] = "OnViewDeactivated";
|
||||
static const char S_ON_VIEW_KEYDOWN[] = "OnViewKeydown";
|
||||
static const char S_ON_VIEW_CLICK[] = "OnViewClick";
|
||||
static const char S_ON_VIEW_DBLCLICK[] = "OnViewDblclick";
|
||||
static const char S_ON_VIEW_CURPOS[] = "OnViewCurpos";
|
||||
static const char S_ON_VIEW_SWITCHED[] = "OnViewSwitched";
|
||||
static const char S_ON_VIEW_MOUSE_OVER[] = "OnViewMouseOver";
|
||||
|
||||
|
||||
#ifdef __PYWRAPS__
|
||||
static const char S_PY_IDAAPI_MODNAME[] = "__main__";
|
||||
@ -66,7 +78,7 @@ static const char S_PY_IDAAPI_MODNAME[] = S_IDAAPI_MODNAME;
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static PyObject *py_cvt_helper_module = NULL;
|
||||
static ref_t py_cvt_helper_module;
|
||||
static bool pywraps_initialized = false;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@ -155,19 +167,16 @@ static error_t idaapi idc_py_invoke0(
|
||||
idc_value_t *argv,
|
||||
idc_value_t *res)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyObject *pyfunc = (PyObject *) argv[0].pvoid;
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallFunctionObjArgs(pyfunc, NULL);
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
Py_XDECREF(py_result);
|
||||
newref_t py_result(PyObject_CallFunctionObjArgs(pyfunc, NULL));
|
||||
|
||||
// Report Python error as IDC exception
|
||||
qstring err;
|
||||
error_t err_code = eOk;
|
||||
if ( PyW_GetError(&err) )
|
||||
return PyW_CreateIdcException(res, err.c_str());
|
||||
|
||||
return eOk;
|
||||
err_code = PyW_CreateIdcException(res, err.c_str());
|
||||
return err_code;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
@ -223,8 +232,11 @@ void deinit_pywraps()
|
||||
return;
|
||||
|
||||
pywraps_initialized = false;
|
||||
Py_XDECREF(py_cvt_helper_module);
|
||||
py_cvt_helper_module = NULL;
|
||||
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
py_cvt_helper_module = ref_t(); // Deref.
|
||||
}
|
||||
|
||||
// Unregister the IDC PyInvoke0 method (helper function for add_idc_hotkey())
|
||||
set_idc_func_ex(S_PYINVOKE0, NULL, idc_py_invoke0_args, 0);
|
||||
@ -232,47 +244,34 @@ void deinit_pywraps()
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Utility function to create a class instance whose constructor takes zero arguments
|
||||
PyObject *create_idaapi_class_instance0(const char *clsname)
|
||||
ref_t create_idaapi_class_instance0(const char *clsname)
|
||||
{
|
||||
PyObject *py_cls = get_idaapi_attr(clsname);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
ref_t py_cls(get_idaapi_attr(clsname));
|
||||
if ( py_cls == NULL )
|
||||
return NULL;
|
||||
return ref_t();
|
||||
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_obj = PyObject_CallFunctionObjArgs(py_cls, NULL);
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
Py_DECREF(py_cls);
|
||||
ref_t py_obj = newref_t(PyObject_CallFunctionObjArgs(py_cls.o, NULL));
|
||||
if ( PyW_GetError() || py_obj == NULL )
|
||||
{
|
||||
Py_XDECREF(py_obj);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
py_obj = ref_t();
|
||||
return py_obj;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Utility function to create linked class instances
|
||||
PyObject *create_idaapi_linked_class_instance(
|
||||
ref_t create_idaapi_linked_class_instance(
|
||||
const char *clsname,
|
||||
void *lnk)
|
||||
{
|
||||
PyObject *py_cls = get_idaapi_attr(clsname);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
ref_t py_cls(get_idaapi_attr(clsname));
|
||||
if ( py_cls == NULL )
|
||||
return NULL;
|
||||
|
||||
PyObject *py_lnk = PyCObject_FromVoidPtr(lnk, NULL);
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_obj = PyObject_CallFunctionObjArgs(py_cls, py_lnk, NULL);
|
||||
PYW_GIL_RELEASE;
|
||||
Py_DECREF(py_cls);
|
||||
Py_DECREF(py_lnk);
|
||||
return ref_t();
|
||||
|
||||
newref_t py_lnk(PyCObject_FromVoidPtr(lnk, NULL));
|
||||
ref_t py_obj = newref_t(PyObject_CallFunctionObjArgs(py_cls.o, py_lnk.o, NULL));
|
||||
if ( PyW_GetError() || py_obj == NULL )
|
||||
{
|
||||
Py_XDECREF(py_obj);
|
||||
py_obj = NULL;
|
||||
}
|
||||
py_obj = ref_t();
|
||||
return py_obj;
|
||||
}
|
||||
|
||||
@ -280,10 +279,10 @@ PyObject *create_idaapi_linked_class_instance(
|
||||
// Gets a class type reference in idaapi
|
||||
// With the class type reference we can create a new instance of that type
|
||||
// This function takes a reference to the idaapi module and keeps the reference
|
||||
PyObject *get_idaapi_attr_by_id(const int class_id)
|
||||
ref_t get_idaapi_attr_by_id(const int class_id)
|
||||
{
|
||||
if ( class_id >= PY_CLSID_LAST || py_cvt_helper_module == NULL )
|
||||
return NULL;
|
||||
return ref_t();
|
||||
|
||||
// Some class names. The array is parallel with the PY_CLSID_xxx consts
|
||||
static const char *class_names[]=
|
||||
@ -292,16 +291,18 @@ PyObject *get_idaapi_attr_by_id(const int class_id)
|
||||
"object_t",
|
||||
"PyIdc_cvt_refclass__"
|
||||
};
|
||||
return PyObject_GetAttrString(py_cvt_helper_module, class_names[class_id]);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return newref_t(PyObject_GetAttrString(py_cvt_helper_module.o, class_names[class_id]));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Gets a class reference by name
|
||||
PyObject *get_idaapi_attr(const char *attrname)
|
||||
ref_t get_idaapi_attr(const char *attrname)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return py_cvt_helper_module == NULL
|
||||
? NULL
|
||||
: PyW_TryGetAttrString(py_cvt_helper_module, attrname);
|
||||
? ref_t()
|
||||
: PyW_TryGetAttrString(py_cvt_helper_module.o, attrname);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
@ -311,41 +312,39 @@ bool PyW_GetStringAttr(
|
||||
const char *attr_name,
|
||||
qstring *str)
|
||||
{
|
||||
PyObject *py_attr = PyW_TryGetAttrString(py_obj, attr_name);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
ref_t py_attr(PyW_TryGetAttrString(py_obj, attr_name));
|
||||
if ( py_attr == NULL )
|
||||
return false;
|
||||
|
||||
bool ok = PyString_Check(py_attr) != 0;
|
||||
bool ok = PyString_Check(py_attr.o) != 0;
|
||||
if ( ok )
|
||||
*str = PyString_AsString(py_attr);
|
||||
*str = PyString_AsString(py_attr.o);
|
||||
|
||||
Py_DECREF(py_attr);
|
||||
return ok;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Returns an attribute or NULL
|
||||
// No errors will be set if the attribute did not exist
|
||||
PyObject *PyW_TryGetAttrString(PyObject *py_obj, const char *attr)
|
||||
ref_t PyW_TryGetAttrString(PyObject *py_obj, const char *attr)
|
||||
{
|
||||
if ( !PyObject_HasAttrString(py_obj, attr) )
|
||||
return NULL;
|
||||
else
|
||||
return PyObject_GetAttrString(py_obj, attr);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
ref_t o;
|
||||
if ( PyObject_HasAttrString(py_obj, attr) )
|
||||
o = newref_t(PyObject_GetAttrString(py_obj, attr));
|
||||
return o;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Tries to import a module and clears the exception on failure
|
||||
PyObject *PyW_TryImportModule(const char *name)
|
||||
ref_t PyW_TryImportModule(const char *name)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *result = PyImport_ImportModule(name);
|
||||
PYW_GIL_RELEASE;
|
||||
if ( result != NULL )
|
||||
return result;
|
||||
if ( PyErr_Occurred() )
|
||||
PyErr_Clear();
|
||||
return NULL;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t result(PyImport_ImportModule(name));
|
||||
if ( result == NULL && PyErr_Occurred() )
|
||||
PyErr_Clear();
|
||||
return result;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -358,144 +357,158 @@ PyObject *PyW_TryImportModule(const char *name)
|
||||
// And because of that we are confused as to whether to convert to 32 or 64
|
||||
bool PyW_GetNumberAsIDC(PyObject *py_var, idc_value_t *idc_var)
|
||||
{
|
||||
if ( !(PyInt_CheckExact(py_var) || PyLong_CheckExact(py_var)) )
|
||||
return false;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
bool rc = true;
|
||||
do
|
||||
{
|
||||
if ( !(PyInt_CheckExact(py_var) || PyLong_CheckExact(py_var)) )
|
||||
{
|
||||
rc = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Can we convert to C long?
|
||||
long l = PyInt_AsLong(py_var);
|
||||
if ( !PyErr_Occurred() )
|
||||
{
|
||||
idc_var->set_long(l);
|
||||
return true;
|
||||
}
|
||||
// Clear last error
|
||||
PyErr_Clear();
|
||||
// Can be fit into a C unsigned long?
|
||||
l = (long) PyLong_AsUnsignedLong(py_var);
|
||||
if ( !PyErr_Occurred() )
|
||||
{
|
||||
idc_var->set_long(l);
|
||||
return true;
|
||||
}
|
||||
PyErr_Clear();
|
||||
idc_var->set_int64(PyLong_AsLongLong(py_var));
|
||||
return true;
|
||||
// Can we convert to C long?
|
||||
long l = PyInt_AsLong(py_var);
|
||||
if ( !PyErr_Occurred() )
|
||||
{
|
||||
idc_var->set_long(l);
|
||||
break;
|
||||
}
|
||||
// Clear last error
|
||||
PyErr_Clear();
|
||||
// Can be fit into a C unsigned long?
|
||||
l = (long) PyLong_AsUnsignedLong(py_var);
|
||||
if ( !PyErr_Occurred() )
|
||||
{
|
||||
idc_var->set_long(l);
|
||||
break;
|
||||
}
|
||||
PyErr_Clear();
|
||||
idc_var->set_int64(PyLong_AsLongLong(py_var));
|
||||
} while ( false );
|
||||
return rc;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Parses a Python object as a long or long long
|
||||
bool PyW_GetNumber(PyObject *py_var, uint64 *num, bool *is_64)
|
||||
{
|
||||
if ( !(PyInt_CheckExact(py_var) || PyLong_CheckExact(py_var)) )
|
||||
return false;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
bool rc = true;
|
||||
#define SETNUM(numexpr, is64_expr) \
|
||||
do \
|
||||
{ \
|
||||
if ( num != NULL ) \
|
||||
*num = numexpr; \
|
||||
if ( is_64 != NULL ) \
|
||||
*is_64 = is64_expr; \
|
||||
} while ( false )
|
||||
|
||||
// Can we convert to C long?
|
||||
long l = PyInt_AsLong(py_var);
|
||||
if ( !PyErr_Occurred() )
|
||||
do
|
||||
{
|
||||
if ( num != NULL )
|
||||
*num = uint64(l);
|
||||
if ( is_64 != NULL )
|
||||
*is_64 = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Clear last error
|
||||
PyErr_Clear();
|
||||
|
||||
// Can be fit into a C unsigned long?
|
||||
unsigned long ul = PyLong_AsUnsignedLong(py_var);
|
||||
if ( !PyErr_Occurred() )
|
||||
{
|
||||
if ( num != NULL )
|
||||
*num = uint64(ul);
|
||||
if ( is_64 != NULL )
|
||||
*is_64 = false;
|
||||
return true;
|
||||
}
|
||||
PyErr_Clear();
|
||||
|
||||
// Try to parse as int64
|
||||
PY_LONG_LONG ll = PyLong_AsLongLong(py_var);
|
||||
if ( !PyErr_Occurred() )
|
||||
{
|
||||
if ( num != NULL )
|
||||
*num = uint64(ll);
|
||||
if ( is_64 != NULL )
|
||||
*is_64 = true;
|
||||
return true;
|
||||
}
|
||||
PyErr_Clear();
|
||||
|
||||
// Try to parse as uint64
|
||||
unsigned PY_LONG_LONG ull = PyLong_AsUnsignedLongLong(py_var);
|
||||
PyObject *err = PyErr_Occurred();
|
||||
if ( err == NULL )
|
||||
{
|
||||
if ( num != NULL )
|
||||
*num = uint64(ull);
|
||||
if ( is_64 != NULL )
|
||||
*is_64 = true;
|
||||
return true;
|
||||
}
|
||||
// Negative number? _And_ it with uint64(-1)
|
||||
bool ok = false;
|
||||
if ( err == PyExc_TypeError )
|
||||
{
|
||||
PyObject *py_mask = Py_BuildValue("K", 0xFFFFFFFFFFFFFFFFull);
|
||||
PyObject *py_num = PyNumber_And(py_var, py_mask);
|
||||
if ( py_num != NULL && py_mask != NULL )
|
||||
if ( !(PyInt_CheckExact(py_var) || PyLong_CheckExact(py_var)) )
|
||||
{
|
||||
PyErr_Clear();
|
||||
ull = PyLong_AsUnsignedLongLong(py_num);
|
||||
if ( !PyErr_Occurred() )
|
||||
rc = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Can we convert to C long?
|
||||
long l = PyInt_AsLong(py_var);
|
||||
if ( !PyErr_Occurred() )
|
||||
{
|
||||
SETNUM(uint64(l), false);
|
||||
break;
|
||||
}
|
||||
|
||||
// Clear last error
|
||||
PyErr_Clear();
|
||||
|
||||
// Can be fit into a C unsigned long?
|
||||
unsigned long ul = PyLong_AsUnsignedLong(py_var);
|
||||
if ( !PyErr_Occurred() )
|
||||
{
|
||||
SETNUM(uint64(ul), false);
|
||||
break;
|
||||
}
|
||||
PyErr_Clear();
|
||||
|
||||
// Try to parse as int64
|
||||
PY_LONG_LONG ll = PyLong_AsLongLong(py_var);
|
||||
if ( !PyErr_Occurred() )
|
||||
{
|
||||
SETNUM(uint64(ll), true);
|
||||
break;
|
||||
}
|
||||
PyErr_Clear();
|
||||
|
||||
// Try to parse as uint64
|
||||
unsigned PY_LONG_LONG ull = PyLong_AsUnsignedLongLong(py_var);
|
||||
PyObject *err = PyErr_Occurred();
|
||||
if ( err == NULL )
|
||||
{
|
||||
SETNUM(uint64(ull), true);
|
||||
break;
|
||||
}
|
||||
// Negative number? _And_ it with uint64(-1)
|
||||
rc = false;
|
||||
if ( err == PyExc_TypeError )
|
||||
{
|
||||
newref_t py_mask(Py_BuildValue("K", 0xFFFFFFFFFFFFFFFFull));
|
||||
newref_t py_num(PyNumber_And(py_var, py_mask.o));
|
||||
if ( py_num != NULL && py_mask != NULL )
|
||||
{
|
||||
if ( num != NULL )
|
||||
*num = uint64(ull);
|
||||
if ( is_64 != NULL )
|
||||
*is_64 = true;
|
||||
ok = true;
|
||||
PyErr_Clear();
|
||||
ull = PyLong_AsUnsignedLongLong(py_num.o);
|
||||
if ( !PyErr_Occurred() )
|
||||
{
|
||||
SETNUM(uint64(ull), true);
|
||||
rc = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Py_XDECREF(py_num);
|
||||
Py_XDECREF(py_mask);
|
||||
}
|
||||
PyErr_Clear();
|
||||
return ok;
|
||||
PyErr_Clear();
|
||||
} while ( false );
|
||||
return rc;
|
||||
#undef SETNUM
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Checks if a given object is of sequence type
|
||||
bool PyW_IsSequenceType(PyObject *obj)
|
||||
{
|
||||
if ( !PySequence_Check(obj) )
|
||||
return false;
|
||||
|
||||
Py_ssize_t sz = PySequence_Size(obj);
|
||||
if ( sz == -1 || PyErr_Occurred() != NULL )
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
bool rc = true;
|
||||
do
|
||||
{
|
||||
PyErr_Clear();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if ( !PySequence_Check(obj) )
|
||||
{
|
||||
rc = false;
|
||||
break;
|
||||
}
|
||||
|
||||
Py_ssize_t sz = PySequence_Size(obj);
|
||||
if ( sz == -1 || PyErr_Occurred() != NULL )
|
||||
{
|
||||
PyErr_Clear();
|
||||
rc = false;
|
||||
break;
|
||||
}
|
||||
} while ( false );
|
||||
return rc;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Returns the string representation of an object
|
||||
bool PyW_ObjectToString(PyObject *obj, qstring *out)
|
||||
{
|
||||
PyObject *py_str = PyObject_Str(obj);
|
||||
if ( py_str != NULL )
|
||||
{
|
||||
*out = PyString_AsString(py_str);
|
||||
Py_DECREF(py_str);
|
||||
return true;
|
||||
}
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t py_str(PyObject_Str(obj));
|
||||
bool ok = py_str != NULL;
|
||||
if ( ok )
|
||||
*out = PyString_AsString(py_str.o);
|
||||
else
|
||||
{
|
||||
out->qclear();
|
||||
return false;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@ -503,6 +516,8 @@ bool PyW_ObjectToString(PyObject *obj, qstring *out)
|
||||
// exception string
|
||||
bool PyW_GetError(qstring *out, bool clear_err)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
if ( PyErr_Occurred() == NULL )
|
||||
return false;
|
||||
|
||||
@ -523,23 +538,18 @@ bool PyW_GetError(qstring *out, bool clear_err)
|
||||
PyErr_Restore(err_type, err_value, err_traceback);
|
||||
|
||||
// Resolve FormatExc()
|
||||
PyObject *py_fmtexc = get_idaapi_attr(S_IDAAPI_FORMATEXC);
|
||||
ref_t py_fmtexc(get_idaapi_attr(S_IDAAPI_FORMATEXC));
|
||||
|
||||
// Helper there?
|
||||
if ( py_fmtexc != NULL )
|
||||
{
|
||||
// Call helper
|
||||
PYW_GIL_ENSURE;
|
||||
py_ret = PyObject_CallFunctionObjArgs(
|
||||
py_fmtexc,
|
||||
py_fmtexc.o,
|
||||
err_type,
|
||||
err_value,
|
||||
err_traceback,
|
||||
NULL);
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
// Dispose helper reference
|
||||
Py_DECREF(py_fmtexc);
|
||||
}
|
||||
|
||||
// Clear the error
|
||||
@ -576,6 +586,8 @@ bool PyW_GetError(qstring *out, bool clear_err)
|
||||
//-------------------------------------------------------------------------
|
||||
bool PyW_GetError(char *buf, size_t bufsz, bool clear_err)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
qstring s;
|
||||
if ( !PyW_GetError(&s, clear_err) )
|
||||
return false;
|
||||
@ -589,6 +601,8 @@ bool PyW_GetError(char *buf, size_t bufsz, bool clear_err)
|
||||
// This method is used to display errors that occurred in a callback
|
||||
bool PyW_ShowCbErr(const char *cb_name)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
static qstring err_str;
|
||||
if ( !PyW_GetError(&err_str) )
|
||||
return false;
|
||||
@ -600,10 +614,11 @@ bool PyW_ShowCbErr(const char *cb_name)
|
||||
//---------------------------------------------------------------------------
|
||||
void *pyobj_get_clink(PyObject *pyobj)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
// Try to query the link attribute
|
||||
PyObject *attr = PyW_TryGetAttrString(pyobj, S_CLINK_NAME);
|
||||
void *t = attr != NULL && PyCObject_Check(attr) ? PyCObject_AsVoidPtr(attr) : NULL;
|
||||
Py_XDECREF(attr);
|
||||
ref_t attr(PyW_TryGetAttrString(pyobj, S_CLINK_NAME));
|
||||
void *t = attr != NULL && PyCObject_Check(attr.o) ? PyCObject_AsVoidPtr(attr.o) : NULL;
|
||||
return t;
|
||||
}
|
||||
|
||||
@ -624,8 +639,10 @@ def parse_command_line(cmdline):
|
||||
*/
|
||||
static PyObject *py_parse_command_line(const char *cmdline)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
qstrvec_t args;
|
||||
if ( parse_command_line2(cmdline, &args, NULL) == 0 )
|
||||
if ( parse_command_line3(cmdline, &args, NULL, LP_PATH_WITH_ARGS) == 0 )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
PyObject *py_list = PyList_New(args.size());
|
||||
@ -727,6 +744,7 @@ static bool qstrvec_t_assign(PyObject *self, PyObject *other)
|
||||
|
||||
static PyObject *qstrvec_t_addressof(PyObject *self, size_t idx)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
qstrvec_t *sv = qstrvec_t_get_clink(self);
|
||||
if ( sv == NULL || idx >= sv->size() )
|
||||
Py_RETURN_NONE;
|
||||
@ -751,6 +769,7 @@ static bool qstrvec_t_from_list(
|
||||
PyObject *self,
|
||||
PyObject *py_list)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
qstrvec_t *sv = qstrvec_t_get_clink(self);
|
||||
return sv == NULL ? false : PyW_PyListToStrVec(py_list, *sv);
|
||||
}
|
||||
@ -763,6 +782,7 @@ static size_t qstrvec_t_size(PyObject *self)
|
||||
|
||||
static PyObject *qstrvec_t_get(PyObject *self, size_t idx)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
qstrvec_t *sv = qstrvec_t_get_clink(self);
|
||||
if ( sv == NULL || idx >= sv->size() )
|
||||
Py_RETURN_NONE;
|
||||
|
@ -18,6 +18,36 @@ import os
|
||||
import sys
|
||||
import bisect
|
||||
import __builtin__
|
||||
import imp
|
||||
|
||||
def require(modulename):
|
||||
"""
|
||||
Load, or reload a module.
|
||||
|
||||
When under heavy development, a user's tool might consist of multiple
|
||||
modules. If those are imported using the standard 'import' mechanism,
|
||||
there is no guarantee that the Python implementation will re-read
|
||||
and re-evaluate the module's Python code. In fact, it usually doesn't.
|
||||
What should be done instead is 'reload()'-ing that module.
|
||||
|
||||
This is a simple helper function that will do just that: In case the
|
||||
module doesn't exist, it 'import's it, and if it does exist,
|
||||
'reload()'s it.
|
||||
|
||||
For more information, see: <http://www.hexblog.com/?p=749>.
|
||||
"""
|
||||
if modulename in sys.modules.keys():
|
||||
reload(sys.modules[modulename])
|
||||
else:
|
||||
import importlib
|
||||
import inspect
|
||||
m = importlib.import_module(modulename)
|
||||
frame_obj, filename, line_number, function_name, lines, index = inspect.stack()[1]
|
||||
importer_module = inspect.getmodule(frame_obj)
|
||||
if importer_module is None: # No importer module; called from command line
|
||||
importer_module = sys.modules['__main__']
|
||||
setattr(importer_module, modulename, m)
|
||||
sys.modules[modulename] = m
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
@ -403,11 +433,7 @@ def IDAPython_ExecScript(script, g):
|
||||
if len(scriptpath) and scriptpath not in sys.path:
|
||||
sys.path.append(scriptpath)
|
||||
|
||||
# Save the argv, path, I/O and base modules for later cleanup
|
||||
argv = sys.argv
|
||||
path = sys.path
|
||||
stdio = [sys.stdin, sys.stdout, sys.stderr]
|
||||
basemodules = sys.modules.copy()
|
||||
sys.argv = [ script ]
|
||||
|
||||
# Adjust the __file__ path in the globals we pass to the script
|
||||
@ -421,18 +447,65 @@ def IDAPython_ExecScript(script, g):
|
||||
PY_COMPILE_ERR = "%s\n%s" % (str(e), traceback.format_exc())
|
||||
print(PY_COMPILE_ERR)
|
||||
finally:
|
||||
# Restore the globals to the state before the script was run
|
||||
# Restore state
|
||||
g['__file__'] = old__file__
|
||||
|
||||
sys.argv = argv
|
||||
sys.path = path
|
||||
sys.stdin, sys.stdout, sys.stderr = stdio
|
||||
|
||||
# Clean up the modules loaded by the script
|
||||
for module in sys.modules.keys():
|
||||
if not module in basemodules:
|
||||
del sys.modules[module]
|
||||
return PY_COMPILE_ERR
|
||||
|
||||
# ------------------------------------------------------------
|
||||
def IDAPython_LoadProcMod(script, g):
|
||||
"""
|
||||
Load processor module.
|
||||
"""
|
||||
pname = g['__name__'] if g and g.has_key("__name__") else '__main__'
|
||||
parent = sys.modules[pname]
|
||||
|
||||
scriptpath, scriptname = os.path.split(script)
|
||||
if len(scriptpath) and scriptpath not in sys.path:
|
||||
sys.path.append(scriptpath)
|
||||
|
||||
procmod_name = os.path.splitext(scriptname)[0]
|
||||
procobj = None
|
||||
fp = None
|
||||
try:
|
||||
fp, pathname, description = imp.find_module(procmod_name)
|
||||
procmod = imp.load_module(procmod_name, fp, pathname, description)
|
||||
if parent:
|
||||
setattr(parent, procmod_name, procmod)
|
||||
# export attrs from parent to processor module
|
||||
parent_attrs = getattr(parent, '__all__',
|
||||
(attr for attr in dir(parent) if not attr.startswith('_')))
|
||||
for pa in parent_attrs:
|
||||
setattr(procmod, pa, getattr(parent, pa))
|
||||
# instantiate processor object
|
||||
if getattr(procmod, 'PROCESSOR_ENTRY', None):
|
||||
procobj = procmod.PROCESSOR_ENTRY()
|
||||
PY_COMPILE_ERR = None
|
||||
except Exception as e:
|
||||
PY_COMPILE_ERR = "%s\n%s" % (str(e), traceback.format_exc())
|
||||
print(PY_COMPILE_ERR)
|
||||
finally:
|
||||
if fp: fp.close()
|
||||
|
||||
sys.path.remove(scriptpath)
|
||||
|
||||
return (PY_COMPILE_ERR, procobj)
|
||||
|
||||
# ------------------------------------------------------------
|
||||
def IDAPython_UnLoadProcMod(script, g):
|
||||
"""
|
||||
Unload processor module.
|
||||
"""
|
||||
pname = g['__name__'] if g and g.has_key("__name__") else '__main__'
|
||||
parent = sys.modules[pname]
|
||||
|
||||
scriptname = os.path.split(script)[1]
|
||||
procmod_name = os.path.splitext(scriptname)[0]
|
||||
if getattr(parent, procmod_name, None):
|
||||
delattr(parent, procmod_name)
|
||||
del sys.modules[procmod_name]
|
||||
PY_COMPILE_ERR = None
|
||||
return PY_COMPILE_ERR
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
75
pywraps/py_idaview.hpp
Normal file
75
pywraps/py_idaview.hpp
Normal file
@ -0,0 +1,75 @@
|
||||
#ifndef __PY_IDA_VIEW__
|
||||
#define __PY_IDA_VIEW__
|
||||
|
||||
//<code(py_idaview)>
|
||||
class py_idaview_t : public py_customidamemo_t
|
||||
{
|
||||
typedef py_customidamemo_t inherited;
|
||||
|
||||
public:
|
||||
static bool Bind(PyObject *self);
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
bool py_idaview_t::Bind(PyObject *self)
|
||||
{
|
||||
// Already a py_idaview_t associated to this object?
|
||||
py_idaview_t *_this = view_extract_this<py_idaview_t>(self);
|
||||
if ( _this != NULL )
|
||||
return false;
|
||||
|
||||
qstring title;
|
||||
if ( !PyW_GetStringAttr(self, S_M_TITLE, &title) )
|
||||
return false;
|
||||
|
||||
// Get the IDAView associated to this TForm
|
||||
TForm *tform = find_tform(title.c_str());
|
||||
if ( tform == NULL )
|
||||
return false;
|
||||
TCustomControl *v = get_tform_idaview(tform);
|
||||
if ( v == NULL )
|
||||
return false;
|
||||
|
||||
// Get unique py_idaview_t associated to that tform
|
||||
py_idaview_t *py_view;
|
||||
TCustomControl *found_view;
|
||||
if ( lookup_info.find_by_form(&found_view, (py_customidamemo_t**) &py_view, tform) )
|
||||
{
|
||||
// If we have a py_idaview_t for that form, ensure it has
|
||||
// the expected view.
|
||||
QASSERT(30451, found_view == v);
|
||||
}
|
||||
else
|
||||
{
|
||||
py_view = new py_idaview_t();
|
||||
lookup_info.add(tform, v, py_view);
|
||||
}
|
||||
|
||||
// Finally, bind:
|
||||
// py_idaview_t <=> IDAViewWrapper
|
||||
// py_idaview_t => TCustomControl
|
||||
bool ok = py_view->bind(self, v);
|
||||
if ( ok )
|
||||
{
|
||||
ok = py_view->collect_pyobject_callbacks(self);
|
||||
if ( !ok )
|
||||
delete py_view;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
bool pyidag_bind(PyObject *self)
|
||||
{
|
||||
return py_idaview_t::Bind(self);
|
||||
}
|
||||
|
||||
//</code(py_idaview)>
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
//<inline(py_idaview)>
|
||||
bool pyidag_bind(PyObject *self);
|
||||
//</inline(py_idaview)>
|
||||
|
||||
#endif // __PY_IDA_VIEW__
|
16
pywraps/py_idaview.py
Normal file
16
pywraps/py_idaview.py
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
#<pycode(py_idaview)>
|
||||
class IDAViewWrapper(CustomIDAMemo):
|
||||
"""This class wraps access to native IDA views. See kernwin.hpp file"""
|
||||
def __init__(self, title):
|
||||
"""
|
||||
Constructs the IDAViewWrapper object around the view
|
||||
whose title is 'title'.
|
||||
|
||||
@param title: The title of the existing IDA view. E.g., 'IDA View-A'
|
||||
"""
|
||||
self._title = title
|
||||
|
||||
def Bind(self):
|
||||
return _idaapi.pyidag_bind(self)
|
||||
#</pycode(py_idaview)>
|
@ -33,12 +33,17 @@ static PyObject *AssembleLine(
|
||||
{
|
||||
int inslen;
|
||||
char buf[MAXSTR];
|
||||
bool ok = false;
|
||||
if (ph.notify != NULL &&
|
||||
(inslen = ph.notify(ph.assemble, ea, cs, ip, use32, line, buf)) > 0)
|
||||
(inslen = ph.notify(ph.assemble, ea, cs, ip, use32, line, buf)) > 0)
|
||||
{
|
||||
return PyString_FromStringAndSize(buf, inslen);
|
||||
ok = true;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( ok )
|
||||
return PyString_FromStringAndSize(buf, inslen);
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@ -66,17 +71,20 @@ bool assemble(
|
||||
{
|
||||
int inslen;
|
||||
char buf[MAXSTR];
|
||||
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
bool rc = false;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
if (ph.notify != NULL)
|
||||
{
|
||||
inslen = ph.notify(ph.assemble, ea, cs, ip, use32, line, buf);
|
||||
inslen = ph.notify(ph.assemble, ea, cs, ip, use32, line, buf);
|
||||
if (inslen > 0)
|
||||
{
|
||||
patch_many_bytes(ea, buf, inslen);
|
||||
return true;
|
||||
rc = true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -318,6 +326,7 @@ def ph_get_instruc():
|
||||
static PyObject *ph_get_instruc()
|
||||
{
|
||||
Py_ssize_t i = 0;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyObject *py_result = PyTuple_New(ph.instruc_end - ph.instruc_start);
|
||||
for ( const instruc_t *p = ph.instruc + ph.instruc_start, *end = ph.instruc + ph.instruc_end;
|
||||
p != end;
|
||||
@ -341,10 +350,10 @@ def ph_get_regnames():
|
||||
static PyObject *ph_get_regnames()
|
||||
{
|
||||
Py_ssize_t i = 0;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyObject *py_result = PyList_New(ph.regsNum);
|
||||
for ( Py_ssize_t i=0; i<ph.regsNum; i++ )
|
||||
PyList_SetItem(py_result, i, PyString_FromString(ph.regNames[i]));
|
||||
|
||||
return py_result;
|
||||
}
|
||||
|
||||
@ -372,6 +381,10 @@ static PyObject *ph_get_operand_info(
|
||||
ea_t ea,
|
||||
int n)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
bool ok = false;
|
||||
idd_opinfo_t opinf;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
do
|
||||
{
|
||||
if ( dbg == NULL || n == - 1 )
|
||||
@ -386,7 +399,6 @@ static PyObject *ph_get_operand_info(
|
||||
break;
|
||||
|
||||
// Call the processor module
|
||||
idd_opinfo_t opinf;
|
||||
if ( ph.notify(ph.get_operand_info,
|
||||
ea,
|
||||
n,
|
||||
@ -397,14 +409,19 @@ static PyObject *ph_get_operand_info(
|
||||
{
|
||||
break;
|
||||
}
|
||||
return Py_BuildValue("(i" PY_FMT64 "Kii)",
|
||||
opinf.modified,
|
||||
opinf.ea,
|
||||
opinf.value.ival,
|
||||
opinf.debregidx,
|
||||
opinf.value_size);
|
||||
ok = true;
|
||||
} while (false);
|
||||
Py_RETURN_NONE;
|
||||
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( ok )
|
||||
return Py_BuildValue("(i" PY_FMT64 "Kii)",
|
||||
opinf.modified,
|
||||
opinf.ea,
|
||||
opinf.value.ival,
|
||||
opinf.debregidx,
|
||||
opinf.value_size);
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -785,6 +802,7 @@ public:
|
||||
bool /*use32*/,
|
||||
const char * /*line*/)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
};
|
||||
@ -847,6 +865,8 @@ public:
|
||||
//-------------------------------------------------------------------------
|
||||
int idaapi IDP_Callback(void *ud, int notification_code, va_list va)
|
||||
{
|
||||
// This hook gets called from the kernel. Ensure we hold the GIL.
|
||||
PYW_GIL_GET;
|
||||
IDP_Hooks *proxy = (IDP_Hooks *)ud;
|
||||
int ret = 0;
|
||||
try
|
||||
@ -868,16 +888,16 @@ int idaapi IDP_Callback(void *ud, int notification_code, va_list va)
|
||||
case processor_t::custom_outop:
|
||||
{
|
||||
op_t *op = va_arg(va, op_t *);
|
||||
PyObject *py_obj = create_idaapi_linked_class_instance(S_PY_OP_T_CLSNAME, op);
|
||||
ref_t py_obj(create_idaapi_linked_class_instance(S_PY_OP_T_CLSNAME, op));
|
||||
if ( py_obj == NULL )
|
||||
break;
|
||||
ret = proxy->custom_outop(py_obj) ? 2 : 0;
|
||||
Py_XDECREF(py_obj);
|
||||
ret = proxy->custom_outop(py_obj.o) ? 2 : 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case processor_t::custom_mnem:
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyObject *py_ret = proxy->custom_mnem();
|
||||
if ( py_ret != NULL && PyString_Check(py_ret) )
|
||||
{
|
||||
@ -1009,6 +1029,7 @@ int idaapi IDP_Callback(void *ud, int notification_code, va_list va)
|
||||
// Extract user buffer (we hardcode the MAXSTR size limit)
|
||||
uchar *bin = va_arg(va, uchar *);
|
||||
// Call python
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyObject *py_buffer = proxy->assemble(ea, cs, ip, use32, line);
|
||||
if ( py_buffer != NULL && PyString_Check(py_buffer) )
|
||||
{
|
||||
@ -1328,6 +1349,7 @@ int idaapi IDP_Callback(void *ud, int notification_code, va_list va)
|
||||
catch (Swig::DirectorException &e)
|
||||
{
|
||||
msg("Exception in IDP Hook function: %s\n", e.getMessage());
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( PyErr_Occurred() )
|
||||
PyErr_Print();
|
||||
}
|
||||
@ -1337,6 +1359,9 @@ int idaapi IDP_Callback(void *ud, int notification_code, va_list va)
|
||||
//---------------------------------------------------------------------------
|
||||
int idaapi IDB_Callback(void *ud, int notification_code, va_list va)
|
||||
{
|
||||
// This hook gets called from the kernel. Ensure we hold the GIL.
|
||||
PYW_GIL_GET;
|
||||
|
||||
class IDB_Hooks *proxy = (class IDB_Hooks *)ud;
|
||||
ea_t ea, ea2;
|
||||
bool repeatable_cmt;
|
||||
@ -1508,10 +1533,9 @@ int idaapi IDB_Callback(void *ud, int notification_code, va_list va)
|
||||
catch (Swig::DirectorException &e)
|
||||
{
|
||||
msg("Exception in IDB Hook function: %s\n", e.getMessage());
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
PyErr_Print();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ def register_timer(interval, callback):
|
||||
*/
|
||||
static PyObject *py_register_timer(int interval, PyObject *py_callback)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
if ( py_callback == NULL || !PyCallable_Check(py_callback) )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
@ -32,17 +34,15 @@ static PyObject *py_register_timer(int interval, PyObject *py_callback)
|
||||
{
|
||||
static int idaapi callback(void *ud)
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
py_timer_ctx_t *ctx = (py_timer_ctx_t *)ud;
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallFunctionObjArgs(ctx->pycallback, NULL);
|
||||
int ret = py_result == NULL ? -1 : PyLong_AsLong(py_result);
|
||||
Py_XDECREF(py_result);
|
||||
PYW_GIL_RELEASE;
|
||||
newref_t py_result(PyObject_CallFunctionObjArgs(ctx->pycallback, NULL));
|
||||
int ret = py_result == NULL ? -1 : PyLong_AsLong(py_result.o);
|
||||
|
||||
// Timer has been unregistered?
|
||||
if ( ret == -1 )
|
||||
{
|
||||
// Fee the context
|
||||
// Free the context
|
||||
Py_DECREF(ctx->pycallback);
|
||||
delete ctx;
|
||||
}
|
||||
@ -83,6 +83,8 @@ def unregister_timer(timer_obj):
|
||||
*/
|
||||
static PyObject *py_unregister_timer(PyObject *py_timerctx)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
if ( py_timerctx == NULL || !PyCObject_Check(py_timerctx) )
|
||||
Py_RETURN_FALSE;
|
||||
|
||||
@ -111,6 +113,7 @@ def choose_idasgn():
|
||||
static PyObject *py_choose_idasgn()
|
||||
{
|
||||
char *name = choose_idasgn();
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( name == NULL )
|
||||
{
|
||||
Py_RETURN_NONE;
|
||||
@ -140,6 +143,7 @@ static PyObject *py_get_highlighted_identifier(int flags = 0)
|
||||
{
|
||||
char buf[MAXSTR];
|
||||
bool ok = get_highlighted_identifier(buf, sizeof(buf), flags);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !ok )
|
||||
Py_RETURN_NONE;
|
||||
else
|
||||
@ -157,6 +161,7 @@ static int py_load_custom_icon_data(PyObject *data, const char *format)
|
||||
{
|
||||
Py_ssize_t len;
|
||||
char *s;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( PyString_AsStringAndSize(data, &s, &len) == -1 )
|
||||
return 0;
|
||||
else
|
||||
@ -191,6 +196,7 @@ def asktext(max_text, defval, prompt):
|
||||
*/
|
||||
PyObject *py_asktext(int max_text, const char *defval, const char *prompt)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( max_text <= 0 )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
@ -231,6 +237,26 @@ ea_t py_str2ea(const char *str, ea_t screenEA = BADADDR)
|
||||
return ok ? ea : BADADDR;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/*
|
||||
#<pydoc>
|
||||
def str2user(str):
|
||||
"""
|
||||
Insert C-style escape characters to string
|
||||
|
||||
@return: new string with escape characters inserted
|
||||
"""
|
||||
pass
|
||||
#</pydoc>
|
||||
*/
|
||||
PyObject *py_str2user(const char *str)
|
||||
{
|
||||
qstring qstr(str);
|
||||
qstring retstr;
|
||||
qstr2user(&retstr, qstr);
|
||||
return PyString_FromString(retstr.c_str());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/*
|
||||
#<pydoc>
|
||||
@ -265,6 +291,7 @@ def del_menu_item(menu_ctx):
|
||||
*/
|
||||
static bool py_del_menu_item(PyObject *py_ctx)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyCObject_Check(py_ctx) )
|
||||
return false;
|
||||
|
||||
@ -297,6 +324,7 @@ def del_hotkey(ctx):
|
||||
*/
|
||||
bool py_del_hotkey(PyObject *pyctx)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyCObject_Check(pyctx) )
|
||||
return false;
|
||||
|
||||
@ -327,6 +355,7 @@ def add_hotkey(hotkey, pyfunc):
|
||||
*/
|
||||
PyObject *py_add_hotkey(const char *hotkey, PyObject *pyfunc)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
// Make sure a callable was passed
|
||||
if ( !PyCallable_Check(pyfunc) )
|
||||
return NULL;
|
||||
@ -414,6 +443,7 @@ static PyObject *py_add_menu_item(
|
||||
PyObject *pyfunc,
|
||||
PyObject *args)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
bool no_args;
|
||||
|
||||
// No slash in the menu path?
|
||||
@ -512,55 +542,55 @@ def execute_sync(callable, reqf):
|
||||
//------------------------------------------------------------------------
|
||||
static int py_execute_sync(PyObject *py_callable, int reqf)
|
||||
{
|
||||
// Not callable?
|
||||
if ( !PyCallable_Check(py_callable) )
|
||||
return -1;
|
||||
|
||||
struct py_exec_request_t: exec_request_t
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
int rc = -1;
|
||||
// Callable?
|
||||
if ( PyCallable_Check(py_callable) )
|
||||
{
|
||||
PyObject *py_callable;
|
||||
bool no_wait;
|
||||
virtual int idaapi execute()
|
||||
struct py_exec_request_t : exec_request_t
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallFunctionObjArgs(py_callable, NULL);
|
||||
int r = py_result == NULL || !PyInt_Check(py_result) ? -1 : PyInt_AsLong(py_result);
|
||||
Py_XDECREF(py_result);
|
||||
PYW_GIL_RELEASE;
|
||||
ref_t py_callable;
|
||||
virtual int idaapi execute()
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
newref_t py_result(PyObject_CallFunctionObjArgs(py_callable.o, NULL));
|
||||
int ret = py_result == NULL || !PyInt_Check(py_result.o)
|
||||
? -1
|
||||
: PyInt_AsLong(py_result.o);
|
||||
// if the requesting thread decided not to wait for the request to
|
||||
// complete, we have to self-destroy, nobody else will do it
|
||||
if ( (code & MFF_NOWAIT) != 0 )
|
||||
delete this;
|
||||
return ret;
|
||||
}
|
||||
py_exec_request_t(PyObject *pyc)
|
||||
{
|
||||
// No need to GIL-ensure here, since this is created
|
||||
// within the py_execute_sync() scope.
|
||||
py_callable = borref_t(pyc);
|
||||
}
|
||||
virtual ~py_exec_request_t()
|
||||
{
|
||||
// Need to GIL-ensure here, since this might be called
|
||||
// from the main thread.
|
||||
PYW_GIL_GET;
|
||||
py_callable = ref_t(); // Release callable
|
||||
}
|
||||
};
|
||||
py_exec_request_t *req = new py_exec_request_t(py_callable);
|
||||
|
||||
// Free this request
|
||||
if ( no_wait )
|
||||
delete this;
|
||||
|
||||
return r;
|
||||
}
|
||||
py_exec_request_t(PyObject *pyc, bool no_wait):
|
||||
py_callable(pyc), no_wait(no_wait)
|
||||
{
|
||||
// Take reference to the callable
|
||||
Py_INCREF(py_callable);
|
||||
}
|
||||
virtual ~py_exec_request_t()
|
||||
{
|
||||
// Release callable
|
||||
Py_XDECREF(py_callable);
|
||||
}
|
||||
};
|
||||
|
||||
bool no_wait = (reqf & MFF_NOWAIT) != 0;
|
||||
|
||||
// Allocate a request
|
||||
py_exec_request_t *req = new py_exec_request_t(py_callable, no_wait);
|
||||
|
||||
// Execute it
|
||||
int r = execute_sync(*req, reqf);
|
||||
|
||||
// Delete only if NOWAIT was not specified
|
||||
// (Otherwise the request will delete itself)
|
||||
if ( !no_wait )
|
||||
delete req;
|
||||
|
||||
return r;
|
||||
// Release GIL before executing, or if this is running in the
|
||||
// non-main thread, this will wait on the req.sem, while the main
|
||||
// thread might be waiting for the GIL to be available.
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = execute_sync(*req, reqf);
|
||||
Py_END_ALLOW_THREADS;
|
||||
// destroy the request once it is finished. exception: NOWAIT requests
|
||||
// will be handled in the future, so do not destroy them yet!
|
||||
if ( (reqf & MFF_NOWAIT) == 0 )
|
||||
delete req;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
@ -585,23 +615,22 @@ static bool py_execute_ui_requests(PyObject *py_list)
|
||||
struct py_ui_request_t: public ui_request_t
|
||||
{
|
||||
private:
|
||||
ppyobject_vec_t py_callables;
|
||||
ref_vec_t py_callables;
|
||||
size_t py_callable_idx;
|
||||
|
||||
static int idaapi s_py_list_walk_cb(
|
||||
PyObject *py_item,
|
||||
Py_ssize_t index,
|
||||
void *ud)
|
||||
const ref_t &py_item,
|
||||
Py_ssize_t index,
|
||||
void *ud)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
// Not callable? Terminate iteration
|
||||
if ( !PyCallable_Check(py_item) )
|
||||
if ( !PyCallable_Check(py_item.o) )
|
||||
return CIP_FAILED;
|
||||
|
||||
// Append this callable and increment its reference
|
||||
py_ui_request_t *_this = (py_ui_request_t *)ud;
|
||||
_this->py_callables.push_back(py_item);
|
||||
Py_INCREF(py_item);
|
||||
|
||||
return CIP_OK;
|
||||
}
|
||||
public:
|
||||
@ -611,14 +640,13 @@ static bool py_execute_ui_requests(PyObject *py_list)
|
||||
|
||||
virtual bool idaapi run()
|
||||
{
|
||||
// Get callable
|
||||
PyObject *py_callable = py_callables.at(py_callable_idx);
|
||||
PYW_GIL_GET;
|
||||
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallFunctionObjArgs(py_callable, NULL);
|
||||
bool reschedule = py_result != NULL && PyObject_IsTrue(py_result);
|
||||
Py_XDECREF(py_result);
|
||||
PYW_GIL_RELEASE;
|
||||
// Get callable
|
||||
ref_t py_callable = py_callables.at(py_callable_idx);
|
||||
bool reschedule;
|
||||
newref_t py_result(PyObject_CallFunctionObjArgs(py_callable.o, NULL));
|
||||
reschedule = py_result != NULL && PyObject_IsTrue(py_result.o);
|
||||
|
||||
// No rescheduling? Then advance to the next callable
|
||||
if ( !reschedule )
|
||||
@ -640,13 +668,7 @@ static bool py_execute_ui_requests(PyObject *py_list)
|
||||
|
||||
virtual idaapi ~py_ui_request_t()
|
||||
{
|
||||
// Release all callables
|
||||
for ( ppyobject_vec_t::const_iterator it=py_callables.begin();
|
||||
it != py_callables.end();
|
||||
++it )
|
||||
{
|
||||
Py_XDECREF(*it);
|
||||
}
|
||||
py_callables.clear();
|
||||
}
|
||||
};
|
||||
|
||||
@ -809,6 +831,7 @@ public:
|
||||
|
||||
virtual PyObject *get_ea_hint(ea_t /*ea*/)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
Py_RETURN_NONE;
|
||||
};
|
||||
};
|
||||
@ -821,6 +844,8 @@ public:
|
||||
//---------------------------------------------------------------------------
|
||||
int idaapi UI_Callback(void *ud, int notification_code, va_list va)
|
||||
{
|
||||
// This hook gets called from the kernel. Ensure we hold the GIL.
|
||||
PYW_GIL_GET;
|
||||
UI_Hooks *proxy = (UI_Hooks *)ud;
|
||||
int ret = 0;
|
||||
try
|
||||
@ -857,6 +882,7 @@ int idaapi UI_Callback(void *ud, int notification_code, va_list va)
|
||||
char *_buf;
|
||||
Py_ssize_t _len;
|
||||
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyObject *py_str = proxy->get_ea_hint(ea);
|
||||
if ( py_str != NULL
|
||||
&& PyString_Check(py_str)
|
||||
@ -872,6 +898,7 @@ int idaapi UI_Callback(void *ud, int notification_code, va_list va)
|
||||
catch (Swig::DirectorException &e)
|
||||
{
|
||||
msg("Exception in UI Hook function: %s\n", e.getMessage());
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( PyErr_Occurred() )
|
||||
PyErr_Print();
|
||||
}
|
||||
@ -881,15 +908,15 @@ int idaapi UI_Callback(void *ud, int notification_code, va_list va)
|
||||
//------------------------------------------------------------------------
|
||||
bool idaapi py_menu_item_callback(void *userdata)
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
|
||||
// userdata is a tuple of ( func, args )
|
||||
// func and args are borrowed references from userdata
|
||||
PyObject *func = PyTuple_GET_ITEM(userdata, 0);
|
||||
PyObject *args = PyTuple_GET_ITEM(userdata, 1);
|
||||
|
||||
// Call the python function
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *result = PyEval_CallObject(func, args);
|
||||
PYW_GIL_RELEASE;
|
||||
newref_t result(PyEval_CallObject(func, args));
|
||||
|
||||
// We cannot raise an exception in the callback, just print it.
|
||||
if ( result == NULL )
|
||||
@ -898,10 +925,8 @@ bool idaapi py_menu_item_callback(void *userdata)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ret = PyObject_IsTrue(result) != 0;
|
||||
Py_DECREF(result);
|
||||
return ret;
|
||||
return PyObject_IsTrue(result.o) != 0;
|
||||
}
|
||||
//</code(py_kernwin)>
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -12,10 +12,12 @@ static void idaapi s_py_get_user_defined_prefix(
|
||||
char *buf,
|
||||
size_t bufsize)
|
||||
{
|
||||
PyObject *py_ret = PyObject_CallFunction(
|
||||
py_get_user_defined_prefix,
|
||||
PY_FMT64 "iis" PY_FMT64,
|
||||
ea, lnnum, indent, line, bufsize);
|
||||
PYW_GIL_GET;
|
||||
newref_t py_ret(
|
||||
PyObject_CallFunction(
|
||||
py_get_user_defined_prefix,
|
||||
PY_FMT64 "iis" PY_FMT64,
|
||||
ea, lnnum, indent, line, bufsize));
|
||||
|
||||
// Error? Display it
|
||||
// No error? Copy the buffer
|
||||
@ -23,14 +25,13 @@ static void idaapi s_py_get_user_defined_prefix(
|
||||
{
|
||||
Py_ssize_t py_len;
|
||||
char *py_str;
|
||||
if ( PyString_AsStringAndSize(py_ret, &py_str, &py_len) != -1 )
|
||||
if ( PyString_AsStringAndSize(py_ret.o, &py_str, &py_len) != -1 )
|
||||
{
|
||||
memcpy(buf, py_str, qmin(bufsize, py_len));
|
||||
if ( py_len < bufsize )
|
||||
buf[py_len] = '\0';
|
||||
}
|
||||
}
|
||||
Py_XDECREF(py_ret);
|
||||
}
|
||||
//</code(py_lines)>
|
||||
|
||||
@ -65,6 +66,7 @@ def set_user_defined_prefix(width, callback):
|
||||
*/
|
||||
static PyObject *py_set_user_defined_prefix(size_t width, PyObject *pycb)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( width == 0 || pycb == Py_None )
|
||||
{
|
||||
// Release old callback reference
|
||||
@ -110,6 +112,7 @@ def tag_remove(colstr):
|
||||
*/
|
||||
PyObject *py_tag_remove(const char *instr)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
size_t sz = strlen(instr);
|
||||
char *buf = new char[sz + 5];
|
||||
if ( buf == NULL )
|
||||
@ -135,6 +138,7 @@ PyObject *py_tag_addr(ea_t ea)
|
||||
{
|
||||
char buf[100];
|
||||
tag_addr(buf, buf + sizeof(buf), ea);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return PyString_FromString(buf);
|
||||
}
|
||||
|
||||
@ -180,6 +184,7 @@ PyObject *py_generate_disassembly(
|
||||
bool as_stack,
|
||||
bool notags)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( max_lines <= 0 )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
@ -188,7 +193,7 @@ PyObject *py_generate_disassembly(
|
||||
int lnnum;
|
||||
int nlines = generate_disassembly(ea, lines, max_lines, &lnnum, as_stack);
|
||||
|
||||
PyObject *py_tuple = PyTuple_New(nlines);
|
||||
newref_t py_tuple(PyTuple_New(nlines));
|
||||
for ( int i=0; i<nlines; i++ )
|
||||
{
|
||||
const char *s = lines[i];
|
||||
@ -199,13 +204,11 @@ PyObject *py_generate_disassembly(
|
||||
tag_remove(s, &qbuf[0], line_len);
|
||||
s = (const char *)&qbuf[0];
|
||||
}
|
||||
PyTuple_SetItem(py_tuple, i, PyString_FromString(s));
|
||||
PyTuple_SetItem(py_tuple.o, i, PyString_FromString(s));
|
||||
qfree(lines[i]);
|
||||
}
|
||||
delete [] lines;
|
||||
PyObject *py_result = Py_BuildValue("(iO)", lnnum, py_tuple);
|
||||
Py_DECREF(py_tuple);
|
||||
return py_result;
|
||||
return Py_BuildValue("(iO)", lnnum, py_tuple.o);
|
||||
}
|
||||
//</inline(py_lines)>
|
||||
#endif
|
||||
|
@ -110,6 +110,7 @@ private:
|
||||
//--------------------------------------------------------------------------
|
||||
void _from_cobject(PyObject *pycobject)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
this->set_linput((linput_t *)PyCObject_AsVoidPtr(pycobject));
|
||||
}
|
||||
|
||||
@ -133,6 +134,7 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
loader_input_t(PyObject *pycobject = NULL): li(NULL), own(OWN_NONE), __idc_cvt_id__(PY_ICID_OPAQUE)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( pycobject != NULL && PyCObject_Check(pycobject) )
|
||||
_from_cobject(pycobject);
|
||||
}
|
||||
@ -143,11 +145,13 @@ public:
|
||||
if ( li == NULL )
|
||||
return;
|
||||
|
||||
PYW_GIL_GET;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
if ( own == OWN_CREATE )
|
||||
close_linput(li);
|
||||
else if ( own == OWN_FROM_FP )
|
||||
unmake_linput(li);
|
||||
|
||||
Py_END_ALLOW_THREADS;
|
||||
li = NULL;
|
||||
own = OWN_NONE;
|
||||
}
|
||||
@ -162,14 +166,17 @@ public:
|
||||
bool open(const char *filename, bool remote = false)
|
||||
{
|
||||
close();
|
||||
PYW_GIL_GET;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
li = open_linput(filename, remote);
|
||||
if ( li == NULL )
|
||||
return false;
|
||||
|
||||
// Save file name
|
||||
fn = filename;
|
||||
own = OWN_CREATE;
|
||||
return true;
|
||||
if ( li != NULL )
|
||||
{
|
||||
// Save file name
|
||||
fn = filename;
|
||||
own = OWN_CREATE;
|
||||
}
|
||||
Py_END_ALLOW_THREADS;
|
||||
return li != NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@ -193,6 +200,7 @@ public:
|
||||
// This method can be used to pass a linput_t* from C code
|
||||
static loader_input_t *from_cobject(PyObject *pycobject)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyCObject_Check(pycobject) )
|
||||
return NULL;
|
||||
loader_input_t *l = new loader_input_t();
|
||||
@ -203,14 +211,18 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
static loader_input_t *from_fp(FILE *fp)
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
loader_input_t *l = NULL;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
linput_t *fp_li = make_linput(fp);
|
||||
if ( fp_li == NULL )
|
||||
return NULL;
|
||||
|
||||
loader_input_t *l = new loader_input_t();
|
||||
l->own = OWN_FROM_FP;
|
||||
l->fn.sprnt("<FILE * %p>", fp);
|
||||
l->li = fp_li;
|
||||
if ( fp_li != NULL )
|
||||
{
|
||||
l = new loader_input_t();
|
||||
l->own = OWN_FROM_FP;
|
||||
l->fn.sprnt("<FILE * %p>", fp);
|
||||
l->li = fp_li;
|
||||
}
|
||||
Py_END_ALLOW_THREADS;
|
||||
return l;
|
||||
}
|
||||
|
||||
@ -223,37 +235,55 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
bool open_memory(ea_t start, asize_t size = 0)
|
||||
{
|
||||
linput_t *l = create_memory_linput(start, size);
|
||||
if ( l == NULL )
|
||||
return false;
|
||||
close();
|
||||
li = l;
|
||||
fn = "<memory>";
|
||||
own = OWN_CREATE;
|
||||
return true;
|
||||
PYW_GIL_GET;
|
||||
linput_t *l;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
l = create_memory_linput(start, size);
|
||||
if ( l != NULL )
|
||||
{
|
||||
close();
|
||||
li = l;
|
||||
fn = "<memory>";
|
||||
own = OWN_CREATE;
|
||||
}
|
||||
Py_END_ALLOW_THREADS;
|
||||
return l != NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
int32 seek(int32 pos, int whence = SEEK_SET)
|
||||
{
|
||||
return qlseek(li, pos, whence);
|
||||
int32 r;
|
||||
PYW_GIL_GET;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = qlseek(li, pos, whence);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return r;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
int32 tell()
|
||||
{
|
||||
return qltell(li);
|
||||
int32 r;
|
||||
PYW_GIL_GET;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = qltell(li);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return r;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
PyObject *getz(size_t sz, int32 fpos = -1)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
do
|
||||
{
|
||||
char *buf = (char *) malloc(sz + 5);
|
||||
if ( buf == NULL )
|
||||
break;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
qlgetz(li, fpos, buf, sz);
|
||||
Py_END_ALLOW_THREADS;
|
||||
PyObject *ret = PyString_FromString(buf);
|
||||
free(buf);
|
||||
return ret;
|
||||
@ -264,12 +294,17 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
PyObject *gets(size_t len)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
do
|
||||
{
|
||||
char *buf = (char *) malloc(len + 5);
|
||||
if ( buf == NULL )
|
||||
break;
|
||||
if ( qlgets(buf, len, li) == NULL )
|
||||
bool ok;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
ok = qlgets(buf, len, li) != NULL;
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( !ok )
|
||||
{
|
||||
free(buf);
|
||||
break;
|
||||
@ -284,12 +319,16 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
PyObject *read(size_t size)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
do
|
||||
{
|
||||
char *buf = (char *) malloc(size + 5);
|
||||
if ( buf == NULL )
|
||||
break;
|
||||
ssize_t r = qlread(li, buf, size);
|
||||
ssize_t r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = qlread(li, buf, size);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( r == -1 )
|
||||
{
|
||||
free(buf);
|
||||
@ -311,12 +350,16 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
PyObject *readbytes(size_t size, bool big_endian)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
do
|
||||
{
|
||||
char *buf = (char *) malloc(size + 5);
|
||||
if ( buf == NULL )
|
||||
break;
|
||||
int r = lreadbytes(li, buf, size, big_endian);
|
||||
int r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = lreadbytes(li, buf, size, big_endian);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( r == -1 )
|
||||
{
|
||||
free(buf);
|
||||
@ -332,25 +375,38 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
int file2base(int32 pos, ea_t ea1, ea_t ea2, int patchable)
|
||||
{
|
||||
return ::file2base(li, pos, ea1, ea2, patchable);
|
||||
int rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = ::file2base(li, pos, ea1, ea2, patchable);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
int32 size()
|
||||
{
|
||||
return qlsize(li);
|
||||
int32 rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = qlsize(li);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
PyObject *filename()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return PyString_FromString(fn.c_str());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
PyObject *get_char()
|
||||
{
|
||||
int ch = qlgetc(li);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
int ch;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
ch = qlgetc(li);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( ch == EOF )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("c", ch);
|
||||
|
@ -25,8 +25,11 @@ static int py_mem2base(PyObject *py_mem, ea_t ea, long fpos = -1)
|
||||
{
|
||||
Py_ssize_t len;
|
||||
char *buf;
|
||||
if ( PyString_AsStringAndSize(py_mem, &buf, &len) == -1 )
|
||||
return 0;
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( PyString_AsStringAndSize(py_mem, &buf, &len) == -1 )
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mem2base((void *)buf, ea, ea+len, fpos);
|
||||
}
|
||||
@ -47,6 +50,7 @@ def load_plugin(name):
|
||||
static PyObject *py_load_plugin(const char *name)
|
||||
{
|
||||
plugin_t *r = load_plugin(name);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( r == NULL )
|
||||
Py_RETURN_NONE;
|
||||
else
|
||||
@ -67,10 +71,20 @@ def run_plugin(plg):
|
||||
*/
|
||||
static bool py_run_plugin(PyObject *plg, int arg)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyCObject_Check(plg) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return run_plugin((plugin_t *)PyCObject_AsVoidPtr(plg), arg);
|
||||
{
|
||||
plugin_t *p = (plugin_t *)PyCObject_AsVoidPtr(plg);
|
||||
bool rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = run_plugin(p, arg);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
//</inline(py_loader)>
|
||||
|
@ -21,53 +21,35 @@ static int idaapi py_import_enum_cb(
|
||||
if ( name == NULL )
|
||||
name = get_true_name(BADADDR, ea, name_buf, sizeof(name_buf));
|
||||
|
||||
PyObject *py_name;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
ref_t py_name;
|
||||
if ( name == NULL )
|
||||
{
|
||||
py_name = Py_None;
|
||||
Py_INCREF(Py_None);
|
||||
}
|
||||
py_name = borref_t(Py_None);
|
||||
else
|
||||
{
|
||||
py_name = PyString_FromString(name);
|
||||
}
|
||||
py_name = newref_t(PyString_FromString(name));
|
||||
|
||||
PyObject *py_ord = Py_BuildValue(PY_FMT64, pyul_t(ord));
|
||||
PyObject *py_ea = Py_BuildValue(PY_FMT64, pyul_t(ea));
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallFunctionObjArgs(
|
||||
(PyObject *)param,
|
||||
py_ea,
|
||||
py_name,
|
||||
py_ord,
|
||||
NULL);
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
int r = py_result != NULL && PyObject_IsTrue(py_result) ? 1 : 0;
|
||||
|
||||
Py_DECREF(py_ea);
|
||||
Py_DECREF(py_name);
|
||||
Py_DECREF(py_ord);
|
||||
Py_XDECREF(py_result);
|
||||
|
||||
return r;
|
||||
newref_t py_ord(Py_BuildValue(PY_FMT64, pyul_t(ord)));
|
||||
newref_t py_ea(Py_BuildValue(PY_FMT64, pyul_t(ea)));
|
||||
newref_t py_result(
|
||||
PyObject_CallFunctionObjArgs(
|
||||
(PyObject *)param,
|
||||
py_ea.o,
|
||||
py_name.o,
|
||||
py_ord.o,
|
||||
NULL));
|
||||
return py_result != NULL && PyObject_IsTrue(py_result.o) ? 1 : 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
switch_info_ex_t *switch_info_ex_t_get_clink(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyObject_HasAttrString(self, S_CLINK_NAME) )
|
||||
return NULL;
|
||||
|
||||
switch_info_ex_t *r;
|
||||
PyObject *attr = PyObject_GetAttrString(self, S_CLINK_NAME);
|
||||
if ( PyCObject_Check(attr) )
|
||||
r = (switch_info_ex_t *) PyCObject_AsVoidPtr(attr);
|
||||
else
|
||||
r = NULL;
|
||||
|
||||
Py_DECREF(attr);
|
||||
return r;
|
||||
newref_t attr(PyObject_GetAttrString(self, S_CLINK_NAME));
|
||||
return PyCObject_Check(attr.o) ? ((switch_info_ex_t *) PyCObject_AsVoidPtr(attr.o)) : NULL;
|
||||
}
|
||||
//</code(py_nalt)>
|
||||
|
||||
@ -86,10 +68,11 @@ def get_import_module_name(path, fname, callback):
|
||||
*/
|
||||
static PyObject *py_get_import_module_name(int mod_index)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
char buf[MAXSTR];
|
||||
if ( !get_import_module_name(mod_index, buf, sizeof(buf)) )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
|
||||
return PyString_FromString(buf);
|
||||
}
|
||||
|
||||
@ -108,14 +91,16 @@ def get_switch_info_ex(ea):
|
||||
PyObject *py_get_switch_info_ex(ea_t ea)
|
||||
{
|
||||
switch_info_ex_t *ex = new switch_info_ex_t();
|
||||
PyObject *py_obj;
|
||||
if ( ::get_switch_info_ex(ea, ex, sizeof(switch_info_ex_t)) <= 0
|
||||
ref_t py_obj;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( ::get_switch_info_ex(ea, ex, sizeof(switch_info_ex_t)) <= 0
|
||||
|| (py_obj = create_idaapi_linked_class_instance(S_PY_SWIEX_CLSNAME, ex)) == NULL )
|
||||
{
|
||||
delete ex;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
return py_obj;
|
||||
py_obj.incref();
|
||||
return py_obj.o;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -129,7 +114,7 @@ def create_switch_xrefs(insn_ea, si):
|
||||
will call it for switch tables
|
||||
|
||||
Note: Custom switch information are not supported yet.
|
||||
|
||||
|
||||
@param insn_ea: address of the 'indirect jump' instruction
|
||||
@param si: switch information
|
||||
|
||||
@ -157,7 +142,7 @@ idaman bool ida_export py_create_switch_xrefs(
|
||||
def create_switch_table(insn_ea, si):
|
||||
"""
|
||||
Create switch table from the switch information
|
||||
|
||||
|
||||
@param insn_ea: address of the 'indirect jump' instruction
|
||||
@param si: switch information
|
||||
|
||||
@ -173,7 +158,7 @@ idaman bool ida_export py_create_switch_table(
|
||||
switch_info_ex_t *swi = switch_info_ex_t_get_clink(py_swi);
|
||||
if ( swi == NULL )
|
||||
return false;
|
||||
|
||||
|
||||
create_switch_table(insn_ea, swi);
|
||||
return true;
|
||||
}
|
||||
@ -232,9 +217,9 @@ def enum_import_names(mod_index, callback):
|
||||
*/
|
||||
static int py_enum_import_names(int mod_index, PyObject *py_cb)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyCallable_Check(py_cb) )
|
||||
return -1;
|
||||
|
||||
return enum_import_names(mod_index, py_import_enum_cb, py_cb);
|
||||
}
|
||||
|
||||
@ -242,12 +227,14 @@ static int py_enum_import_names(int mod_index, PyObject *py_cb)
|
||||
static PyObject *switch_info_ex_t_create()
|
||||
{
|
||||
switch_info_ex_t *inst = new switch_info_ex_t();
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return PyCObject_FromVoidPtr(inst, NULL);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
static bool switch_info_ex_t_destroy(PyObject *py_obj)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyCObject_Check(py_obj) )
|
||||
return false;
|
||||
switch_info_ex_t *inst = (switch_info_ex_t *) PyCObject_AsVoidPtr(py_obj);
|
||||
@ -273,6 +260,7 @@ static bool switch_info_ex_t_assign(PyObject *self, PyObject *other)
|
||||
static PyObject *switch_info_ex_t_get_regdtyp(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("b", (char)link->regdtyp);
|
||||
@ -282,12 +270,14 @@ static void switch_info_ex_t_set_regdtyp(PyObject *self, PyObject *value)
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
link->regdtyp = (char)PyInt_AsLong(value);
|
||||
}
|
||||
|
||||
static PyObject *switch_info_ex_t_get_flags2(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("i", link->flags2);
|
||||
@ -297,12 +287,14 @@ static void switch_info_ex_t_set_flags2(PyObject *self, PyObject *value)
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
link->flags2 = (int)PyInt_AsLong(value);
|
||||
}
|
||||
|
||||
static PyObject *switch_info_ex_t_get_jcases(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("i", link->jcases);
|
||||
@ -312,12 +304,14 @@ static void switch_info_ex_t_set_jcases(PyObject *self, PyObject *value)
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
link->jcases = (int)PyInt_AsLong(value);
|
||||
}
|
||||
|
||||
static PyObject *switch_info_ex_t_get_regnum(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("i", (int)link->regnum);
|
||||
@ -327,12 +321,14 @@ static void switch_info_ex_t_set_regnum(PyObject *self, PyObject *value)
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
link->regnum = (int)PyInt_AsLong(value);
|
||||
}
|
||||
|
||||
static PyObject *switch_info_ex_t_get_flags(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("H", (ushort)link->flags);
|
||||
@ -342,12 +338,14 @@ static void switch_info_ex_t_set_flags(PyObject *self, PyObject *value)
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
link->flags = (uint16)PyInt_AsLong(value);
|
||||
}
|
||||
|
||||
static PyObject *switch_info_ex_t_get_ncases(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("H", (uint16)link->ncases);
|
||||
@ -357,12 +355,14 @@ static void switch_info_ex_t_set_ncases(PyObject *self, PyObject *value)
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
link->ncases = (ushort)PyInt_AsLong(value);
|
||||
}
|
||||
|
||||
static PyObject *switch_info_ex_t_get_defjump(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue(PY_FMT64, (pyul_t)link->defjump);
|
||||
@ -372,6 +372,7 @@ static void switch_info_ex_t_set_defjump(PyObject *self, PyObject *value)
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
uint64 v(0); PyW_GetNumber(value, &v);
|
||||
link->defjump = (pyul_t)v;
|
||||
}
|
||||
@ -388,6 +389,7 @@ static void switch_info_ex_t_set_jumps(PyObject *self, PyObject *value)
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
uint64 v(0); PyW_GetNumber(value, &v);
|
||||
link->jumps = (pyul_t)v;
|
||||
}
|
||||
@ -395,6 +397,7 @@ static void switch_info_ex_t_set_jumps(PyObject *self, PyObject *value)
|
||||
static PyObject *switch_info_ex_t_get_elbase(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue(PY_FMT64, (pyul_t)link->elbase);
|
||||
@ -405,6 +408,7 @@ static void switch_info_ex_t_set_elbase(PyObject *self, PyObject *value)
|
||||
if ( link == NULL )
|
||||
return;
|
||||
uint64 v(0);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyW_GetNumber(value, &v);
|
||||
link->elbase = (pyul_t)v;
|
||||
}
|
||||
@ -412,6 +416,7 @@ static void switch_info_ex_t_set_elbase(PyObject *self, PyObject *value)
|
||||
static PyObject *switch_info_ex_t_get_startea(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue(PY_FMT64, (pyul_t)link->startea);
|
||||
@ -422,6 +427,7 @@ static void switch_info_ex_t_set_startea(PyObject *self, PyObject *value)
|
||||
if ( link == NULL )
|
||||
return;
|
||||
uint64 v(0);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyW_GetNumber(value, &v);
|
||||
link->startea = (pyul_t)v;
|
||||
}
|
||||
@ -429,6 +435,7 @@ static void switch_info_ex_t_set_startea(PyObject *self, PyObject *value)
|
||||
static PyObject *switch_info_ex_t_get_custom(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue(PY_FMT64, (pyul_t)link->custom);
|
||||
@ -439,6 +446,7 @@ static void switch_info_ex_t_set_custom(PyObject *self, PyObject *value)
|
||||
if ( link == NULL )
|
||||
return;
|
||||
uint64 v(0);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyW_GetNumber(value, &v);
|
||||
link->custom = (pyul_t)v;
|
||||
}
|
||||
@ -446,6 +454,7 @@ static void switch_info_ex_t_set_custom(PyObject *self, PyObject *value)
|
||||
static PyObject *switch_info_ex_t_get_ind_lowcase(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue(PY_FMT64, (pyul_t)link->ind_lowcase);
|
||||
@ -456,6 +465,7 @@ static void switch_info_ex_t_set_ind_lowcase(PyObject *self, PyObject *value)
|
||||
if ( link == NULL )
|
||||
return;
|
||||
uint64 v(0);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyW_GetNumber(value, &v);
|
||||
link->ind_lowcase = (pyul_t)v;
|
||||
}
|
||||
@ -463,6 +473,7 @@ static void switch_info_ex_t_set_ind_lowcase(PyObject *self, PyObject *value)
|
||||
static PyObject *switch_info_ex_t_get_values_lowcase(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue(PY_FMT64, (pyul_t)link->values);
|
||||
@ -473,6 +484,7 @@ static void switch_info_ex_t_set_values_lowcase(PyObject *self, PyObject *value)
|
||||
if ( link == NULL )
|
||||
return;
|
||||
uint64 v(0);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyW_GetNumber(value, &v);
|
||||
link->values = (pyul_t)v;
|
||||
}
|
||||
|
@ -5,16 +5,19 @@ PyObject *py_get_debug_names(ea_t ea1, ea_t ea2)
|
||||
{
|
||||
// Get debug names
|
||||
ea_name_vec_t names;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
get_debug_names(ea1, ea2, names);
|
||||
Py_END_ALLOW_THREADS;
|
||||
PyObject *dict = Py_BuildValue("{}");
|
||||
if (dict == NULL)
|
||||
return NULL;
|
||||
|
||||
for (ea_name_vec_t::iterator it=names.begin();it!=names.end();++it)
|
||||
if (dict != NULL)
|
||||
{
|
||||
PyDict_SetItem(dict,
|
||||
Py_BuildValue(PY_FMT64, it->ea),
|
||||
PyString_FromString(it->name.c_str()));
|
||||
for (ea_name_vec_t::iterator it=names.begin();it!=names.end();++it)
|
||||
{
|
||||
PyDict_SetItem(dict,
|
||||
Py_BuildValue(PY_FMT64, it->ea),
|
||||
PyString_FromString(it->name.c_str()));
|
||||
}
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
//------------------------------------------------------------------------
|
||||
class pywraps_notify_when_t
|
||||
{
|
||||
ppyobject_vec_t table[NW_EVENTSCNT];
|
||||
ref_vec_t table[NW_EVENTSCNT];
|
||||
qstring err;
|
||||
bool in_notify;
|
||||
struct notify_when_args_t
|
||||
@ -22,6 +22,8 @@ class pywraps_notify_when_t
|
||||
//------------------------------------------------------------------------
|
||||
static int idaapi idp_callback(void *ud, int event_id, va_list va)
|
||||
{
|
||||
// This hook gets called from the kernel. Ensure we hold the GIL.
|
||||
PYW_GIL_GET;
|
||||
pywraps_notify_when_t *_this = (pywraps_notify_when_t *)ud;
|
||||
switch ( event_id )
|
||||
{
|
||||
@ -60,32 +62,29 @@ class pywraps_notify_when_t
|
||||
//------------------------------------------------------------------------
|
||||
void register_callback(int slot, PyObject *py_callable)
|
||||
{
|
||||
ppyobject_vec_t &tbl = table[slot];
|
||||
ppyobject_vec_t::iterator it_end = tbl.end(), it = std::find(tbl.begin(), it_end, py_callable);
|
||||
borref_t callable_ref(py_callable);
|
||||
ref_vec_t &tbl = table[slot];
|
||||
ref_vec_t::iterator it_end = tbl.end(), it = std::find(tbl.begin(), it_end, callable_ref);
|
||||
|
||||
// Already added
|
||||
if ( it != it_end )
|
||||
return;
|
||||
|
||||
// Increment reference
|
||||
Py_INCREF(py_callable);
|
||||
|
||||
// Insert the element
|
||||
tbl.push_back(py_callable);
|
||||
tbl.push_back(callable_ref);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
void unregister_callback(int slot, PyObject *py_callable)
|
||||
{
|
||||
ppyobject_vec_t &tbl = table[slot];
|
||||
ppyobject_vec_t::iterator it_end = tbl.end(), it = std::find(tbl.begin(), it_end, py_callable);
|
||||
borref_t callable_ref(py_callable);
|
||||
ref_vec_t &tbl = table[slot];
|
||||
ref_vec_t::iterator it_end = tbl.end(), it = std::find(tbl.begin(), it_end, callable_ref);
|
||||
|
||||
// Not found?
|
||||
if ( it == it_end )
|
||||
return;
|
||||
|
||||
// Decrement reference
|
||||
Py_DECREF(py_callable);
|
||||
|
||||
// Delete the element
|
||||
tbl.erase(it);
|
||||
}
|
||||
@ -101,11 +100,11 @@ public:
|
||||
bool deinit()
|
||||
{
|
||||
// Uninstall all objects
|
||||
ppyobject_vec_t::iterator it, it_end;
|
||||
ref_vec_t::iterator it, it_end;
|
||||
for ( int slot=0; slot<NW_EVENTSCNT; slot++ )
|
||||
{
|
||||
for ( it = table[slot].begin(), it_end = table[slot].end(); it!=it_end; ++it )
|
||||
unregister_callback(slot, *it);
|
||||
unregister_callback(slot, it->o);
|
||||
}
|
||||
// ...and remove the notification
|
||||
return unhook_from_notification_point(HT_IDP, idp_callback, this);
|
||||
@ -154,6 +153,8 @@ public:
|
||||
//------------------------------------------------------------------------
|
||||
bool notify_va(int slot, va_list va)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
// Sanity bounds check!
|
||||
if ( slot < 0 || slot >= NW_EVENTSCNT )
|
||||
return false;
|
||||
@ -161,42 +162,38 @@ public:
|
||||
bool ok = true;
|
||||
in_notify = true;
|
||||
int old = slot == NW_OPENIDB_SLOT ? va_arg(va, int) : 0;
|
||||
for (ppyobject_vec_t::iterator it = table[slot].begin(), it_end = table[slot].end();
|
||||
it != it_end;
|
||||
++it)
|
||||
|
||||
{
|
||||
// Form the notification code
|
||||
PyObject *py_code = PyInt_FromLong(1 << slot);
|
||||
PyObject *py_result(NULL);
|
||||
switch ( slot )
|
||||
for (ref_vec_t::iterator it = table[slot].begin(), it_end = table[slot].end();
|
||||
it != it_end;
|
||||
++it)
|
||||
{
|
||||
case NW_CLOSEIDB_SLOT:
|
||||
case NW_INITIDA_SLOT:
|
||||
case NW_TERMIDA_SLOT:
|
||||
// Form the notification code
|
||||
newref_t py_code(PyInt_FromLong(1 << slot));
|
||||
ref_t py_result;
|
||||
switch ( slot )
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
py_result = PyObject_CallFunctionObjArgs(*it, py_code, NULL);
|
||||
PYW_GIL_RELEASE;
|
||||
break;
|
||||
case NW_CLOSEIDB_SLOT:
|
||||
case NW_INITIDA_SLOT:
|
||||
case NW_TERMIDA_SLOT:
|
||||
{
|
||||
py_result = newref_t(PyObject_CallFunctionObjArgs(it->o, py_code.o, NULL));
|
||||
break;
|
||||
}
|
||||
case NW_OPENIDB_SLOT:
|
||||
{
|
||||
newref_t py_old(PyInt_FromLong(old));
|
||||
py_result = newref_t(PyObject_CallFunctionObjArgs(it->o, py_code.o, py_old.o, NULL));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NW_OPENIDB_SLOT:
|
||||
if ( PyW_GetError(&err) || py_result == NULL )
|
||||
{
|
||||
PyObject *py_old = PyInt_FromLong(old);
|
||||
PYW_GIL_ENSURE;
|
||||
py_result = PyObject_CallFunctionObjArgs(*it, py_code, py_old, NULL);
|
||||
PYW_GIL_RELEASE;
|
||||
Py_DECREF(py_old);
|
||||
PyErr_Clear();
|
||||
warning("notify_when(): Error occured while notifying object.\n%s", err.c_str());
|
||||
ok = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
Py_DECREF(py_code);
|
||||
if ( PyW_GetError(&err) || py_result == NULL )
|
||||
{
|
||||
PyErr_Clear();
|
||||
warning("notify_when(): Error occured while notifying object.\n%s", err.c_str());
|
||||
ok = false;
|
||||
}
|
||||
Py_XDECREF(py_result);
|
||||
}
|
||||
in_notify = false;
|
||||
|
||||
@ -211,6 +208,7 @@ public:
|
||||
}
|
||||
delayed_notify_when_list.qclear();
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -247,6 +245,10 @@ bool pywraps_nw_notify(int slot, ...)
|
||||
if ( g_nw == NULL )
|
||||
return false;
|
||||
|
||||
// Appears to be called from 'driver_notifywhen.cpp', which
|
||||
// itself is called from possibly non-python code.
|
||||
// I.e., we must acquire the GIL.
|
||||
PYW_GIL_GET;
|
||||
va_list va;
|
||||
va_start(va, slot);
|
||||
bool ok = g_nw->notify_va(slot, va);
|
||||
@ -261,11 +263,11 @@ bool pywraps_nw_term()
|
||||
{
|
||||
if ( g_nw == NULL )
|
||||
return true;
|
||||
|
||||
|
||||
// If could not deinitialize then return w/o stopping nw
|
||||
if ( !g_nw->deinit() )
|
||||
return false;
|
||||
|
||||
|
||||
// Cleanup
|
||||
delete g_nw;
|
||||
g_nw = NULL;
|
||||
@ -296,6 +298,7 @@ def notify_when(when, callback):
|
||||
*/
|
||||
static bool notify_when(int when, PyObject *py_callable)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( g_nw == NULL || !PyCallable_Check(py_callable) )
|
||||
return false;
|
||||
return g_nw->notify_when(when, py_callable);
|
||||
|
@ -6,11 +6,14 @@
|
||||
class plgform_t
|
||||
{
|
||||
private:
|
||||
PyObject *py_obj;
|
||||
ref_t py_obj;
|
||||
TForm *form;
|
||||
|
||||
static int idaapi s_callback(void *ud, int notification_code, va_list va)
|
||||
{
|
||||
// This hook gets called from the kernel. Ensure we hold the GIL.
|
||||
PYW_GIL_GET;
|
||||
|
||||
plgform_t *_this = (plgform_t *)ud;
|
||||
if ( notification_code == ui_tform_visible )
|
||||
{
|
||||
@ -21,15 +24,12 @@ private:
|
||||
// G: HWND
|
||||
// We wrap and pass as a CObject in the hope that a Python UI framework
|
||||
// can unwrap a CObject and get the hwnd/widget back
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(
|
||||
_this->py_obj,
|
||||
(char *)S_ON_CREATE, "O",
|
||||
PyCObject_FromVoidPtr(form, NULL));
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
newref_t py_result(
|
||||
PyObject_CallMethod(
|
||||
_this->py_obj.o,
|
||||
(char *)S_ON_CREATE, "O",
|
||||
PyCObject_FromVoidPtr(form, NULL)));
|
||||
PyW_ShowCbErr(S_ON_CREATE);
|
||||
Py_XDECREF(py_result);
|
||||
}
|
||||
}
|
||||
else if ( notification_code == ui_tform_invisible )
|
||||
@ -37,16 +37,14 @@ private:
|
||||
TForm *form = va_arg(va, TForm *);
|
||||
if ( form == _this->form )
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(
|
||||
_this->py_obj,
|
||||
(char *)S_ON_CLOSE, "O",
|
||||
PyCObject_FromVoidPtr(form, NULL));
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
PyW_ShowCbErr(S_ON_CLOSE);
|
||||
Py_XDECREF(py_result);
|
||||
|
||||
{
|
||||
newref_t py_result(
|
||||
PyObject_CallMethod(
|
||||
_this->py_obj.o,
|
||||
(char *)S_ON_CLOSE, "O",
|
||||
PyCObject_FromVoidPtr(form, NULL)));
|
||||
PyW_ShowCbErr(S_ON_CLOSE);
|
||||
}
|
||||
_this->unhook();
|
||||
}
|
||||
}
|
||||
@ -59,11 +57,12 @@ private:
|
||||
form = NULL;
|
||||
|
||||
// Call DECREF at last, since it may trigger __del__
|
||||
Py_XDECREF(py_obj);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
py_obj = ref_t();
|
||||
}
|
||||
|
||||
public:
|
||||
plgform_t(): py_obj(NULL), form(NULL)
|
||||
plgform_t(): form(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@ -98,8 +97,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
py_obj = obj;
|
||||
Py_INCREF(obj);
|
||||
py_obj = borref_t(obj);
|
||||
|
||||
if ( is_idaq() )
|
||||
options |= FORM_QWIDGET;
|
||||
@ -117,6 +115,7 @@ public:
|
||||
|
||||
static PyObject *create()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return PyCObject_FromVoidPtr(new plgform_t(), destroy);
|
||||
}
|
||||
|
||||
@ -129,7 +128,7 @@ public:
|
||||
|
||||
//<inline(py_plgform)>
|
||||
//---------------------------------------------------------------------------
|
||||
#define DECL_PLGFORM plgform_t *plgform = (plgform_t *) PyCObject_AsVoidPtr(py_link);
|
||||
#define DECL_PLGFORM PYW_GIL_CHECK_LOCKED_SCOPE(); plgform_t *plgform = (plgform_t *) PyCObject_AsVoidPtr(py_link);
|
||||
static PyObject *plgform_new()
|
||||
{
|
||||
return plgform_t::create();
|
||||
@ -155,4 +154,4 @@ static void plgform_close(
|
||||
#undef DECL_PLGFORM
|
||||
//</inline(py_plgform)>
|
||||
|
||||
#endif // __PY_PLGFORM__
|
||||
#endif // __PY_PLGFORM__
|
||||
|
@ -59,6 +59,19 @@ class PluginForm(object):
|
||||
|
||||
@param ctx: Context. Reference to a module that already imported QtGui module
|
||||
"""
|
||||
if form is None:
|
||||
return None
|
||||
if type(form).__name__ == "SwigPyObject":
|
||||
# Since 'form' is a SwigPyObject, we first need to convert it to a PyCObject.
|
||||
# However, there's no easy way of doing it, so we'll use a rather brutal approach:
|
||||
# converting the SwigPyObject to a 'long' (will go through 'SwigPyObject_long',
|
||||
# that will return the pointer's value as a long), and then convert that value
|
||||
# back to a pointer into a PyCObject.
|
||||
ptr_l = long(form)
|
||||
from ctypes import pythonapi, c_void_p, py_object
|
||||
pythonapi.PyCObject_FromVoidPtr.restype = py_object
|
||||
pythonapi.PyCObject_AsVoidPtr.argtypes = [c_void_p, c_void_p]
|
||||
form = pythonapi.PyCObject_FromVoidPtr(ptr_l, 0)
|
||||
return ctx.QtGui.QWidget.FromCObject(form)
|
||||
|
||||
|
||||
@ -89,7 +102,7 @@ class PluginForm(object):
|
||||
|
||||
@return: None
|
||||
"""
|
||||
return _idaapi.plgform_close(self.__clink__)
|
||||
return _idaapi.plgform_close(self.__clink__, options)
|
||||
|
||||
FORM_SAVE = 0x1
|
||||
"""Save state in desktop config"""
|
||||
@ -105,4 +118,4 @@ class PluginForm(object):
|
||||
#</pycode(py_plgform)>
|
||||
|
||||
plg = PluginForm()
|
||||
plg.Show("This is it")
|
||||
plg.Show("This is it")
|
||||
|
@ -102,6 +102,7 @@ private:
|
||||
}
|
||||
inline void _from_cobject(PyObject *pycobject)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
_from_fp((FILE *)PyCObject_AsVoidPtr(pycobject));
|
||||
}
|
||||
public:
|
||||
@ -119,7 +120,12 @@ public:
|
||||
own = true;
|
||||
fn.qclear();
|
||||
__idc_cvt_id__ = PY_ICID_OPAQUE;
|
||||
if ( pycobject != NULL && PyCObject_Check(pycobject) )
|
||||
bool ok;
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
ok = pycobject != NULL && PyCObject_Check(pycobject);
|
||||
}
|
||||
if ( ok )
|
||||
_from_cobject(pycobject);
|
||||
}
|
||||
|
||||
@ -135,7 +141,11 @@ public:
|
||||
if ( fp == NULL )
|
||||
return;
|
||||
if ( own )
|
||||
{
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
qfclose(fp);
|
||||
Py_END_ALLOW_THREADS;
|
||||
}
|
||||
fp = NULL;
|
||||
own = true;
|
||||
}
|
||||
@ -150,7 +160,9 @@ public:
|
||||
bool open(const char *filename, const char *mode)
|
||||
{
|
||||
close();
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
fp = qfopen(filename, mode);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( fp == NULL )
|
||||
return false;
|
||||
// Save file name
|
||||
@ -181,7 +193,11 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
static qfile_t *tmpfile()
|
||||
{
|
||||
return from_fp(qtmpfile());
|
||||
FILE *fp;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
fp = qtmpfile();
|
||||
Py_END_ALLOW_THREADS;
|
||||
return from_fp(fp);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@ -193,13 +209,21 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
int seek(int32 offset, int whence = SEEK_SET)
|
||||
{
|
||||
return qfseek(fp, offset, whence);
|
||||
int rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = qfseek(fp, offset, whence);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
int32 tell()
|
||||
{
|
||||
return qftell(fp);
|
||||
int32 rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = qftell(fp);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@ -210,12 +234,17 @@ public:
|
||||
char *buf = (char *) malloc(size + 5);
|
||||
if ( buf == NULL )
|
||||
break;
|
||||
int r = freadbytes(fp, buf, size, big_endian);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
int r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = freadbytes(fp, buf, size, big_endian);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( r != 0 )
|
||||
{
|
||||
free(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
PyObject *ret = PyString_FromStringAndSize(buf, r);
|
||||
free(buf);
|
||||
return ret;
|
||||
@ -231,7 +260,11 @@ public:
|
||||
char *buf = (char *) malloc(size + 5);
|
||||
if ( buf == NULL )
|
||||
break;
|
||||
int r = qfread(fp, buf, size);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
int r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = qfread(fp, buf, size);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( r <= 0 )
|
||||
{
|
||||
free(buf);
|
||||
@ -252,7 +285,12 @@ public:
|
||||
char *buf = (char *) malloc(size + 5);
|
||||
if ( buf == NULL )
|
||||
break;
|
||||
if ( qfgets(buf, size, fp) == NULL )
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
char *p;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
p = qfgets(buf, size, fp);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( p == NULL )
|
||||
{
|
||||
free(buf);
|
||||
break;
|
||||
@ -267,50 +305,87 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
int writebytes(PyObject *py_buf, bool big_endian)
|
||||
{
|
||||
int sz = PyString_GET_SIZE(py_buf);
|
||||
void *buf = (void *)PyString_AS_STRING(py_buf);
|
||||
return fwritebytes(fp, buf, sz, big_endian);
|
||||
Py_ssize_t sz;
|
||||
void *buf;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
sz = PyString_GET_SIZE(py_buf);
|
||||
buf = (void *)PyString_AS_STRING(py_buf);
|
||||
int rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = fwritebytes(fp, buf, int(sz), big_endian);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
int write(PyObject *py_buf)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyString_Check(py_buf) )
|
||||
return 0;
|
||||
return qfwrite(fp, (void *)PyString_AS_STRING(py_buf), PyString_GET_SIZE(py_buf));
|
||||
// Just so that there is no risk that the buffer returned by
|
||||
// 'PyString_AS_STRING' gets deallocated within the
|
||||
// Py_BEGIN|END_ALLOW_THREADS section.
|
||||
borref_t py_buf_ref(py_buf);
|
||||
void *p = (void *)PyString_AS_STRING(py_buf);
|
||||
Py_ssize_t sz = PyString_GET_SIZE(py_buf);
|
||||
int rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = qfwrite(fp, p, sz);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
int puts(const char *str)
|
||||
{
|
||||
return qfputs(str, fp);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
int rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = qfputs(str, fp);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
int32 size()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
int32 r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
int pos = qfseek(fp, 0, SEEK_END);
|
||||
int32 r = qftell(fp);
|
||||
r = qftell(fp);
|
||||
qfseek(fp, pos, SEEK_SET);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return r;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
int flush()
|
||||
{
|
||||
return qflush(fp);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
int rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = qflush(fp);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
PyObject *filename()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return PyString_FromString(fn.c_str());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
PyObject *get_char()
|
||||
{
|
||||
int ch = qfgetc(fp);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
int ch;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
ch = qfgetc(fp);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( ch == EOF )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("c", ch);
|
||||
@ -319,7 +394,12 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
int put_char(char chr)
|
||||
{
|
||||
return qfputc(chr, fp);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
int rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = qfputc(chr, fp);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
};
|
||||
//</inline(py_qfile)>
|
||||
|
@ -5,22 +5,26 @@
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *idc_parse_decl(til_t *ti, const char *decl, int flags)
|
||||
{
|
||||
qtype fields, type;
|
||||
tinfo_t tif;
|
||||
qstring name;
|
||||
bool ok = parse_decl(ti, decl, &name, &type, &fields, flags);
|
||||
if ( !ok )
|
||||
Py_RETURN_NONE;
|
||||
qtype fields, type;
|
||||
bool ok = parse_decl2(ti, decl, &name, &tif, flags);
|
||||
if ( ok )
|
||||
ok = tif.serialize(&type, &fields, NULL, SUDT_FAST);
|
||||
|
||||
return Py_BuildValue("(sss)",
|
||||
name.c_str(),
|
||||
(char *)type.c_str(),
|
||||
(char *)fields.c_str());
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( ok )
|
||||
return Py_BuildValue("(sss)",
|
||||
name.c_str(),
|
||||
(char *)type.c_str(),
|
||||
(char *)fields.c_str());
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
#<pydoc>
|
||||
def get_type_size0(ti, tp):
|
||||
def calc_type_size(ti, tp):
|
||||
"""
|
||||
Returns the size of a type
|
||||
@param ti: Type info. 'idaapi.cvar.idati' can be passed.
|
||||
@ -32,25 +36,69 @@ def get_type_size0(ti, tp):
|
||||
pass
|
||||
#</pydoc>
|
||||
*/
|
||||
PyObject *py_get_type_size0(const til_t *ti, PyObject *tp)
|
||||
PyObject *py_calc_type_size(const til_t *ti, PyObject *tp)
|
||||
{
|
||||
if ( !PyString_Check(tp) )
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( PyString_Check(tp) )
|
||||
{
|
||||
// To avoid release of 'data' during Py_BEGIN|END_ALLOW_THREADS section.
|
||||
borref_t tpref(tp);
|
||||
const type_t *data = (type_t *)PyString_AsString(tp);
|
||||
size_t sz;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
tinfo_t tif;
|
||||
tif.deserialize(ti, &data, NULL, NULL);
|
||||
sz = tif.get_size();
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( sz != BADSIZE )
|
||||
return PyInt_FromLong(sz);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "String expected!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t sz = get_type_size0(ti, (type_t *)PyString_AsString(tp));
|
||||
if ( sz == BADSIZE )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
return PyInt_FromLong(sz);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
#<pydoc>
|
||||
def print_type(ea, on_line):
|
||||
def apply_type(ti, ea, tp_name, py_type, py_fields, flags)
|
||||
"""
|
||||
Apply the specified type to the address
|
||||
@param ti: Type info. 'idaapi.cvar.idati' can be passed.
|
||||
@param py_type: type string
|
||||
@param py_fields: type fields
|
||||
@param ea: the address of the object
|
||||
@param flags: combination of TINFO_... constants or 0
|
||||
@return: Boolean
|
||||
"""
|
||||
pass
|
||||
#</pydoc>
|
||||
*/
|
||||
static bool py_apply_type(til_t *ti, PyObject *py_type, PyObject *py_fields, ea_t ea, int flags)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyString_Check(py_type) && !PyString_Check(py_fields) )
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "Typestring must be passed!");
|
||||
return NULL;
|
||||
}
|
||||
const type_t *type = (const type_t *) PyString_AsString(py_type);
|
||||
const p_list *fields = (const p_list *) PyString_AsString(py_fields);
|
||||
bool rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
tinfo_t tif;
|
||||
rc = tif.deserialize(ti, &type, &fields, NULL) && apply_tinfo2(ea, tif, flags);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
#<pydoc>
|
||||
def print_type(ea, one_line):
|
||||
"""
|
||||
Returns the type of an item
|
||||
@return:
|
||||
@ -62,14 +110,13 @@ def print_type(ea, on_line):
|
||||
*/
|
||||
static PyObject *py_print_type(ea_t ea, bool one_line)
|
||||
{
|
||||
char buf[MAXSTR];
|
||||
if ( print_type2(ea, buf, sizeof(buf), one_line ? PRTYPE_1LINE : PRTYPE_MULTI) )
|
||||
{
|
||||
qstrncat(buf, ";", sizeof(buf));
|
||||
char buf[64*MAXSTR];
|
||||
int flags = PRTYPE_SEMI | (one_line ? PRTYPE_1LINE : PRTYPE_MULTI);
|
||||
bool ok = print_type2(ea, buf, sizeof(buf), one_line ? PRTYPE_1LINE : PRTYPE_MULTI);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( ok )
|
||||
return PyString_FromString(buf);
|
||||
}
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -90,17 +137,24 @@ PyObject *py_unpack_object_from_idb(
|
||||
ea_t ea,
|
||||
int pio_flags = 0)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyString_Check(py_type) && !PyString_Check(py_fields) )
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "Typestring must be passed!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// To avoid release of 'type'/'fields' during Py_BEGIN|END_ALLOW_THREADS section.
|
||||
borref_t py_type_ref(py_type);
|
||||
borref_t py_fields_ref(py_fields);
|
||||
|
||||
// Unpack
|
||||
type_t *type = (type_t *) PyString_AsString(py_type);
|
||||
p_list *fields = (p_list *) PyString_AsString(py_fields);
|
||||
idc_value_t idc_obj;
|
||||
error_t err = unpack_object_from_idb(
|
||||
error_t err;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
err = unpack_object_from_idb(
|
||||
&idc_obj,
|
||||
ti,
|
||||
type,
|
||||
@ -108,22 +162,21 @@ PyObject *py_unpack_object_from_idb(
|
||||
ea,
|
||||
NULL,
|
||||
pio_flags);
|
||||
Py_END_ALLOW_THREADS;
|
||||
|
||||
// Unpacking failed?
|
||||
if ( err != eOk )
|
||||
return Py_BuildValue("(ii)", 0, err);
|
||||
|
||||
// Convert
|
||||
PyObject *py_ret(NULL);
|
||||
ref_t py_ret;
|
||||
err = idcvar_to_pyvar(idc_obj, &py_ret);
|
||||
|
||||
// Conversion failed?
|
||||
if ( err != CIP_OK )
|
||||
return Py_BuildValue("(ii)", 0, err);
|
||||
|
||||
PyObject *py_result = Py_BuildValue("(iO)", 1, py_ret);
|
||||
Py_DECREF(py_ret);
|
||||
return py_result;
|
||||
else
|
||||
return Py_BuildValue("(iO)", 1, py_ret.o);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -152,12 +205,17 @@ PyObject *py_unpack_object_from_bv(
|
||||
PyObject *py_bytes,
|
||||
int pio_flags = 0)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyString_Check(py_type) && !PyString_Check(py_fields) && !PyString_Check(py_bytes) )
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "Incorrect argument type!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// To avoid release of 'type'/'fields' during Py_BEGIN|END_ALLOW_THREADS section.
|
||||
borref_t py_type_ref(py_type);
|
||||
borref_t py_fields_ref(py_fields);
|
||||
|
||||
// Get type strings
|
||||
type_t *type = (type_t *) PyString_AsString(py_type);
|
||||
p_list *fields = (p_list *) PyString_AsString(py_fields);
|
||||
@ -168,29 +226,30 @@ PyObject *py_unpack_object_from_bv(
|
||||
memcpy(bytes.begin(), PyString_AsString(py_bytes), bytes.size());
|
||||
|
||||
idc_value_t idc_obj;
|
||||
error_t err = unpack_object_from_bv(
|
||||
error_t err;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
err = unpack_object_from_bv(
|
||||
&idc_obj,
|
||||
ti,
|
||||
type,
|
||||
fields,
|
||||
bytes,
|
||||
pio_flags);
|
||||
Py_END_ALLOW_THREADS;
|
||||
|
||||
// Unpacking failed?
|
||||
if ( err != eOk )
|
||||
return Py_BuildValue("(ii)", 0, err);
|
||||
|
||||
// Convert
|
||||
PyObject *py_ret(NULL);
|
||||
ref_t py_ret;
|
||||
err = idcvar_to_pyvar(idc_obj, &py_ret);
|
||||
|
||||
// Conversion failed?
|
||||
if ( err != CIP_OK )
|
||||
return Py_BuildValue("(ii)", 0, err);
|
||||
|
||||
PyObject *py_result = Py_BuildValue("(iO)", 1, py_ret);
|
||||
Py_DECREF(py_ret);
|
||||
return py_result;
|
||||
return Py_BuildValue("(iO)", 1, py_ret.o);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -218,6 +277,7 @@ PyObject *py_pack_object_to_idb(
|
||||
ea_t ea,
|
||||
int pio_flags = 0)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyString_Check(py_type) && !PyString_Check(py_fields) )
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "Typestring must be passed!");
|
||||
@ -226,15 +286,24 @@ PyObject *py_pack_object_to_idb(
|
||||
|
||||
// Convert Python object to IDC object
|
||||
idc_value_t idc_obj;
|
||||
if ( !convert_pyobj_to_idc_exc(py_obj, &idc_obj) )
|
||||
borref_t py_obj_ref(py_obj);
|
||||
if ( !pyvar_to_idcvar_or_error(py_obj_ref, &idc_obj) )
|
||||
return NULL;
|
||||
|
||||
// To avoid release of 'type'/'fields' during Py_BEGIN|END_ALLOW_THREADS section.
|
||||
borref_t py_type_ref(py_type);
|
||||
borref_t py_fields_ref(py_fields);
|
||||
|
||||
// Get type strings
|
||||
type_t *type = (type_t *) PyString_AsString(py_type);
|
||||
p_list *fields = (p_list *) PyString_AsString(py_fields);
|
||||
type_t *type = (type_t *)PyString_AsString(py_type);
|
||||
p_list *fields = (p_list *)PyString_AsString(py_fields);
|
||||
|
||||
// Pack
|
||||
error_t err = pack_object_to_idb(&idc_obj, ti, type, fields, ea, pio_flags);
|
||||
// error_t err;
|
||||
error_t err;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
err = pack_object_to_idb(&idc_obj, ti, type, fields, ea, pio_flags);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return PyInt_FromLong(err);
|
||||
}
|
||||
|
||||
@ -265,6 +334,7 @@ PyObject *py_pack_object_to_bv(
|
||||
ea_t base_ea,
|
||||
int pio_flags=0)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyString_Check(py_type) && !PyString_Check(py_fields) )
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "Typestring must be passed!");
|
||||
@ -273,16 +343,23 @@ PyObject *py_pack_object_to_bv(
|
||||
|
||||
// Convert Python object to IDC object
|
||||
idc_value_t idc_obj;
|
||||
if ( !convert_pyobj_to_idc_exc(py_obj, &idc_obj) )
|
||||
borref_t py_obj_ref(py_obj);
|
||||
if ( !pyvar_to_idcvar_or_error(py_obj_ref, &idc_obj) )
|
||||
return NULL;
|
||||
|
||||
// To avoid release of 'type'/'fields' during Py_BEGIN|END_ALLOW_THREADS section.
|
||||
borref_t py_type_ref(py_type);
|
||||
borref_t py_fields_ref(py_fields);
|
||||
|
||||
// Get type strings
|
||||
type_t *type = (type_t *) PyString_AsString(py_type);
|
||||
p_list *fields = (p_list *) PyString_AsString(py_fields);
|
||||
type_t *type = (type_t *)PyString_AsString(py_type);
|
||||
p_list *fields = (p_list *)PyString_AsString(py_fields);
|
||||
|
||||
// Pack
|
||||
relobj_t bytes;
|
||||
error_t err = pack_object_to_bv(
|
||||
error_t err;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
err = pack_object_to_bv(
|
||||
&idc_obj,
|
||||
ti,
|
||||
type,
|
||||
@ -290,19 +367,172 @@ PyObject *py_pack_object_to_bv(
|
||||
&bytes,
|
||||
NULL,
|
||||
pio_flags);
|
||||
do
|
||||
{
|
||||
if ( err != eOk )
|
||||
break;
|
||||
if ( !bytes.relocate(base_ea, inf.mf) )
|
||||
{
|
||||
if ( err == eOk && !bytes.relocate(base_ea, inf.mf) )
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( err == eOk )
|
||||
return Py_BuildValue("(is#)", 1, bytes.begin(), bytes.size());
|
||||
} while ( false );
|
||||
return Py_BuildValue("(ii)", 0, err);
|
||||
else
|
||||
return Py_BuildValue("(ii)", 0, err);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
/* Parse types from a string or file. See ParseTypes() in idc.py */
|
||||
int idc_parse_types(const char *input, int flags)
|
||||
{
|
||||
int hti = ((flags >> 4) & 7) << HTI_PAK_SHIFT;
|
||||
|
||||
if ((flags & 1) != 0)
|
||||
hti |= HTI_FIL;
|
||||
|
||||
return parse_decls(idati, input, (flags & 2) == 0 ? msg : NULL, hti);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *py_idc_get_type_raw(ea_t ea)
|
||||
{
|
||||
qtype type, fields;
|
||||
bool ok = get_tinfo(ea, &type, &fields);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( ok )
|
||||
return Py_BuildValue("(ss)", (char *)type.c_str(), (char *)fields.c_str());
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *py_idc_get_local_type_raw(int ordinal)
|
||||
{
|
||||
const type_t *type;
|
||||
const p_list *fields;
|
||||
bool ok = get_numbered_type(idati, ordinal, &type, &fields);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( ok )
|
||||
return Py_BuildValue("(ss)", (char *)type, (char *)fields);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
char *idc_guess_type(ea_t ea, char *buf, size_t bufsize)
|
||||
{
|
||||
tinfo_t tif;
|
||||
if ( guess_tinfo2(ea, &tif) )
|
||||
{
|
||||
qstring out;
|
||||
if ( tif.print(&out) )
|
||||
return qstrncpy(buf, out.begin(), bufsize);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
char *idc_get_type(ea_t ea, char *buf, size_t bufsize)
|
||||
{
|
||||
tinfo_t tif;
|
||||
if ( get_tinfo2(ea, &tif) )
|
||||
{
|
||||
qstring out;
|
||||
if ( tif.print(&out) )
|
||||
{
|
||||
qstrncpy(buf, out.c_str(), bufsize);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
int idc_set_local_type(int ordinal, const char *dcl, int flags)
|
||||
{
|
||||
if (dcl == NULL || dcl[0] == '\0')
|
||||
{
|
||||
if ( !del_numbered_type(idati, ordinal) )
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tinfo_t tif;
|
||||
qstring name;
|
||||
if ( !parse_decl2(idati, dcl, &name, &tif, flags) )
|
||||
return 0;
|
||||
|
||||
if ( ordinal <= 0 )
|
||||
{
|
||||
if ( !name.empty() )
|
||||
ordinal = get_type_ordinal(idati, name.begin());
|
||||
|
||||
if ( ordinal <= 0 )
|
||||
ordinal = alloc_type_ordinal(idati);
|
||||
}
|
||||
|
||||
if ( tif.set_numbered_type(idati, ordinal, 0, name.c_str()) != TERR_OK )
|
||||
return 0;
|
||||
}
|
||||
return ordinal;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
int idc_get_local_type(int ordinal, int flags, char *buf, size_t maxsize)
|
||||
{
|
||||
tinfo_t tif;
|
||||
if ( !tif.get_numbered_type(idati, ordinal) )
|
||||
{
|
||||
buf[0] = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
qstring res;
|
||||
const char *name = get_numbered_type_name(idati, ordinal);
|
||||
if ( !tif.print(&res, name, flags, 2, 40) )
|
||||
{
|
||||
buf[0] = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
qstrncpy(buf, res.begin(), maxsize);
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *idc_print_type(PyObject *py_type, PyObject *py_fields, const char *name, int flags)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyString_Check(py_type) && !PyString_Check(py_fields) )
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "Typestring must be passed!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// To avoid release of 'type'/'fields' during Py_BEGIN|END_ALLOW_THREADS section.
|
||||
borref_t py_type_ref(py_type);
|
||||
borref_t py_fields_ref(py_fields);
|
||||
|
||||
qstring res;
|
||||
const type_t *type = (type_t *)PyString_AsString(py_type);
|
||||
const p_list *fields = (p_list *)PyString_AsString(py_fields);
|
||||
bool ok;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
tinfo_t tif;
|
||||
ok = tif.deserialize(idati, &type, &fields, NULL)
|
||||
&& tif.print(&res, name, flags, 2, 40);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( ok )
|
||||
return PyString_FromString(res.begin());
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
char idc_get_local_type_name(int ordinal, char *buf, size_t bufsize)
|
||||
{
|
||||
const char *name = get_numbered_type_name(idati, ordinal);
|
||||
if ( name == NULL )
|
||||
return false;
|
||||
|
||||
qstrncpy(buf, name, bufsize);
|
||||
return true;
|
||||
}
|
||||
|
||||
//</inline(py_typeinf)>
|
||||
|
||||
#endif
|
||||
|
15
pywraps/py_typeinf.py
Normal file
15
pywraps/py_typeinf.py
Normal file
@ -0,0 +1,15 @@
|
||||
#<pycode(py_typeinf)>
|
||||
|
||||
def get_type_size0(ti, tp):
|
||||
"""
|
||||
DEPRECATED. Please use calc_type_size instead
|
||||
Returns the size of a type
|
||||
@param ti: Type info. 'idaapi.cvar.idati' can be passed.
|
||||
@param tp: type string
|
||||
@return:
|
||||
- None on failure
|
||||
- The size of the type
|
||||
"""
|
||||
return calc_type_size(ti, tp)
|
||||
|
||||
#</pycode(py_typeinf)>
|
@ -35,6 +35,8 @@ def init_output_buffer(size = MAXSTR):
|
||||
*/
|
||||
PyObject *py_init_output_buffer(size_t size = MAXSTR)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
// Let Python allocate a writable string buffer for us
|
||||
PyObject *py_str = PyString_FromStringAndSize(NULL, size);
|
||||
if ( py_str == NULL )
|
||||
@ -73,6 +75,7 @@ PyObject *py_decode_preceding_insn(ea_t ea)
|
||||
{
|
||||
bool farref;
|
||||
ea_t r = decode_preceding_insn(ea, &farref);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return Py_BuildValue("(" PY_FMT64 "i)", pyul_t(r), farref ? 1 : 0);
|
||||
}
|
||||
|
||||
@ -117,6 +120,7 @@ def get_stkvar(op, v):
|
||||
*/
|
||||
PyObject *py_get_stkvar(PyObject *py_op, PyObject *py_v)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *op = op_t_get_clink(py_op);
|
||||
uint64 v;
|
||||
if ( op == NULL || !PyW_GetNumber(py_v, &v) )
|
||||
@ -150,6 +154,7 @@ def add_stkvar3(op, v, flags):
|
||||
*/
|
||||
bool py_add_stkvar3(PyObject *py_op, PyObject *py_v, int flags)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *op = op_t_get_clink(py_op);
|
||||
uint64 v;
|
||||
return ( op == NULL || !PyW_GetNumber(py_v, &v) || !add_stkvar3(*op, sval_t(v), flags)) ? false : true;
|
||||
@ -192,11 +197,24 @@ bool py_apply_type_to_stkarg(
|
||||
const char *name)
|
||||
{
|
||||
uint64 v;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *op = op_t_get_clink(py_op);
|
||||
if ( op == NULL || !PyW_GetNumber(py_uv, &v) || !PyString_Check(py_type))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return apply_type_to_stkarg(*op, uval_t(v), (type_t *) PyString_AsString(py_type), name);
|
||||
{
|
||||
const type_t *t = (type_t *) PyString_AsString(py_type);
|
||||
tinfo_t tif;
|
||||
tif.deserialize(idati, &t);
|
||||
borref_t br(py_op);
|
||||
bool rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = apply_tinfo_to_stkarg(*op, uval_t(v), tif, name);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -213,6 +231,7 @@ def OutImmChar(op, outflags = 0):
|
||||
*/
|
||||
static void py_OutImmChar(PyObject *x)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *op = op_t_get_clink(x);
|
||||
if ( op != NULL )
|
||||
OutImmChar(*op);
|
||||
@ -233,6 +252,7 @@ def ua_stkvar2(op, outflags = 0):
|
||||
*/
|
||||
static bool py_ua_stkvar2(PyObject *x, adiff_t v, int flags)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *op = op_t_get_clink(x);
|
||||
return op == NULL ? false : ua_stkvar2(*op, v, flags);
|
||||
}
|
||||
@ -252,6 +272,7 @@ def ua_add_off_drefs(op, type):
|
||||
*/
|
||||
ea_t py_ua_add_off_drefs(PyObject *py_op, dref_t type)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *op = op_t_get_clink(py_op);
|
||||
return op == NULL ? BADADDR : ua_add_off_drefs(*op, type);
|
||||
}
|
||||
@ -270,6 +291,7 @@ def ua_add_off_drefs2(op, type, outf):
|
||||
*/
|
||||
ea_t py_ua_add_off_drefs2(PyObject *py_op, dref_t type, int outf)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *op = op_t_get_clink(py_op);
|
||||
return op == NULL ? BADADDR : ua_add_off_drefs2(*op, type, outf);
|
||||
}
|
||||
@ -295,6 +317,7 @@ bool py_out_name_expr(
|
||||
ea_t ea,
|
||||
PyObject *py_off)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *op = op_t_get_clink(py_op);
|
||||
uint64 v(0);
|
||||
adiff_t off;
|
||||
@ -302,13 +325,14 @@ bool py_out_name_expr(
|
||||
off = adiff_t(v);
|
||||
else
|
||||
off = BADADDR;
|
||||
|
||||
|
||||
return op == NULL ? false : out_name_expr(*op, ea, off);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static PyObject *insn_t_get_op_link(PyObject *py_insn_lnk, int i)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( i < 0 || i >= UA_MAXOP || !PyCObject_Check(py_insn_lnk) )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
@ -322,18 +346,21 @@ static PyObject *insn_t_get_op_link(PyObject *py_insn_lnk, int i)
|
||||
//-------------------------------------------------------------------------
|
||||
static PyObject *insn_t_create()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return PyCObject_FromVoidPtr(new insn_t(), NULL);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static PyObject *op_t_create()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return PyCObject_FromVoidPtr(new op_t(), NULL);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static bool op_t_assign(PyObject *self, PyObject *other)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *lhs = op_t_get_clink(self);
|
||||
op_t *rhs = op_t_get_clink(other);
|
||||
if (lhs == NULL || rhs == NULL)
|
||||
@ -346,6 +373,7 @@ static bool op_t_assign(PyObject *self, PyObject *other)
|
||||
//-------------------------------------------------------------------------
|
||||
static bool insn_t_assign(PyObject *self, PyObject *other)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *lhs = insn_t_get_clink(self);
|
||||
insn_t *rhs = insn_t_get_clink(other);
|
||||
if (lhs == NULL || rhs == NULL)
|
||||
@ -358,6 +386,7 @@ static bool insn_t_assign(PyObject *self, PyObject *other)
|
||||
//-------------------------------------------------------------------------
|
||||
static bool op_t_destroy(PyObject *py_obj)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyCObject_Check(py_obj) )
|
||||
return false;
|
||||
|
||||
@ -370,6 +399,7 @@ static bool op_t_destroy(PyObject *py_obj)
|
||||
//-------------------------------------------------------------------------
|
||||
static bool insn_t_destroy(PyObject *py_obj)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyCObject_Check(py_obj) )
|
||||
return false;
|
||||
|
||||
@ -381,13 +411,16 @@ static bool insn_t_destroy(PyObject *py_obj)
|
||||
// Returns a C link to the global 'cmd' variable
|
||||
static PyObject *py_get_global_cmd_link()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return PyCObject_FromVoidPtr(&::cmd, NULL);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static PyObject *insn_t_is_canon_insn(int itype)
|
||||
{
|
||||
if ( ph.is_canon_insn(itype) )
|
||||
bool ok = ph.is_canon_insn(itype);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( ok )
|
||||
Py_RETURN_TRUE;
|
||||
else
|
||||
Py_RETURN_FALSE;
|
||||
@ -396,13 +429,17 @@ static PyObject *insn_t_is_canon_insn(int itype)
|
||||
//-------------------------------------------------------------------------
|
||||
static PyObject *insn_t_get_canon_feature(int itype)
|
||||
{
|
||||
return Py_BuildValue("I", ph.is_canon_insn(itype) ? ph.instruc[itype-ph.instruc_start].feature : 0);
|
||||
uint32 v = ph.is_canon_insn(itype) ? ph.instruc[itype-ph.instruc_start].feature : 0;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return Py_BuildValue("I", v);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static PyObject *insn_t_get_canon_mnem(int itype)
|
||||
{
|
||||
if ( ph.is_canon_insn(itype) )
|
||||
bool ok = ph.is_canon_insn(itype);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( ok )
|
||||
return Py_BuildValue("s", ph.instruc[itype-ph.instruc_start].name);
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
@ -411,6 +448,7 @@ static PyObject *insn_t_get_canon_mnem(int itype)
|
||||
//-------------------------------------------------------------------------
|
||||
static PyObject *insn_t_get_cs(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -419,10 +457,11 @@ static PyObject *insn_t_get_cs(PyObject *self)
|
||||
|
||||
static void insn_t_set_cs(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
|
||||
|
||||
uint64 v(0);
|
||||
PyW_GetNumber(value, &v);
|
||||
link->cs = ea_t(v);
|
||||
@ -430,6 +469,7 @@ static void insn_t_set_cs(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *insn_t_get_ip(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -438,6 +478,7 @@ static PyObject *insn_t_get_ip(PyObject *self)
|
||||
|
||||
static void insn_t_set_ip(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -448,6 +489,7 @@ static void insn_t_set_ip(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *insn_t_get_ea(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -456,6 +498,7 @@ static PyObject *insn_t_get_ea(PyObject *self)
|
||||
|
||||
static void insn_t_set_ea(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -466,6 +509,7 @@ static void insn_t_set_ea(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *insn_t_get_itype(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -474,6 +518,7 @@ static PyObject *insn_t_get_itype(PyObject *self)
|
||||
|
||||
static void insn_t_set_itype(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -482,6 +527,7 @@ static void insn_t_set_itype(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *insn_t_get_size(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -490,6 +536,7 @@ static PyObject *insn_t_get_size(PyObject *self)
|
||||
|
||||
static void insn_t_set_size(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -498,6 +545,7 @@ static void insn_t_set_size(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *insn_t_get_auxpref(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -506,6 +554,7 @@ static PyObject *insn_t_get_auxpref(PyObject *self)
|
||||
|
||||
static void insn_t_set_auxpref(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -514,6 +563,7 @@ static void insn_t_set_auxpref(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *insn_t_get_segpref(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -522,6 +572,7 @@ static PyObject *insn_t_get_segpref(PyObject *self)
|
||||
|
||||
static void insn_t_set_segpref(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -530,6 +581,7 @@ static void insn_t_set_segpref(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *insn_t_get_insnpref(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -538,6 +590,7 @@ static PyObject *insn_t_get_insnpref(PyObject *self)
|
||||
|
||||
static void insn_t_set_insnpref(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -546,6 +599,7 @@ static void insn_t_set_insnpref(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *insn_t_get_flags(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -554,6 +608,7 @@ static PyObject *insn_t_get_flags(PyObject *self)
|
||||
|
||||
static void insn_t_set_flags(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -563,6 +618,7 @@ static void insn_t_set_flags(PyObject *self, PyObject *value)
|
||||
//-------------------------------------------------------------------------
|
||||
static PyObject *op_t_get_n(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -579,6 +635,7 @@ static void op_t_set_n(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_type(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -587,6 +644,7 @@ static PyObject *op_t_get_type(PyObject *self)
|
||||
|
||||
static void op_t_set_type(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -595,6 +653,7 @@ static void op_t_set_type(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_offb(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -603,6 +662,7 @@ static PyObject *op_t_get_offb(PyObject *self)
|
||||
|
||||
static void op_t_set_offb(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -611,6 +671,7 @@ static void op_t_set_offb(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_offo(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -619,6 +680,7 @@ static PyObject *op_t_get_offo(PyObject *self)
|
||||
|
||||
static void op_t_set_offo(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -627,6 +689,7 @@ static void op_t_set_offo(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_flags(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -635,6 +698,7 @@ static PyObject *op_t_get_flags(PyObject *self)
|
||||
|
||||
static void op_t_set_flags(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -643,6 +707,7 @@ static void op_t_set_flags(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_dtyp(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -651,6 +716,7 @@ static PyObject *op_t_get_dtyp(PyObject *self)
|
||||
|
||||
static void op_t_set_dtyp(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -659,6 +725,7 @@ static void op_t_set_dtyp(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_reg_phrase(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -666,6 +733,7 @@ static PyObject *op_t_get_reg_phrase(PyObject *self)
|
||||
}
|
||||
static void op_t_set_reg_phrase(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -674,6 +742,7 @@ static void op_t_set_reg_phrase(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_value(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -682,6 +751,7 @@ static PyObject *op_t_get_value(PyObject *self)
|
||||
|
||||
static void op_t_set_value(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -690,6 +760,7 @@ static void op_t_set_value(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_addr(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -698,6 +769,7 @@ static PyObject *op_t_get_addr(PyObject *self)
|
||||
|
||||
static void op_t_set_addr(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -708,6 +780,7 @@ static void op_t_set_addr(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_specval(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -716,6 +789,7 @@ static PyObject *op_t_get_specval(PyObject *self)
|
||||
|
||||
static void op_t_set_specval(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -726,6 +800,7 @@ static void op_t_set_specval(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_specflag1(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -734,6 +809,7 @@ static PyObject *op_t_get_specflag1(PyObject *self)
|
||||
|
||||
static void op_t_set_specflag1(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -742,6 +818,7 @@ static void op_t_set_specflag1(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_specflag2(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -750,6 +827,7 @@ static PyObject *op_t_get_specflag2(PyObject *self)
|
||||
|
||||
static void op_t_set_specflag2(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -758,6 +836,7 @@ static void op_t_set_specflag2(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_specflag3(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -766,6 +845,7 @@ static PyObject *op_t_get_specflag3(PyObject *self)
|
||||
|
||||
static void op_t_set_specflag3(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -774,6 +854,7 @@ static void op_t_set_specflag3(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_specflag4(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -782,6 +863,7 @@ static PyObject *op_t_get_specflag4(PyObject *self)
|
||||
|
||||
static void op_t_set_specflag4(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
|
810
pywraps/py_view_base.hpp
Normal file
810
pywraps/py_view_base.hpp
Normal file
@ -0,0 +1,810 @@
|
||||
#ifndef __PY_VIEW_BASE__
|
||||
#define __PY_VIEW_BASE__
|
||||
|
||||
//<code(py_view_base)>
|
||||
|
||||
//#define PYGDBG_ENABLED
|
||||
#ifdef PYGDBG_ENABLED
|
||||
#define PYGLOG(...) msg(__VA_ARGS__)
|
||||
#else
|
||||
#define PYGLOG(...)
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
class py_customidamemo_t;
|
||||
class lookup_info_t
|
||||
{
|
||||
public:
|
||||
void add(TForm *form, TCustomControl *view, py_customidamemo_t *py_view)
|
||||
{
|
||||
QASSERT(0, form != NULL && view != NULL && py_view != NULL
|
||||
&& !find_by_form(NULL, NULL, form)
|
||||
&& !find_by_view(NULL, NULL, view)
|
||||
&& !find_by_py_view(NULL, NULL, py_view));
|
||||
entry_t &e = entries.push_back();
|
||||
e.form = form;
|
||||
e.view = view;
|
||||
e.py_view = py_view;
|
||||
}
|
||||
|
||||
#define FIND_BY__BODY(crit, res1, res2) \
|
||||
{ \
|
||||
for ( entries_t::const_iterator it = entries.begin(); it != entries.end(); ++it ) \
|
||||
{ \
|
||||
const entry_t &e = *it; \
|
||||
if ( e.crit == crit ) \
|
||||
{ \
|
||||
if ( out_##res1 != NULL ) \
|
||||
*out_##res1 = e.res1; \
|
||||
if ( out_##res2 != NULL ) \
|
||||
*out_##res2 = e.res2; \
|
||||
return true; \
|
||||
} \
|
||||
} \
|
||||
return false; \
|
||||
}
|
||||
bool find_by_form(TCustomControl **out_view, py_customidamemo_t **out_py_view, const TForm *form) const FIND_BY__BODY(form, view, py_view);
|
||||
bool find_by_view(TForm **out_form, py_customidamemo_t **out_py_view, const TCustomControl *view) const FIND_BY__BODY(view, form, py_view);
|
||||
bool find_by_py_view(TForm **out_form, TCustomControl **out_view, const py_customidamemo_t *py_view) const FIND_BY__BODY(py_view, view, form);
|
||||
#undef FIND_BY__BODY
|
||||
|
||||
bool del_by_py_view(const py_customidamemo_t *py_view)
|
||||
{
|
||||
for ( entries_t::iterator it = entries.begin(); it != entries.end(); ++it )
|
||||
{
|
||||
if ( it->py_view == py_view )
|
||||
{
|
||||
entries.erase(it);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
struct entry_t
|
||||
{
|
||||
TForm *form;
|
||||
TCustomControl *view;
|
||||
py_customidamemo_t *py_view;
|
||||
};
|
||||
typedef qvector<entry_t> entries_t;
|
||||
entries_t entries;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
T *view_extract_this(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
ref_t py_this(PyW_TryGetAttrString(self, S_M_THIS));
|
||||
if ( py_this == NULL || !PyCObject_Check(py_this.o) )
|
||||
return NULL;
|
||||
return (T*) PyCObject_AsVoidPtr(py_this.o);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
class py_customidamemo_t
|
||||
{
|
||||
void convert_node_info(
|
||||
node_info_t *out,
|
||||
uint32 *out_flags,
|
||||
ref_t py_nodeinfo)
|
||||
{
|
||||
if ( out_flags != NULL )
|
||||
*out_flags = 0;
|
||||
#define COPY_PROP(checker, converter, pname, flag) \
|
||||
do \
|
||||
{ \
|
||||
newref_t pname(PyObject_GetAttrString(py_nodeinfo.o, #pname)); \
|
||||
if ( pname != NULL && checker(pname.o) ) \
|
||||
{ \
|
||||
out->pname = converter(pname.o); \
|
||||
if ( out_flags != NULL ) \
|
||||
*out_flags |= flag; \
|
||||
} \
|
||||
} while ( false )
|
||||
#define COPY_ULONG_PROP(pname, flag) COPY_PROP(PyNumber_Check, PyLong_AsUnsignedLong, pname, flag)
|
||||
#define COPY_STRING_PROP(pname, flag) COPY_PROP(PyString_Check, PyString_AsString, pname, flag)
|
||||
COPY_ULONG_PROP(bg_color, NIF_BG_COLOR);
|
||||
COPY_ULONG_PROP(frame_color, NIF_FRAME_COLOR);
|
||||
COPY_ULONG_PROP(ea, NIF_EA);
|
||||
COPY_STRING_PROP(text, NIF_TEXT);
|
||||
#undef COPY_STRING_PROP
|
||||
#undef COPY_ULONG_PROP
|
||||
#undef COPY_PROP
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
GRBASE_HAVE_VIEW_ACTIVATED = 0x001,
|
||||
GRBASE_HAVE_VIEW_DEACTIVATED = 0x002,
|
||||
GRBASE_HAVE_KEYDOWN = 0x004,
|
||||
GRBASE_HAVE_POPUP = 0x008,
|
||||
GRBASE_HAVE_VIEW_CLICK = 0x010,
|
||||
GRBASE_HAVE_VIEW_DBLCLICK = 0x020,
|
||||
GRBASE_HAVE_VIEW_CURPOS = 0x040,
|
||||
GRBASE_HAVE_CLOSE = 0x080,
|
||||
GRBASE_HAVE_VIEW_SWITCHED = 0x100,
|
||||
GRBASE_HAVE_VIEW_MOUSE_OVER = 0x200,
|
||||
};
|
||||
|
||||
static void ensure_view_callbacks_installed();
|
||||
int cb_flags;
|
||||
|
||||
protected:
|
||||
ref_t self;
|
||||
TCustomControl *view;
|
||||
// This is called after having modified the
|
||||
// node properties in the IDB. In case an
|
||||
// implementation is performing some caching,
|
||||
// this is a chance to update that cache.
|
||||
// If 'ni' is NULL, then the node info was deleted.
|
||||
virtual void node_info_modified(
|
||||
int /*n*/,
|
||||
const node_info_t * /*ni*/,
|
||||
uint32 /*flags*/) {}
|
||||
|
||||
struct callback_id_t
|
||||
{
|
||||
qstring name;
|
||||
int have;
|
||||
};
|
||||
struct callbacks_ids_t : public qvector<callback_id_t>
|
||||
{
|
||||
void add(const char *_n, int _h)
|
||||
{
|
||||
callback_id_t &o = push_back();
|
||||
o.name = _n;
|
||||
o.have = _h;
|
||||
}
|
||||
};
|
||||
callbacks_ids_t cbids;
|
||||
|
||||
bool collect_pyobject_callbacks(PyObject *self);
|
||||
virtual void collect_class_callbacks_ids(callbacks_ids_t *out);
|
||||
|
||||
// Bi-directionally bind/unbind the Python object and this controller.
|
||||
bool bind(PyObject *_self, TCustomControl *view);
|
||||
void unbind();
|
||||
|
||||
static lookup_info_t lookup_info;
|
||||
|
||||
public:
|
||||
py_customidamemo_t();
|
||||
virtual ~py_customidamemo_t();
|
||||
virtual void refresh()
|
||||
{
|
||||
refresh_viewer(view);
|
||||
}
|
||||
void set_node_info(PyObject *py_node_idx, PyObject *py_node_info, PyObject *py_flags);
|
||||
void set_nodes_infos(PyObject *dict);
|
||||
PyObject *get_node_info(PyObject *py_node_idx);
|
||||
void del_nodes_infos(PyObject *py_nodes);
|
||||
PyObject *get_current_renderer_type();
|
||||
void set_current_renderer_type(PyObject *py_rto);
|
||||
PyObject *create_groups(PyObject *groups_infos);
|
||||
PyObject *delete_groups(PyObject *groups, PyObject *new_current);
|
||||
PyObject *set_groups_visibility(PyObject *groups, PyObject *expand, PyObject *new_current);
|
||||
|
||||
// View events
|
||||
void on_view_activated();
|
||||
void on_view_deactivated();
|
||||
void on_view_keydown(int key, int state);
|
||||
void on_view_popup();
|
||||
void on_view_click(const view_mouse_event_t *event);
|
||||
void on_view_dblclick(const view_mouse_event_t *event);
|
||||
void on_view_curpos();
|
||||
void on_view_close();
|
||||
void on_view_switched(tcc_renderer_type_t rt);
|
||||
void on_view_mouse_over(const view_mouse_event_t *event);
|
||||
inline bool has_callback(int flag) { return (cb_flags & flag) != 0; }
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
py_customidamemo_t::py_customidamemo_t()
|
||||
: self(newref_t(NULL)),
|
||||
view(NULL)
|
||||
{
|
||||
PYGLOG("%p: py_customidamemo_t()\n", this);
|
||||
ensure_view_callbacks_installed();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
py_customidamemo_t::~py_customidamemo_t()
|
||||
{
|
||||
PYGLOG("%p: ~py_customidamemo_t()\n", this);
|
||||
unbind();
|
||||
lookup_info.del_by_py_view(this);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void py_customidamemo_t::ensure_view_callbacks_installed()
|
||||
{
|
||||
static bool installed = false;
|
||||
if ( !installed )
|
||||
{
|
||||
struct ida_local lambda_t
|
||||
{
|
||||
static int idaapi callback(void * /*ud*/, int code, va_list va)
|
||||
{
|
||||
py_customidamemo_t *py_view;
|
||||
if ( lookup_info.find_by_view(NULL, &py_view, va_arg(va, TCustomControl *)) )
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
switch ( code )
|
||||
{
|
||||
case view_activated:
|
||||
py_view->on_view_activated();
|
||||
break;
|
||||
case view_deactivated:
|
||||
py_view->on_view_deactivated();
|
||||
break;
|
||||
case view_keydown:
|
||||
{
|
||||
int key = va_arg(va, int);
|
||||
int state = va_arg(va, int);
|
||||
py_view->on_view_keydown(key, state);
|
||||
}
|
||||
break;
|
||||
case view_popup:
|
||||
py_view->on_view_popup();
|
||||
break;
|
||||
case view_click:
|
||||
case view_dblclick:
|
||||
{
|
||||
const view_mouse_event_t *event = va_arg(va, view_mouse_event_t*);
|
||||
if ( code == view_click )
|
||||
py_view->on_view_click(event);
|
||||
else
|
||||
py_view->on_view_dblclick(event);
|
||||
}
|
||||
break;
|
||||
case view_curpos:
|
||||
py_view->on_view_curpos();
|
||||
break;
|
||||
case view_close:
|
||||
py_view->on_view_close();
|
||||
delete py_view;
|
||||
break;
|
||||
case view_switched:
|
||||
{
|
||||
tcc_renderer_type_t rt = (tcc_renderer_type_t) va_arg(va, int);
|
||||
py_view->on_view_switched(rt);
|
||||
}
|
||||
break;
|
||||
case view_mouse_over:
|
||||
{
|
||||
const view_mouse_event_t *event = va_arg(va, view_mouse_event_t*);
|
||||
py_view->on_view_mouse_over(event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
hook_to_notification_point(HT_VIEW, lambda_t::callback, NULL);
|
||||
installed = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void py_customidamemo_t::set_node_info(
|
||||
PyObject *py_node_idx,
|
||||
PyObject *py_node_info,
|
||||
PyObject *py_flags)
|
||||
{
|
||||
if ( !PyNumber_Check(py_node_idx) || !PyNumber_Check(py_flags) )
|
||||
return;
|
||||
borref_t py_idx(py_node_idx);
|
||||
borref_t py_ni(py_node_info);
|
||||
borref_t py_fl(py_flags);
|
||||
node_info_t ni;
|
||||
convert_node_info(&ni, NULL, py_ni);
|
||||
int idx = PyInt_AsLong(py_idx.o);
|
||||
uint32 flgs = PyLong_AsLong(py_fl.o);
|
||||
viewer_set_node_info(view, idx, ni, flgs);
|
||||
node_info_modified(idx, &ni, flgs);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void py_customidamemo_t::set_nodes_infos(PyObject *dict)
|
||||
{
|
||||
if ( !PyDict_Check(dict) )
|
||||
return;
|
||||
Py_ssize_t pos = 0;
|
||||
PyObject *o_key, *o_value;
|
||||
while ( PyDict_Next(dict, &pos, &o_key, &o_value) )
|
||||
{
|
||||
borref_t key(o_key);
|
||||
borref_t value(o_value);
|
||||
if ( !PyNumber_Check(key.o) )
|
||||
continue;
|
||||
uint32 flags;
|
||||
node_info_t ni;
|
||||
convert_node_info(&ni, &flags, value);
|
||||
int idx = PyInt_AsLong(key.o);
|
||||
viewer_set_node_info(view, idx, ni, flags);
|
||||
node_info_modified(idx, &ni, flags);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *py_customidamemo_t::get_node_info(PyObject *py_node_idx)
|
||||
{
|
||||
if ( !PyNumber_Check(py_node_idx) )
|
||||
Py_RETURN_NONE;
|
||||
node_info_t ni;
|
||||
if ( !viewer_get_node_info(view, &ni, PyInt_AsLong(py_node_idx)) )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("(kkks)", ni.bg_color, ni.frame_color, ni.ea, ni.text.c_str());
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void py_customidamemo_t::del_nodes_infos(PyObject *py_nodes)
|
||||
{
|
||||
if ( !PySequence_Check(py_nodes) )
|
||||
return;
|
||||
Py_ssize_t sz = PySequence_Size(py_nodes);
|
||||
for ( Py_ssize_t i = 0; i < sz; ++i )
|
||||
{
|
||||
newref_t item(PySequence_GetItem(py_nodes, i));
|
||||
if ( !PyNumber_Check(item.o) )
|
||||
continue;
|
||||
int idx = PyInt_AsLong(item.o);
|
||||
viewer_del_node_info(view, idx);
|
||||
node_info_modified(idx, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *py_customidamemo_t::get_current_renderer_type()
|
||||
{
|
||||
tcc_renderer_type_t rt = get_view_renderer_type(view);
|
||||
return PyLong_FromLong(long(rt));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void py_customidamemo_t::set_current_renderer_type(PyObject *py_rto)
|
||||
{
|
||||
tcc_renderer_type_t rt = TCCRT_INVALID;
|
||||
borref_t py_rt(py_rto);
|
||||
if ( PyNumber_Check(py_rt.o) )
|
||||
{
|
||||
rt = tcc_renderer_type_t(PyLong_AsLong(py_rt.o));
|
||||
set_view_renderer_type(view, rt);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *py_customidamemo_t::create_groups(PyObject *_groups_infos)
|
||||
{
|
||||
if ( !PySequence_Check(_groups_infos) )
|
||||
Py_RETURN_NONE;
|
||||
borref_t groups_infos(_groups_infos);
|
||||
groups_crinfos_t gis;
|
||||
Py_ssize_t sz = PySequence_Size(groups_infos.o);
|
||||
for ( Py_ssize_t i = 0; i < sz; ++i )
|
||||
{
|
||||
newref_t item(PySequence_GetItem(groups_infos.o, i));
|
||||
if ( !PyDict_Check(item.o) )
|
||||
continue;
|
||||
borref_t nodes(PyDict_GetItemString(item.o, "nodes"));
|
||||
if ( nodes.o == NULL || !PySequence_Check(nodes.o) )
|
||||
continue;
|
||||
borref_t text(PyDict_GetItemString(item.o, "text"));
|
||||
if ( text.o == NULL || !PyString_Check(text.o) )
|
||||
continue;
|
||||
group_crinfo_t gi;
|
||||
Py_ssize_t nodes_cnt = PySequence_Size(nodes.o);
|
||||
for ( Py_ssize_t k = 0; k < nodes_cnt; ++k )
|
||||
{
|
||||
newref_t node(PySequence_GetItem(nodes.o, k));
|
||||
if ( PyInt_Check(node.o) )
|
||||
gi.nodes.insert(PyInt_AsLong(node.o));
|
||||
}
|
||||
if ( !gi.nodes.empty() )
|
||||
{
|
||||
gi.text = PyString_AsString(text.o);
|
||||
gis.push_back(gi);
|
||||
}
|
||||
}
|
||||
intset_t groups;
|
||||
if ( gis.empty() || !viewer_create_groups(view, &groups, gis) || groups.empty() )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
PyObject *py_groups = PyList_New(0);
|
||||
for ( intset_t::const_iterator it = groups.begin(); it != groups.end(); ++it )
|
||||
PyList_Append(py_groups, PyInt_FromLong(long(*it)));
|
||||
return py_groups;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static void pynodes_to_idanodes(intset_t *idanodes, ref_t pynodes)
|
||||
{
|
||||
Py_ssize_t sz = PySequence_Size(pynodes.o);
|
||||
for ( Py_ssize_t i = 0; i < sz; ++i )
|
||||
{
|
||||
newref_t item(PySequence_GetItem(pynodes.o, i));
|
||||
if ( !PyInt_Check(item.o) )
|
||||
continue;
|
||||
idanodes->insert(PyInt_AsLong(item.o));
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *py_customidamemo_t::delete_groups(PyObject *_groups, PyObject *_new_current)
|
||||
{
|
||||
if ( !PySequence_Check(_groups) || !PyNumber_Check(_new_current) )
|
||||
Py_RETURN_NONE;
|
||||
borref_t groups(_groups);
|
||||
borref_t new_current(_new_current);
|
||||
intset_t ida_groups;
|
||||
pynodes_to_idanodes(&ida_groups, groups);
|
||||
if ( ida_groups.empty() )
|
||||
Py_RETURN_NONE;
|
||||
if ( viewer_delete_groups(view, ida_groups, int(PyInt_AsLong(new_current.o))) )
|
||||
Py_RETURN_TRUE;
|
||||
else
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *py_customidamemo_t::set_groups_visibility(PyObject *_groups, PyObject *_expand, PyObject *_new_current)
|
||||
{
|
||||
if ( !PySequence_Check(_groups)
|
||||
|| !PyBool_Check(_expand)
|
||||
|| !PyNumber_Check(_new_current) )
|
||||
Py_RETURN_NONE;
|
||||
borref_t groups(_groups);
|
||||
borref_t expand(_expand);
|
||||
borref_t new_current(_new_current);
|
||||
intset_t ida_groups;
|
||||
pynodes_to_idanodes(&ida_groups, groups);
|
||||
if ( ida_groups.empty() )
|
||||
Py_RETURN_NONE;
|
||||
if ( viewer_set_groups_visibility(view, ida_groups, expand.o == Py_True, int(PyInt_AsLong(new_current.o))) )
|
||||
Py_RETURN_TRUE;
|
||||
else
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
bool py_customidamemo_t::bind(PyObject *_self, TCustomControl *view)
|
||||
{
|
||||
if ( this->self != NULL || this->view != NULL )
|
||||
return false;
|
||||
PYGLOG("%p: py_customidamemo_t::bind(_self=%p, view=%p)\n", this, _self, view);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
newref_t py_cobj(PyCObject_FromVoidPtr(this, NULL));
|
||||
PyObject_SetAttrString(_self, S_M_THIS, py_cobj.o);
|
||||
|
||||
this->self = borref_t(_self);
|
||||
this->view = view;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void py_customidamemo_t::unbind()
|
||||
{
|
||||
if ( self == NULL )
|
||||
return;
|
||||
PYGLOG("%p: py_customidamemo_t::unbind(); self.o=%p, view=%p\n", this, self.o, view);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t py_cobj(PyCObject_FromVoidPtr(NULL, NULL));
|
||||
PyObject_SetAttrString(self.o, S_M_THIS, py_cobj.o);
|
||||
self = newref_t(NULL);
|
||||
view = NULL;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void py_customidamemo_t::collect_class_callbacks_ids(callbacks_ids_t *out)
|
||||
{
|
||||
out->add(S_ON_VIEW_ACTIVATED, GRBASE_HAVE_VIEW_ACTIVATED);
|
||||
out->add(S_ON_VIEW_DEACTIVATED, GRBASE_HAVE_VIEW_DEACTIVATED);
|
||||
out->add(S_ON_VIEW_KEYDOWN, GRBASE_HAVE_KEYDOWN);
|
||||
out->add(S_ON_POPUP, GRBASE_HAVE_POPUP);
|
||||
out->add(S_ON_VIEW_CLICK, GRBASE_HAVE_VIEW_CLICK);
|
||||
out->add(S_ON_VIEW_DBLCLICK, GRBASE_HAVE_VIEW_DBLCLICK);
|
||||
out->add(S_ON_VIEW_CURPOS, GRBASE_HAVE_VIEW_CURPOS);
|
||||
out->add(S_ON_CLOSE, GRBASE_HAVE_CLOSE);
|
||||
out->add(S_ON_VIEW_SWITCHED, GRBASE_HAVE_VIEW_SWITCHED);
|
||||
out->add(S_ON_VIEW_MOUSE_OVER, GRBASE_HAVE_VIEW_MOUSE_OVER);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
bool py_customidamemo_t::collect_pyobject_callbacks(PyObject *o)
|
||||
{
|
||||
callbacks_ids_t cbids;
|
||||
collect_class_callbacks_ids(&cbids);
|
||||
cb_flags = 0;
|
||||
for ( callbacks_ids_t::const_iterator it = cbids.begin(); it != cbids.end(); ++it )
|
||||
{
|
||||
const callback_id_t &cbid = *it;
|
||||
ref_t attr(PyW_TryGetAttrString(o, cbid.name.c_str()));
|
||||
int have = cbid.have;
|
||||
// Mandatory fields not present?
|
||||
if ( (attr == NULL && have <= 0 )
|
||||
// Mandatory callback fields present but not callable?
|
||||
|| (attr != NULL && have >= 0 && PyCallable_Check(attr.o) == 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ( have > 0 && attr != NULL )
|
||||
cb_flags |= have;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
#define CHK_EVT(flag_needed) \
|
||||
if ( self == NULL || !has_callback(flag_needed) ) \
|
||||
return; \
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE()
|
||||
|
||||
#ifdef PYGDBG_ENABLED
|
||||
#define CHK_RES() PYGLOG("%s: return code: %p\n", __FUNCTION__, result.o)
|
||||
#else
|
||||
#define CHK_RES()
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void py_customidamemo_t::on_view_activated()
|
||||
{
|
||||
CHK_EVT(GRBASE_HAVE_VIEW_ACTIVATED);
|
||||
newref_t result(
|
||||
PyObject_CallMethod(
|
||||
self.o,
|
||||
(char *)S_ON_VIEW_ACTIVATED,
|
||||
NULL));
|
||||
CHK_RES();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void py_customidamemo_t::on_view_deactivated()
|
||||
{
|
||||
CHK_EVT(GRBASE_HAVE_VIEW_DEACTIVATED);
|
||||
newref_t result(
|
||||
PyObject_CallMethod(
|
||||
self.o,
|
||||
(char *)S_ON_VIEW_DEACTIVATED,
|
||||
NULL));
|
||||
CHK_RES();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void py_customidamemo_t::on_view_keydown(int key, int state)
|
||||
{
|
||||
CHK_EVT(GRBASE_HAVE_KEYDOWN);
|
||||
newref_t result(
|
||||
PyObject_CallMethod(
|
||||
self.o,
|
||||
(char *)S_ON_VIEW_KEYDOWN,
|
||||
"ii",
|
||||
key, state));
|
||||
CHK_RES();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void py_customidamemo_t::on_view_popup()
|
||||
{
|
||||
CHK_EVT(GRBASE_HAVE_POPUP);
|
||||
newref_t result(
|
||||
PyObject_CallMethod(
|
||||
self.o,
|
||||
(char *)S_ON_POPUP,
|
||||
NULL));
|
||||
CHK_RES();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void py_customidamemo_t::on_view_click(const view_mouse_event_t *event)
|
||||
{
|
||||
CHK_EVT(GRBASE_HAVE_VIEW_CLICK);
|
||||
newref_t result(
|
||||
PyObject_CallMethod(
|
||||
self.o,
|
||||
(char *)S_ON_VIEW_CLICK,
|
||||
"iii",
|
||||
event->x, event->y, event->state));
|
||||
CHK_RES();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void py_customidamemo_t::on_view_dblclick(const view_mouse_event_t *event)
|
||||
{
|
||||
CHK_EVT(GRBASE_HAVE_VIEW_DBLCLICK);
|
||||
newref_t result(
|
||||
PyObject_CallMethod(
|
||||
self.o,
|
||||
(char *)S_ON_VIEW_DBLCLICK,
|
||||
"iii",
|
||||
event->x, event->y, event->state));
|
||||
CHK_RES();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void py_customidamemo_t::on_view_curpos()
|
||||
{
|
||||
CHK_EVT(GRBASE_HAVE_VIEW_CURPOS);
|
||||
newref_t result(
|
||||
PyObject_CallMethod(
|
||||
self.o,
|
||||
(char *)S_ON_VIEW_CURPOS,
|
||||
NULL));
|
||||
CHK_RES();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void py_customidamemo_t::on_view_close()
|
||||
{
|
||||
CHK_EVT(GRBASE_HAVE_CLOSE);
|
||||
newref_t result(PyObject_CallMethod(self.o, (char *)S_ON_CLOSE, NULL));
|
||||
CHK_RES();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void py_customidamemo_t::on_view_switched(tcc_renderer_type_t rt)
|
||||
{
|
||||
CHK_EVT(GRBASE_HAVE_VIEW_SWITCHED);
|
||||
newref_t result(PyObject_CallMethod(self.o, (char *)S_ON_VIEW_SWITCHED, "i", int(rt)));
|
||||
CHK_RES();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void py_customidamemo_t::on_view_mouse_over(const view_mouse_event_t *event)
|
||||
{
|
||||
CHK_EVT(GRBASE_HAVE_VIEW_MOUSE_OVER);
|
||||
if ( event->rtype == TCCRT_GRAPH || event->rtype == TCCRT_PROXIMITY )
|
||||
{
|
||||
const selection_item_t *item = event->location.item;
|
||||
int icode;
|
||||
ref_t tuple;
|
||||
if ( item != NULL )
|
||||
{
|
||||
if ( item->is_node )
|
||||
{
|
||||
icode = 1;
|
||||
tuple = newref_t(Py_BuildValue("(i)", item->node));
|
||||
}
|
||||
else
|
||||
{
|
||||
icode = 2;
|
||||
tuple = newref_t(Py_BuildValue("(ii)", item->elp.e.src, item->elp.e.dst));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
icode = 0;
|
||||
tuple = newref_t(Py_BuildValue("()"));
|
||||
}
|
||||
newref_t result(PyObject_CallMethod(
|
||||
self.o,
|
||||
(char *)S_ON_VIEW_MOUSE_OVER,
|
||||
"iiiiO",
|
||||
event->x, event->y, event->state, icode, tuple.o));
|
||||
CHK_RES();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#undef CHK_RES
|
||||
#undef CHK_EVT
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
#define GET_THIS() py_customidamemo_t *_this = view_extract_this<py_customidamemo_t>(self)
|
||||
#define CHK_THIS() \
|
||||
GET_THIS(); \
|
||||
if ( _this == NULL ) \
|
||||
return
|
||||
#define CHK_THIS_OR_NONE() \
|
||||
GET_THIS(); \
|
||||
if ( _this == NULL ) \
|
||||
Py_RETURN_NONE
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void pygc_refresh(PyObject *self)
|
||||
{
|
||||
CHK_THIS();
|
||||
_this->refresh();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void pygc_set_node_info(PyObject *self, PyObject *py_node_idx, PyObject *py_node_info, PyObject *py_flags)
|
||||
{
|
||||
CHK_THIS();
|
||||
_this->set_node_info(py_node_idx, py_node_info, py_flags);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void pygc_set_nodes_infos(PyObject *self, PyObject *values)
|
||||
{
|
||||
CHK_THIS();
|
||||
_this->set_nodes_infos(values);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *pygc_get_node_info(PyObject *self, PyObject *py_node_idx)
|
||||
{
|
||||
GET_THIS();
|
||||
if ( _this != NULL )
|
||||
return _this->get_node_info(py_node_idx);
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void pygc_del_nodes_infos(PyObject *self, PyObject *py_nodes)
|
||||
{
|
||||
CHK_THIS();
|
||||
_this->del_nodes_infos(py_nodes);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *pygc_get_current_renderer_type(PyObject *self)
|
||||
{
|
||||
GET_THIS();
|
||||
if ( _this != NULL )
|
||||
return _this->get_current_renderer_type();
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void pygc_set_current_renderer_type(PyObject *self, PyObject *py_rt)
|
||||
{
|
||||
CHK_THIS();
|
||||
_this->set_current_renderer_type(py_rt);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *pygc_create_groups(PyObject *self, PyObject *groups_infos)
|
||||
{
|
||||
CHK_THIS_OR_NONE();
|
||||
return _this->create_groups(groups_infos);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *pygc_delete_groups(PyObject *self, PyObject *groups, PyObject *new_current)
|
||||
{
|
||||
CHK_THIS_OR_NONE();
|
||||
return _this->delete_groups(groups, new_current);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *pygc_set_groups_visibility(PyObject *self, PyObject *groups, PyObject *expand, PyObject *new_current)
|
||||
{
|
||||
CHK_THIS_OR_NONE();
|
||||
return _this->set_groups_visibility(groups, expand, new_current);
|
||||
}
|
||||
|
||||
#undef CHK_THIS_OR_NONE
|
||||
#undef CHK_THIS
|
||||
#undef GET_THIS
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
lookup_info_t py_customidamemo_t::lookup_info;
|
||||
//</code(py_view_base)>
|
||||
|
||||
//<inline(py_view_base)>
|
||||
void pygc_refresh(PyObject *self);
|
||||
void pygc_set_node_info(PyObject *self, PyObject *py_node_idx, PyObject *py_node_info, PyObject *py_flags);
|
||||
void pygc_set_nodes_infos(PyObject *self, PyObject *values);
|
||||
PyObject *pygc_get_node_info(PyObject *self, PyObject *py_node_idx);
|
||||
void pygc_del_nodes_infos(PyObject *self, PyObject *py_nodes);
|
||||
PyObject *pygc_get_current_renderer_type(PyObject *self);
|
||||
void pygc_set_current_renderer_type(PyObject *self, PyObject *py_rt);
|
||||
PyObject *pygc_create_groups(PyObject *self, PyObject *groups_infos);
|
||||
PyObject *pygc_delete_groups(PyObject *self, PyObject *groups, PyObject *new_current);
|
||||
PyObject *pygc_set_groups_visibility(PyObject *self, PyObject *groups, PyObject *expand, PyObject *new_current);
|
||||
//</inline(py_view_base)>
|
||||
|
||||
|
||||
|
||||
#endif // __PY_VIEW_BASE__
|
||||
|
107
pywraps/py_view_base.py
Normal file
107
pywraps/py_view_base.py
Normal file
@ -0,0 +1,107 @@
|
||||
|
||||
#<pycode(py_view_base)>
|
||||
class CustomIDAMemo(object):
|
||||
def Refresh(self):
|
||||
"""
|
||||
Refreshes the graph. This causes the OnRefresh() to be called
|
||||
"""
|
||||
_idaapi.pygc_refresh(self)
|
||||
|
||||
def GetCurrentRendererType(self):
|
||||
return _idaapi.pygc_get_current_renderer_type(self)
|
||||
|
||||
def SetCurrentRendererType(self, rtype):
|
||||
"""
|
||||
Set the current view's renderer.
|
||||
|
||||
@param rtype: The renderer type. Should be one of the idaapi.TCCRT_* values.
|
||||
"""
|
||||
_idaapi.pygc_set_current_renderer_type(self, rtype)
|
||||
|
||||
def SetNodeInfo(self, node_index, node_info, flags):
|
||||
"""
|
||||
Set the properties for the given node.
|
||||
|
||||
Example usage (set second nodes's bg color to red):
|
||||
inst = ...
|
||||
p = idaapi.node_info_t()
|
||||
p.bg_color = 0x00ff0000
|
||||
inst.SetNodeInfo(1, p, idaapi.NIF_BG_COLOR)
|
||||
|
||||
@param node_index: The node index.
|
||||
@param node_info: An idaapi.node_info_t instance.
|
||||
@param flags: An OR'ed value of NIF_* values.
|
||||
"""
|
||||
_idaapi.pygc_set_node_info(self, node_index, node_info, flags)
|
||||
|
||||
def SetNodesInfos(self, values):
|
||||
"""
|
||||
Set the properties for the given nodes.
|
||||
|
||||
Example usage (set first three nodes's bg color to purple):
|
||||
inst = ...
|
||||
p = idaapi.node_info_t()
|
||||
p.bg_color = 0x00ff00ff
|
||||
inst.SetNodesInfos({0 : p, 1 : p, 2 : p})
|
||||
|
||||
@param values: A dictionary of 'int -> node_info_t' objects.
|
||||
"""
|
||||
_idaapi.pygc_set_nodes_infos(self, values)
|
||||
|
||||
def GetNodeInfo(self, node):
|
||||
"""
|
||||
Get the properties for the given node.
|
||||
|
||||
@param node: The index of the node.
|
||||
@return: A tuple (bg_color, frame_color, ea, text), or None.
|
||||
"""
|
||||
return _idaapi.pygc_get_node_info(self, node)
|
||||
|
||||
def DelNodesInfos(self, *nodes):
|
||||
"""
|
||||
Delete the properties for the given node(s).
|
||||
|
||||
@param nodes: A list of node IDs
|
||||
"""
|
||||
return _idaapi.pygc_del_nodes_infos(self, nodes)
|
||||
|
||||
def CreateGroups(self, groups_infos):
|
||||
"""
|
||||
Send a request to modify the graph by creating a
|
||||
(set of) group(s), and perform an animation.
|
||||
|
||||
Each object in the 'groups_infos' list must be of the format:
|
||||
{
|
||||
"nodes" : [<int>, <int>, <int>, ...] # The list of nodes to group
|
||||
"text" : <string> # The synthetic text for that group
|
||||
}
|
||||
|
||||
@param groups_infos: A list of objects that describe those groups.
|
||||
@return: A [<int>, <int>, ...] list of group nodes, or None (failure).
|
||||
"""
|
||||
return _idaapi.pygc_create_groups(self, groups_infos)
|
||||
|
||||
def DeleteGroups(self, groups, new_current = -1):
|
||||
"""
|
||||
Send a request to delete the specified groups in the graph,
|
||||
and perform an animation.
|
||||
|
||||
@param groups: A list of group node numbers.
|
||||
@param new_current: A node to focus on after the groups have been deleted
|
||||
@return: True on success, False otherwise.
|
||||
"""
|
||||
return _idaapi.pygc_delete_groups(self, groups, new_current)
|
||||
|
||||
def SetGroupsVisibility(self, groups, expand, new_current = -1):
|
||||
"""
|
||||
Send a request to expand/collapse the specified groups in the graph,
|
||||
and perform an animation.
|
||||
|
||||
@param groups: A list of group node numbers.
|
||||
@param expand: True to expand the group, False otherwise.
|
||||
@param new_current: A node to focus on after the groups have been expanded/collapsed.
|
||||
@return: True on success, False otherwise.
|
||||
"""
|
||||
return _idaapi.pygc_set_groups_visibility(self, groups, expand, new_current)
|
||||
|
||||
#</pycode(py_view_base)>
|
@ -90,6 +90,10 @@ class processor_t(object):
|
||||
# ----------------------------------------------------------------------
|
||||
BADADDR = 0xFFFFFFFFFFFFFFFFL
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
UA_MAXOP = 6
|
||||
o_last = 14
|
||||
o_void = 0
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
"""
|
||||
|
18
swig/area.i
18
swig/area.i
@ -1,27 +1,17 @@
|
||||
%ignore sarray;
|
||||
%ignore lastreq_t;
|
||||
%ignore AREA_CACHE_SIZE;
|
||||
%ignore ANODE;
|
||||
%ignore ANODE2;
|
||||
%ignore AREA_LONG_COMMENT_TAG;
|
||||
%ignore area_visitor_t;
|
||||
%ignore areacb_t_link_dont_load;
|
||||
%ignore add_area_from_cache;
|
||||
%ignore areacb_t_valid_push_back;
|
||||
|
||||
// Ignore the private members in areacb_t
|
||||
%ignore areacb_t::areasCode;
|
||||
%ignore areacb_t::infosize;
|
||||
%ignore areacb_t::lastreq;
|
||||
%ignore areacb_t::reserved;
|
||||
%ignore areacb_t::sa;
|
||||
%ignore areacb_t::cache;
|
||||
%ignore areacb_t::allocate;
|
||||
%ignore areacb_t::search;
|
||||
%ignore areacb_t::readArea;
|
||||
%ignore areacb_t::findCache;
|
||||
%ignore areacb_t::addCache;
|
||||
%ignore areacb_t::delCache;
|
||||
%ignore areacb_t::free_cache;
|
||||
%ignore areacb_t::find_nth_start;
|
||||
%ignore areacb_t::build_optimizer;
|
||||
%ignore areacb_t::areas;
|
||||
%ignore areacb_t::move_area_comment;
|
||||
%ignore areacb_t::pack_and_write_area;
|
||||
%ignore areacb_t::move_away;
|
||||
|
289
swig/bytes.i
289
swig/bytes.i
@ -102,20 +102,17 @@
|
||||
//------------------------------------------------------------------------
|
||||
static bool idaapi py_testf_cb(flags_t flags, void *ud)
|
||||
{
|
||||
PyObject *py_flags = PyLong_FromUnsignedLong(flags);
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *result = PyObject_CallFunctionObjArgs((PyObject *) ud, py_flags, NULL);
|
||||
PYW_GIL_RELEASE;
|
||||
bool ret = result != NULL && PyObject_IsTrue(result);
|
||||
Py_XDECREF(result);
|
||||
Py_XDECREF(py_flags);
|
||||
return ret;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t py_flags(PyLong_FromUnsignedLong(flags));
|
||||
newref_t result(PyObject_CallFunctionObjArgs((PyObject *) ud, py_flags.o, NULL));
|
||||
return result != NULL && PyObject_IsTrue(result.o);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Wraps the (next|prev)that()
|
||||
static ea_t py_npthat(ea_t ea, ea_t bound, PyObject *py_callable, bool next)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyCallable_Check(py_callable) )
|
||||
return BADADDR;
|
||||
else
|
||||
@ -130,20 +127,17 @@ static int idaapi py_visit_patched_bytes_cb(
|
||||
uint32 v,
|
||||
void *ud)
|
||||
{
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallFunction(
|
||||
(PyObject *)ud,
|
||||
PY_FMT64 "iII",
|
||||
pyul_t(ea),
|
||||
fpos,
|
||||
o,
|
||||
v);
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t py_result(
|
||||
PyObject_CallFunction(
|
||||
(PyObject *)ud,
|
||||
PY_FMT64 "iII",
|
||||
pyul_t(ea),
|
||||
fpos,
|
||||
o,
|
||||
v));
|
||||
PyW_ShowCbErr("visit_patched_bytes");
|
||||
int ret = (py_result != NULL && PyInt_Check(py_result)) ? PyInt_AsLong(py_result) : 0;
|
||||
Py_XDECREF(py_result);
|
||||
return ret;
|
||||
return (py_result != NULL && PyInt_Check(py_result.o)) ? PyInt_AsLong(py_result.o) : 0;
|
||||
}
|
||||
|
||||
|
||||
@ -163,20 +157,18 @@ class py_custom_data_type_t
|
||||
size_t nbytes) // size of the future item
|
||||
{
|
||||
py_custom_data_type_t *_this = (py_custom_data_type_t *)ud;
|
||||
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_MAY_CREATE_AT,
|
||||
PY_FMT64 PY_FMT64,
|
||||
pyul_t(ea),
|
||||
pyul_t(nbytes));
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
PYW_GIL_GET;
|
||||
newref_t py_result(
|
||||
PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_MAY_CREATE_AT,
|
||||
PY_FMT64 PY_FMT64,
|
||||
pyul_t(ea),
|
||||
pyul_t(nbytes)));
|
||||
|
||||
PyW_ShowCbErr(S_MAY_CREATE_AT);
|
||||
bool ok = py_result != NULL && PyObject_IsTrue(py_result);
|
||||
Py_XDECREF(py_result);
|
||||
return ok;
|
||||
return py_result != NULL && PyObject_IsTrue(py_result.o);
|
||||
}
|
||||
|
||||
// !=NULL means variable size datatype
|
||||
@ -187,24 +179,23 @@ class py_custom_data_type_t
|
||||
ea_t ea, // address of the item
|
||||
asize_t maxsize) // maximal size of the item
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
// Returns: 0-no such item can be created/displayed
|
||||
// this callback is required only for varsize datatypes
|
||||
py_custom_data_type_t *_this = (py_custom_data_type_t *)ud;
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_CALC_ITEM_SIZE,
|
||||
PY_FMT64 PY_FMT64,
|
||||
pyul_t(ea),
|
||||
pyul_t(maxsize));
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
newref_t py_result(
|
||||
PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_CALC_ITEM_SIZE,
|
||||
PY_FMT64 PY_FMT64,
|
||||
pyul_t(ea),
|
||||
pyul_t(maxsize)));
|
||||
|
||||
if ( PyW_ShowCbErr(S_CALC_ITEM_SIZE) || py_result == NULL )
|
||||
return 0;
|
||||
|
||||
|
||||
uint64 num = 0;
|
||||
PyW_GetNumber(py_result, &num);
|
||||
Py_XDECREF(py_result);
|
||||
PyW_GetNumber(py_result.o, &num);
|
||||
return asize_t(num);
|
||||
}
|
||||
|
||||
@ -222,6 +213,8 @@ public:
|
||||
|
||||
int register_dt(PyObject *py_obj)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
// Already registered?
|
||||
if ( dtid >= 0 )
|
||||
return dtid;
|
||||
@ -230,9 +223,10 @@ public:
|
||||
dt.cbsize = sizeof(dt);
|
||||
dt.ud = this;
|
||||
|
||||
PyObject *py_attr = NULL;
|
||||
do
|
||||
{
|
||||
ref_t py_attr;
|
||||
|
||||
// name
|
||||
if ( !PyW_GetStringAttr(py_obj, S_NAME, &dt_name) )
|
||||
break;
|
||||
@ -253,30 +247,27 @@ public:
|
||||
|
||||
// value_size
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_VALUE_SIZE);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr) )
|
||||
dt.value_size = PyInt_AsLong(py_attr);
|
||||
Py_XDECREF(py_attr);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr.o) )
|
||||
dt.value_size = PyInt_AsLong(py_attr.o);
|
||||
py_attr = ref_t();
|
||||
|
||||
// props
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_PROPS);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr) )
|
||||
dt.props = PyInt_AsLong(py_attr);
|
||||
Py_XDECREF(py_attr);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr.o) )
|
||||
dt.props = PyInt_AsLong(py_attr.o);
|
||||
py_attr = ref_t();
|
||||
|
||||
// may_create_at
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_MAY_CREATE_AT);
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr) )
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr.o) )
|
||||
dt.may_create_at = s_may_create_at;
|
||||
Py_XDECREF(py_attr);
|
||||
py_attr = ref_t();
|
||||
|
||||
// calc_item_size
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_CALC_ITEM_SIZE);
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr) )
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr.o) )
|
||||
dt.calc_item_size = s_calc_item_size;
|
||||
Py_XDECREF(py_attr);
|
||||
|
||||
// Clear attribute
|
||||
py_attr = NULL;
|
||||
py_attr = ref_t();
|
||||
|
||||
// Now try to register
|
||||
dtid = register_custom_data_type(&dt);
|
||||
@ -287,20 +278,16 @@ public:
|
||||
Py_INCREF(py_obj);
|
||||
py_self = py_obj;
|
||||
|
||||
py_attr = PyInt_FromLong(dtid);
|
||||
PyObject_SetAttrString(py_obj, S_ID, py_attr);
|
||||
Py_DECREF(py_attr);
|
||||
|
||||
// Done with attribute
|
||||
py_attr = NULL;
|
||||
py_attr = newref_t(PyInt_FromLong(dtid));
|
||||
PyObject_SetAttrString(py_obj, S_ID, py_attr.o);
|
||||
} while ( false );
|
||||
|
||||
Py_XDECREF(py_attr);
|
||||
return dtid;
|
||||
}
|
||||
|
||||
bool unregister_dt()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
if ( dtid < 0 )
|
||||
return true;
|
||||
|
||||
@ -340,44 +327,41 @@ private:
|
||||
int operand_num, // current operand number
|
||||
int dtid) // custom data type id
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
|
||||
// Build a string from the buffer
|
||||
PyObject *py_value = PyString_FromStringAndSize(
|
||||
(const char *)value,
|
||||
Py_ssize_t(size));
|
||||
newref_t py_value(PyString_FromStringAndSize(
|
||||
(const char *)value,
|
||||
Py_ssize_t(size)));
|
||||
if ( py_value == NULL )
|
||||
return false;
|
||||
|
||||
py_custom_data_format_t *_this = (py_custom_data_format_t *) ud;
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_PRINTF,
|
||||
"O" PY_FMT64 "ii",
|
||||
py_value,
|
||||
pyul_t(current_ea),
|
||||
operand_num,
|
||||
dtid);
|
||||
PYW_GIL_RELEASE;
|
||||
// Done with the string
|
||||
Py_DECREF(py_value);
|
||||
newref_t py_result(PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_PRINTF,
|
||||
"O" PY_FMT64 "ii",
|
||||
py_value.o,
|
||||
pyul_t(current_ea),
|
||||
operand_num,
|
||||
dtid));
|
||||
|
||||
// Error while calling the function?
|
||||
if ( PyW_ShowCbErr(S_PRINTF) || py_result == NULL )
|
||||
return false;
|
||||
|
||||
bool ok = false;
|
||||
if ( PyString_Check(py_result) )
|
||||
if ( PyString_Check(py_result.o) )
|
||||
{
|
||||
Py_ssize_t len;
|
||||
char *buf;
|
||||
if ( out != NULL && PyString_AsStringAndSize(py_result, &buf, &len) != -1 )
|
||||
if ( out != NULL && PyString_AsStringAndSize(py_result.o, &buf, &len) != -1 )
|
||||
{
|
||||
out->qclear();
|
||||
out->append(buf, len);
|
||||
}
|
||||
ok = true;
|
||||
}
|
||||
Py_DECREF(py_result);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -389,16 +373,17 @@ private:
|
||||
int operand_num, // current operand number (-1 if unknown)
|
||||
qstring *errstr) // buffer for error message
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
|
||||
py_custom_data_format_t *_this = (py_custom_data_format_t *) ud;
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_SCAN,
|
||||
"s" PY_FMT64,
|
||||
input,
|
||||
pyul_t(current_ea),
|
||||
operand_num);
|
||||
PYW_GIL_RELEASE;
|
||||
newref_t py_result(
|
||||
PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_SCAN,
|
||||
"s" PY_FMT64,
|
||||
input,
|
||||
pyul_t(current_ea),
|
||||
operand_num));
|
||||
|
||||
// Error while calling the function?
|
||||
if ( PyW_ShowCbErr(S_SCAN) || py_result == NULL)
|
||||
@ -408,15 +393,14 @@ private:
|
||||
do
|
||||
{
|
||||
// We expect a tuple(bool, string|None)
|
||||
if ( !PyTuple_Check(py_result) || PyTuple_Size(py_result) != 2 )
|
||||
if ( !PyTuple_Check(py_result.o) || PyTuple_Size(py_result.o) != 2 )
|
||||
break;
|
||||
|
||||
// Borrow references
|
||||
PyObject *py_bool = PyTuple_GetItem(py_result, 0);
|
||||
PyObject *py_val = PyTuple_GetItem(py_result, 1);
|
||||
borref_t py_bool(PyTuple_GetItem(py_result.o, 0));
|
||||
borref_t py_val(PyTuple_GetItem(py_result.o, 1));
|
||||
|
||||
// Get return code from Python
|
||||
ok = PyObject_IsTrue(py_bool);
|
||||
ok = PyObject_IsTrue(py_bool.o);
|
||||
|
||||
// We expect None or the value (depending on probe)
|
||||
if ( ok )
|
||||
@ -427,7 +411,7 @@ private:
|
||||
|
||||
Py_ssize_t len;
|
||||
char *buf;
|
||||
if ( PyString_AsStringAndSize(py_val, &buf, &len) != -1 )
|
||||
if ( PyString_AsStringAndSize(py_val.o, &buf, &len) != -1 )
|
||||
{
|
||||
value->qclear();
|
||||
value->append(buf, len);
|
||||
@ -437,16 +421,15 @@ private:
|
||||
else
|
||||
{
|
||||
// Make sure the user returned (False, String)
|
||||
if ( py_bool != Py_False || !PyString_Check(py_val) )
|
||||
if ( py_bool.o != Py_False || !PyString_Check(py_val.o) )
|
||||
{
|
||||
*errstr = "Invalid return value returned from the Python callback!";
|
||||
break;
|
||||
}
|
||||
// Get the error message
|
||||
*errstr = PyString_AsString(py_val);
|
||||
*errstr = PyString_AsString(py_val.o);
|
||||
}
|
||||
} while ( false );
|
||||
Py_DECREF(py_result);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -458,19 +441,18 @@ private:
|
||||
// xrefs from the current item.
|
||||
// this callback may be missing.
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
|
||||
py_custom_data_format_t *_this = (py_custom_data_format_t *) ud;
|
||||
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_ANALYZE,
|
||||
PY_FMT64 "i",
|
||||
pyul_t(current_ea),
|
||||
operand_num);
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
newref_t py_result(
|
||||
PyObject_CallMethod(
|
||||
_this->py_self,
|
||||
(char *)S_ANALYZE,
|
||||
PY_FMT64 "i",
|
||||
pyul_t(current_ea),
|
||||
operand_num));
|
||||
|
||||
PyW_ShowCbErr(S_ANALYZE);
|
||||
Py_XDECREF(py_result);
|
||||
}
|
||||
public:
|
||||
py_custom_data_format_t()
|
||||
@ -479,9 +461,9 @@ public:
|
||||
py_self = NULL;
|
||||
}
|
||||
|
||||
const char *get_name() const
|
||||
{
|
||||
return df_name.c_str();
|
||||
const char *get_name() const
|
||||
{
|
||||
return df_name.c_str();
|
||||
}
|
||||
|
||||
int register_df(int dtid, PyObject *py_obj)
|
||||
@ -493,10 +475,12 @@ public:
|
||||
memset(&df, 0, sizeof(df));
|
||||
df.cbsize = sizeof(df);
|
||||
df.ud = this;
|
||||
PyObject *py_attr = NULL;
|
||||
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
do
|
||||
{
|
||||
ref_t py_attr;
|
||||
|
||||
// name
|
||||
if ( !PyW_GetStringAttr(py_obj, S_NAME, &df_name) )
|
||||
break;
|
||||
@ -508,9 +492,8 @@ public:
|
||||
|
||||
// props
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_PROPS);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr) )
|
||||
df.props = PyInt_AsLong(py_attr);
|
||||
Py_XDECREF(py_attr);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr.o) )
|
||||
df.props = PyInt_AsLong(py_attr.o);
|
||||
|
||||
// hotkey
|
||||
if ( PyW_GetStringAttr(py_obj, S_HOTKEY, &df_hotkey) )
|
||||
@ -518,36 +501,28 @@ public:
|
||||
|
||||
// value_size
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_VALUE_SIZE);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr) )
|
||||
df.value_size = PyInt_AsLong(py_attr);
|
||||
Py_XDECREF(py_attr);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr.o) )
|
||||
df.value_size = PyInt_AsLong(py_attr.o);
|
||||
|
||||
// text_width
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_TEXT_WIDTH);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr) )
|
||||
df.text_width = PyInt_AsLong(py_attr);
|
||||
Py_XDECREF(py_attr);
|
||||
if ( py_attr != NULL && PyInt_Check(py_attr.o) )
|
||||
df.text_width = PyInt_AsLong(py_attr.o);
|
||||
|
||||
// print cb
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_PRINTF);
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr) )
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr.o) )
|
||||
df.print = s_print;
|
||||
Py_XDECREF(py_attr);
|
||||
|
||||
// scan cb
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_SCAN);
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr) )
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr.o) )
|
||||
df.scan = s_scan;
|
||||
Py_XDECREF(py_attr);
|
||||
|
||||
// analyze cb
|
||||
py_attr = PyW_TryGetAttrString(py_obj, S_ANALYZE);
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr) )
|
||||
if ( py_attr != NULL && PyCallable_Check(py_attr.o) )
|
||||
df.analyze = s_analyze;
|
||||
Py_XDECREF(py_attr);
|
||||
|
||||
// Done with attribute
|
||||
py_attr = NULL;
|
||||
|
||||
// Now try to register
|
||||
dfid = register_custom_data_format(dtid, &df);
|
||||
@ -559,19 +534,16 @@ public:
|
||||
py_self = py_obj;
|
||||
|
||||
// Update the format ID
|
||||
py_attr = PyInt_FromLong(dfid);
|
||||
PyObject_SetAttrString(py_obj, S_ID, py_attr);
|
||||
Py_DECREF(py_attr);
|
||||
|
||||
py_attr = NULL;
|
||||
py_attr = newref_t(PyInt_FromLong(dfid));
|
||||
PyObject_SetAttrString(py_obj, S_ID, py_attr.o);
|
||||
} while ( false );
|
||||
|
||||
Py_XDECREF(py_attr);
|
||||
return dfid;
|
||||
}
|
||||
|
||||
bool unregister_df(int dtid)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
// Never registered?
|
||||
if ( dfid < 0 )
|
||||
return true;
|
||||
@ -635,6 +607,8 @@ static py_custom_data_format_list_t py_df_list;
|
||||
//------------------------------------------------------------------------
|
||||
static PyObject *py_data_type_to_py_dict(const data_type_t *dt)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
return Py_BuildValue("{s:" PY_FMT64 ",s:i,s:i,s:s,s:s,s:s,s:s}",
|
||||
S_VALUE_SIZE, pyul_t(dt->value_size),
|
||||
S_PROPS, dt->props,
|
||||
@ -648,6 +622,8 @@ static PyObject *py_data_type_to_py_dict(const data_type_t *dt)
|
||||
//------------------------------------------------------------------------
|
||||
static PyObject *py_data_format_to_py_dict(const data_format_t *df)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
return Py_BuildValue("{s:i,s:i,s:i,s:" PY_FMT64 ",s:s,s:s,s:s}",
|
||||
S_PROPS, df->props,
|
||||
S_CBSIZE, df->cbsize,
|
||||
@ -684,6 +660,7 @@ def visit_patched_bytes(ea1, ea2, callable):
|
||||
*/
|
||||
static int py_visit_patched_bytes(ea_t ea1, ea_t ea2, PyObject *py_callable)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyCallable_Check(py_callable) )
|
||||
return 0;
|
||||
else
|
||||
@ -732,29 +709,23 @@ def get_many_bytes(ea, size):
|
||||
*/
|
||||
static PyObject *py_get_many_bytes(ea_t ea, unsigned int size)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
do
|
||||
{
|
||||
if ( size <= 0 )
|
||||
break;
|
||||
|
||||
// Allocate memory via Python
|
||||
PyObject *py_buf = PyString_FromStringAndSize(NULL, Py_ssize_t(size));
|
||||
newref_t py_buf(PyString_FromStringAndSize(NULL, Py_ssize_t(size)));
|
||||
if ( py_buf == NULL )
|
||||
break;
|
||||
|
||||
// Read bytes
|
||||
bool ok = get_many_bytes(ea, PyString_AsString(py_buf), size);
|
||||
if ( !get_many_bytes(ea, PyString_AsString(py_buf.o), size) )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
// If failed, dispose the Python string
|
||||
if ( !ok )
|
||||
{
|
||||
Py_DECREF(py_buf);
|
||||
|
||||
py_buf = Py_None;
|
||||
Py_INCREF(py_buf);
|
||||
}
|
||||
|
||||
return py_buf;
|
||||
py_buf.incref();
|
||||
return py_buf.o;
|
||||
} while ( false );
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
@ -805,9 +776,11 @@ static PyObject *py_get_ascii_contents2(
|
||||
}
|
||||
if ( type == ASCSTR_C && used_size > 0 && buf[used_size-1] == '\0' )
|
||||
used_size--;
|
||||
PyObject *py_buf = PyString_FromStringAndSize((const char *)buf, used_size);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t py_buf(PyString_FromStringAndSize((const char *)buf, used_size));
|
||||
qfree(buf);
|
||||
return py_buf;
|
||||
py_buf.incref();
|
||||
return py_buf.o;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
/*
|
||||
@ -987,6 +960,7 @@ def get_custom_data_format(dtid, dfid):
|
||||
// Get definition of a registered custom data format and returns a dictionary
|
||||
static PyObject *py_get_custom_data_format(int dtid, int fid)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
const data_format_t *df = get_custom_data_format(dtid, fid);
|
||||
if ( df == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -1007,6 +981,7 @@ def get_custom_data_type(dtid):
|
||||
// Get definition of a registered custom data format and returns a dictionary
|
||||
static PyObject *py_get_custom_data_type(int dtid)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
const data_type_t *dt = get_custom_data_type(dtid);
|
||||
if ( dt == NULL )
|
||||
Py_RETURN_NONE;
|
||||
|
54
swig/dbg.i
54
swig/dbg.i
@ -25,7 +25,14 @@ typedef struct
|
||||
%rename (get_manual_regions) py_get_manual_regions;
|
||||
%ignore set_manual_regions;
|
||||
%ignore inform_idc_about_debthread;
|
||||
%ignore is_dbgmem_valid;
|
||||
// We want ALL wrappers around what is declared in dbg.hpp
|
||||
// to release the GIL when calling into the IDA api: those
|
||||
// might be very long operations, that even require some
|
||||
// network traffic.
|
||||
%thread;
|
||||
%include "dbg.hpp"
|
||||
%nothread;
|
||||
%ignore DBG_Callback;
|
||||
%feature("director") DBG_Hooks;
|
||||
|
||||
@ -112,6 +119,7 @@ static PyObject *refresh_debugger_memory()
|
||||
// Invalidate the cache
|
||||
isEnabled(0);
|
||||
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
@ -119,74 +127,78 @@ int idaapi DBG_Callback(void *ud, int notification_code, va_list va);
|
||||
class DBG_Hooks
|
||||
{
|
||||
public:
|
||||
virtual ~DBG_Hooks() { unhook(); };
|
||||
virtual ~DBG_Hooks() { unhook(); }
|
||||
|
||||
bool hook() { return hook_to_notification_point(HT_DBG, DBG_Callback, this); };
|
||||
bool unhook() { return unhook_from_notification_point(HT_DBG, DBG_Callback, this); };
|
||||
bool hook() { return hook_to_notification_point(HT_DBG, DBG_Callback, this); }
|
||||
bool unhook() { return unhook_from_notification_point(HT_DBG, DBG_Callback, this); }
|
||||
/* Hook functions to be overridden in Python */
|
||||
virtual void dbg_process_start(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea,
|
||||
char *name,
|
||||
ea_t base,
|
||||
asize_t size) { };
|
||||
asize_t size) {}
|
||||
virtual void dbg_process_exit(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea,
|
||||
int exit_code) { };
|
||||
int exit_code) {}
|
||||
virtual void dbg_process_attach(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea,
|
||||
char *name,
|
||||
ea_t base,
|
||||
asize_t size) { };
|
||||
asize_t size) {}
|
||||
virtual void dbg_process_detach(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea) { };
|
||||
ea_t ea) {}
|
||||
virtual void dbg_thread_start(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea) { };
|
||||
ea_t ea) {}
|
||||
virtual void dbg_thread_exit(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea,
|
||||
int exit_code) { };
|
||||
int exit_code) {}
|
||||
virtual void dbg_library_load(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea,
|
||||
char *name,
|
||||
ea_t base,
|
||||
asize_t size) { };
|
||||
asize_t size) {}
|
||||
virtual void dbg_library_unload(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea,
|
||||
char *libname) { };
|
||||
char *libname) {}
|
||||
virtual void dbg_information(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea,
|
||||
char *info) { };
|
||||
char *info) {}
|
||||
virtual int dbg_exception(pid_t pid,
|
||||
thid_t tid,
|
||||
ea_t ea,
|
||||
int code,
|
||||
bool can_cont,
|
||||
ea_t exc_ea,
|
||||
char *info) { return 0; };
|
||||
virtual void dbg_suspend_process(void) { };
|
||||
virtual int dbg_bpt(thid_t tid, ea_t breakpoint_ea) { return 0; };
|
||||
virtual int dbg_trace(thid_t tid, ea_t ip) { return 0; };
|
||||
char *info) { return 0; }
|
||||
virtual void dbg_suspend_process(void) {}
|
||||
virtual int dbg_bpt(thid_t tid, ea_t breakpoint_ea) { return 0; }
|
||||
virtual int dbg_trace(thid_t tid, ea_t ip) { return 0; }
|
||||
virtual void dbg_request_error(int failed_command,
|
||||
int failed_dbg_notification) { };
|
||||
virtual void dbg_step_into(void) { };
|
||||
virtual void dbg_step_over(void) { };
|
||||
virtual void dbg_run_to(pid_t pid, thid_t tid, ea_t ea) { };
|
||||
virtual void dbg_step_until_ret(void) { };
|
||||
int failed_dbg_notification) {}
|
||||
virtual void dbg_step_into(void) {}
|
||||
virtual void dbg_step_over(void) {}
|
||||
virtual void dbg_run_to(pid_t pid, thid_t tid, ea_t ea) {}
|
||||
virtual void dbg_step_until_ret(void) {}
|
||||
};
|
||||
|
||||
int idaapi DBG_Callback(void *ud, int notification_code, va_list va)
|
||||
{
|
||||
// This hook gets called from the kernel. Ensure we hold the GIL.
|
||||
PYW_GIL_GET;
|
||||
|
||||
class DBG_Hooks *proxy = (class DBG_Hooks *)ud;
|
||||
debug_event_t *event;
|
||||
int code = 0;
|
||||
|
||||
try
|
||||
{
|
||||
switch (notification_code)
|
||||
|
144
swig/diskio.i
144
swig/diskio.i
@ -49,17 +49,17 @@
|
||||
//--------------------------------------------------------------------------
|
||||
int idaapi py_enumerate_files_cb(const char *file, void *ud)
|
||||
{
|
||||
PyObject *py_file = PyString_FromString(file);
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_ret = PyObject_CallFunctionObjArgs(
|
||||
(PyObject *)ud,
|
||||
py_file,
|
||||
NULL);
|
||||
PYW_GIL_RELEASE;
|
||||
int r = (py_ret == NULL || !PyNumber_Check(py_ret)) ? 1 /* stop enumeration on failure */ : PyInt_AsLong(py_ret);
|
||||
Py_XDECREF(py_file);
|
||||
Py_XDECREF(py_ret);
|
||||
return r;
|
||||
// No need to 'PYW_GIL_GET' here, as this is called synchronously
|
||||
// and from the same thread as the one that executes
|
||||
// 'py_enumerate_files'.
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t py_file(PyString_FromString(file));
|
||||
newref_t py_ret(
|
||||
PyObject_CallFunctionObjArgs(
|
||||
(PyObject *)ud,
|
||||
py_file.o,
|
||||
NULL));
|
||||
return (py_ret == NULL || !PyNumber_Check(py_ret.o)) ? 1 /* stop enum on failure */ : PyInt_AsLong(py_ret.o);
|
||||
}
|
||||
//</code(py_diskio)>
|
||||
%}
|
||||
@ -173,6 +173,7 @@ private:
|
||||
//--------------------------------------------------------------------------
|
||||
void _from_cobject(PyObject *pycobject)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
this->set_linput((linput_t *)PyCObject_AsVoidPtr(pycobject));
|
||||
}
|
||||
|
||||
@ -196,6 +197,7 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
loader_input_t(PyObject *pycobject = NULL): li(NULL), own(OWN_NONE), __idc_cvt_id__(PY_ICID_OPAQUE)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( pycobject != NULL && PyCObject_Check(pycobject) )
|
||||
_from_cobject(pycobject);
|
||||
}
|
||||
@ -206,11 +208,13 @@ public:
|
||||
if ( li == NULL )
|
||||
return;
|
||||
|
||||
PYW_GIL_GET;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
if ( own == OWN_CREATE )
|
||||
close_linput(li);
|
||||
else if ( own == OWN_FROM_FP )
|
||||
unmake_linput(li);
|
||||
|
||||
Py_END_ALLOW_THREADS;
|
||||
li = NULL;
|
||||
own = OWN_NONE;
|
||||
}
|
||||
@ -225,14 +229,17 @@ public:
|
||||
bool open(const char *filename, bool remote = false)
|
||||
{
|
||||
close();
|
||||
PYW_GIL_GET;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
li = open_linput(filename, remote);
|
||||
if ( li == NULL )
|
||||
return false;
|
||||
|
||||
// Save file name
|
||||
fn = filename;
|
||||
own = OWN_CREATE;
|
||||
return true;
|
||||
if ( li != NULL )
|
||||
{
|
||||
// Save file name
|
||||
fn = filename;
|
||||
own = OWN_CREATE;
|
||||
}
|
||||
Py_END_ALLOW_THREADS;
|
||||
return li != NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@ -256,6 +263,7 @@ public:
|
||||
// This method can be used to pass a linput_t* from C code
|
||||
static loader_input_t *from_cobject(PyObject *pycobject)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyCObject_Check(pycobject) )
|
||||
return NULL;
|
||||
loader_input_t *l = new loader_input_t();
|
||||
@ -266,14 +274,18 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
static loader_input_t *from_fp(FILE *fp)
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
loader_input_t *l = NULL;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
linput_t *fp_li = make_linput(fp);
|
||||
if ( fp_li == NULL )
|
||||
return NULL;
|
||||
|
||||
loader_input_t *l = new loader_input_t();
|
||||
l->own = OWN_FROM_FP;
|
||||
l->fn.sprnt("<FILE * %p>", fp);
|
||||
l->li = fp_li;
|
||||
if ( fp_li != NULL )
|
||||
{
|
||||
l = new loader_input_t();
|
||||
l->own = OWN_FROM_FP;
|
||||
l->fn.sprnt("<FILE * %p>", fp);
|
||||
l->li = fp_li;
|
||||
}
|
||||
Py_END_ALLOW_THREADS;
|
||||
return l;
|
||||
}
|
||||
|
||||
@ -286,37 +298,55 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
bool open_memory(ea_t start, asize_t size = 0)
|
||||
{
|
||||
linput_t *l = create_memory_linput(start, size);
|
||||
if ( l == NULL )
|
||||
return false;
|
||||
close();
|
||||
li = l;
|
||||
fn = "<memory>";
|
||||
own = OWN_CREATE;
|
||||
return true;
|
||||
PYW_GIL_GET;
|
||||
linput_t *l;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
l = create_memory_linput(start, size);
|
||||
if ( l != NULL )
|
||||
{
|
||||
close();
|
||||
li = l;
|
||||
fn = "<memory>";
|
||||
own = OWN_CREATE;
|
||||
}
|
||||
Py_END_ALLOW_THREADS;
|
||||
return l != NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
int32 seek(int32 pos, int whence = SEEK_SET)
|
||||
{
|
||||
return qlseek(li, pos, whence);
|
||||
int32 r;
|
||||
PYW_GIL_GET;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = qlseek(li, pos, whence);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return r;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
int32 tell()
|
||||
{
|
||||
return qltell(li);
|
||||
int32 r;
|
||||
PYW_GIL_GET;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = qltell(li);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return r;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
PyObject *getz(size_t sz, int32 fpos = -1)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
do
|
||||
{
|
||||
char *buf = (char *) malloc(sz + 5);
|
||||
if ( buf == NULL )
|
||||
break;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
qlgetz(li, fpos, buf, sz);
|
||||
Py_END_ALLOW_THREADS;
|
||||
PyObject *ret = PyString_FromString(buf);
|
||||
free(buf);
|
||||
return ret;
|
||||
@ -327,12 +357,17 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
PyObject *gets(size_t len)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
do
|
||||
{
|
||||
char *buf = (char *) malloc(len + 5);
|
||||
if ( buf == NULL )
|
||||
break;
|
||||
if ( qlgets(buf, len, li) == NULL )
|
||||
bool ok;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
ok = qlgets(buf, len, li) != NULL;
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( !ok )
|
||||
{
|
||||
free(buf);
|
||||
break;
|
||||
@ -347,12 +382,16 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
PyObject *read(size_t size)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
do
|
||||
{
|
||||
char *buf = (char *) malloc(size + 5);
|
||||
if ( buf == NULL )
|
||||
break;
|
||||
ssize_t r = qlread(li, buf, size);
|
||||
ssize_t r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = qlread(li, buf, size);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( r == -1 )
|
||||
{
|
||||
free(buf);
|
||||
@ -374,12 +413,16 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
PyObject *readbytes(size_t size, bool big_endian)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
do
|
||||
{
|
||||
char *buf = (char *) malloc(size + 5);
|
||||
if ( buf == NULL )
|
||||
break;
|
||||
int r = lreadbytes(li, buf, size, big_endian);
|
||||
int r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = lreadbytes(li, buf, size, big_endian);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( r == -1 )
|
||||
{
|
||||
free(buf);
|
||||
@ -395,25 +438,38 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
int file2base(int32 pos, ea_t ea1, ea_t ea2, int patchable)
|
||||
{
|
||||
return ::file2base(li, pos, ea1, ea2, patchable);
|
||||
int rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = ::file2base(li, pos, ea1, ea2, patchable);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
int32 size()
|
||||
{
|
||||
return qlsize(li);
|
||||
int32 rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = qlsize(li);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
PyObject *filename()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return PyString_FromString(fn.c_str());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
PyObject *get_char()
|
||||
{
|
||||
int ch = qlgetc(li);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
int ch;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
ch = qlgetc(li);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( ch == EOF )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("c", ch);
|
||||
@ -432,7 +488,7 @@ def enumerate_files(path, fname, callback):
|
||||
@param callback: a callable object that takes the filename as
|
||||
its first argument and it returns 0 to continue
|
||||
enumeration or non-zero to stop enumeration.
|
||||
@return:
|
||||
@return:
|
||||
None in case of script errors
|
||||
tuple(code, fname) : If the callback returns non-zero
|
||||
"""
|
||||
@ -441,6 +497,8 @@ def enumerate_files(path, fname, callback):
|
||||
*/
|
||||
PyObject *py_enumerate_files(PyObject *path, PyObject *fname, PyObject *callback)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
do
|
||||
{
|
||||
if ( !PyString_Check(path) || !PyString_Check(fname) || !PyCallable_Check(callback) )
|
||||
|
24
swig/expr.i
24
swig/expr.i
@ -74,10 +74,12 @@ struct py_idcfunc_ctx_t
|
||||
int nargs;
|
||||
py_idcfunc_ctx_t(PyObject *py_func, const char *name, int nargs): py_func(py_func), name(name), nargs(nargs)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
Py_INCREF(py_func);
|
||||
}
|
||||
~py_idcfunc_ctx_t()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
Py_DECREF(py_func);
|
||||
}
|
||||
};
|
||||
@ -91,25 +93,25 @@ static error_t py_call_idc_func(
|
||||
// Convert IDC arguments to Python list
|
||||
py_idcfunc_ctx_t *ctx = (py_idcfunc_ctx_t *)_ctx;
|
||||
int cvt;
|
||||
ppyobject_vec_t pargs;
|
||||
char errbuf[MAXSTR];
|
||||
if ( !pyw_convert_idc_args(argv, ctx->nargs, pargs, NULL, errbuf, sizeof(errbuf)) )
|
||||
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
ref_vec_t pargs;
|
||||
if ( !pyw_convert_idc_args(argv, ctx->nargs, pargs, true, errbuf, sizeof(errbuf)) )
|
||||
{
|
||||
// Error during conversion? Create an IDC exception
|
||||
return PyW_CreateIdcException(r, errbuf);
|
||||
}
|
||||
|
||||
// Call the Python function
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallObject(
|
||||
ctx->py_func,
|
||||
pargs.empty() ? NULL : pargs[0]);
|
||||
|
||||
newref_t py_result(PyObject_CallObject(
|
||||
ctx->py_func,
|
||||
pargs.empty() ? NULL : pargs[0].o));
|
||||
|
||||
error_t err;
|
||||
if ( PyW_GetError(errbuf, sizeof(errbuf)) )
|
||||
{
|
||||
err = PyW_CreateIdcException(r, errbuf);
|
||||
Py_XDECREF(py_result);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -120,13 +122,7 @@ static error_t py_call_idc_func(
|
||||
err = PyW_CreateIdcException(r, "ERROR: bad return value");
|
||||
else
|
||||
err = eOk;
|
||||
if ( cvt != CIP_OK_NODECREF )
|
||||
Py_XDECREF(py_result);
|
||||
}
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
// Free the converted args
|
||||
pyw_free_idc_args(pargs);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
112
swig/fpro.i
112
swig/fpro.i
@ -100,6 +100,7 @@ private:
|
||||
}
|
||||
inline void _from_cobject(PyObject *pycobject)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
_from_fp((FILE *)PyCObject_AsVoidPtr(pycobject));
|
||||
}
|
||||
public:
|
||||
@ -117,7 +118,12 @@ public:
|
||||
own = true;
|
||||
fn.qclear();
|
||||
__idc_cvt_id__ = PY_ICID_OPAQUE;
|
||||
if ( pycobject != NULL && PyCObject_Check(pycobject) )
|
||||
bool ok;
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
ok = pycobject != NULL && PyCObject_Check(pycobject);
|
||||
}
|
||||
if ( ok )
|
||||
_from_cobject(pycobject);
|
||||
}
|
||||
|
||||
@ -133,7 +139,11 @@ public:
|
||||
if ( fp == NULL )
|
||||
return;
|
||||
if ( own )
|
||||
{
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
qfclose(fp);
|
||||
Py_END_ALLOW_THREADS;
|
||||
}
|
||||
fp = NULL;
|
||||
own = true;
|
||||
}
|
||||
@ -148,7 +158,9 @@ public:
|
||||
bool open(const char *filename, const char *mode)
|
||||
{
|
||||
close();
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
fp = qfopen(filename, mode);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( fp == NULL )
|
||||
return false;
|
||||
// Save file name
|
||||
@ -179,7 +191,11 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
static qfile_t *tmpfile()
|
||||
{
|
||||
return from_fp(qtmpfile());
|
||||
FILE *fp;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
fp = qtmpfile();
|
||||
Py_END_ALLOW_THREADS;
|
||||
return from_fp(fp);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@ -191,13 +207,21 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
int seek(int32 offset, int whence = SEEK_SET)
|
||||
{
|
||||
return qfseek(fp, offset, whence);
|
||||
int rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = qfseek(fp, offset, whence);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
int32 tell()
|
||||
{
|
||||
return qftell(fp);
|
||||
int32 rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = qftell(fp);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@ -208,12 +232,17 @@ public:
|
||||
char *buf = (char *) malloc(size + 5);
|
||||
if ( buf == NULL )
|
||||
break;
|
||||
int r = freadbytes(fp, buf, size, big_endian);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
int r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = freadbytes(fp, buf, size, big_endian);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( r != 0 )
|
||||
{
|
||||
free(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
PyObject *ret = PyString_FromStringAndSize(buf, r);
|
||||
free(buf);
|
||||
return ret;
|
||||
@ -229,7 +258,11 @@ public:
|
||||
char *buf = (char *) malloc(size + 5);
|
||||
if ( buf == NULL )
|
||||
break;
|
||||
int r = qfread(fp, buf, size);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
int r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
r = qfread(fp, buf, size);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( r <= 0 )
|
||||
{
|
||||
free(buf);
|
||||
@ -250,7 +283,12 @@ public:
|
||||
char *buf = (char *) malloc(size + 5);
|
||||
if ( buf == NULL )
|
||||
break;
|
||||
if ( qfgets(buf, size, fp) == NULL )
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
char *p;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
p = qfgets(buf, size, fp);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( p == NULL )
|
||||
{
|
||||
free(buf);
|
||||
break;
|
||||
@ -265,50 +303,87 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
int writebytes(PyObject *py_buf, bool big_endian)
|
||||
{
|
||||
int sz = PyString_GET_SIZE(py_buf);
|
||||
void *buf = (void *)PyString_AS_STRING(py_buf);
|
||||
return fwritebytes(fp, buf, sz, big_endian);
|
||||
Py_ssize_t sz;
|
||||
void *buf;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
sz = PyString_GET_SIZE(py_buf);
|
||||
buf = (void *)PyString_AS_STRING(py_buf);
|
||||
int rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = fwritebytes(fp, buf, int(sz), big_endian);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
int write(PyObject *py_buf)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyString_Check(py_buf) )
|
||||
return 0;
|
||||
return qfwrite(fp, (void *)PyString_AS_STRING(py_buf), PyString_GET_SIZE(py_buf));
|
||||
// Just so that there is no risk that the buffer returned by
|
||||
// 'PyString_AS_STRING' gets deallocated within the
|
||||
// Py_BEGIN|END_ALLOW_THREADS section.
|
||||
borref_t py_buf_ref(py_buf);
|
||||
void *p = (void *)PyString_AS_STRING(py_buf);
|
||||
Py_ssize_t sz = PyString_GET_SIZE(py_buf);
|
||||
int rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = qfwrite(fp, p, sz);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
int puts(const char *str)
|
||||
{
|
||||
return qfputs(str, fp);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
int rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = qfputs(str, fp);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
int32 size()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
int32 r;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
int pos = qfseek(fp, 0, SEEK_END);
|
||||
int32 r = qftell(fp);
|
||||
r = qftell(fp);
|
||||
qfseek(fp, pos, SEEK_SET);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return r;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
int flush()
|
||||
{
|
||||
return qflush(fp);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
int rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = qflush(fp);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
PyObject *filename()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return PyString_FromString(fn.c_str());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
PyObject *get_char()
|
||||
{
|
||||
int ch = qfgetc(fp);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
int ch;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
ch = qfgetc(fp);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( ch == EOF )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("c", ch);
|
||||
@ -317,7 +392,12 @@ public:
|
||||
//--------------------------------------------------------------------------
|
||||
int put_char(char chr)
|
||||
{
|
||||
return qfputc(chr, fp);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
int rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = qfputc(chr, fp);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
};
|
||||
//</inline(py_qfile)>
|
||||
|
@ -17,6 +17,8 @@
|
||||
%ignore write_stkpnts;
|
||||
%ignore del_stkpnts;
|
||||
%ignore rename_frame;
|
||||
%ignore _set_frame_size;
|
||||
%ignore add_empty_frame;
|
||||
|
||||
%ignore get_stkvar;
|
||||
%rename (get_stkvar) py_get_stkvar;
|
||||
|
1056
swig/graph.i
1056
swig/graph.i
File diff suppressed because it is too large
Load Diff
293
swig/hexrays.i
293
swig/hexrays.i
@ -21,7 +21,7 @@
|
||||
#pragma SWIG nowarn=454 // Setting a pointer/reference variable may leak memory
|
||||
|
||||
#define _STD_BEGIN
|
||||
#define typename
|
||||
#define typename
|
||||
|
||||
%{
|
||||
#include "hexrays.hpp"
|
||||
@ -177,9 +177,9 @@ typedef intvec_t eavec_t;// vector of addresses
|
||||
%template(history_t) qstack<history_item_t>;
|
||||
typedef int iterator_word;
|
||||
|
||||
/* no support for nested classes in swig means we need to wrap
|
||||
/* no support for nested classes in swig means we need to wrap
|
||||
this iterator and do some magic...
|
||||
|
||||
|
||||
to use it, call qlist< cinsn_t >::begin() which will return the
|
||||
proper iterator type which can then be used to get the current item.
|
||||
*/
|
||||
@ -246,27 +246,25 @@ void qswap(cinsn_t &a, cinsn_t &b);
|
||||
%{
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
static int hexrays_python_call(PyObject *fct, PyObject *args)
|
||||
static int hexrays_python_call(ref_t fct, ref_t args)
|
||||
{
|
||||
PyObject *resultobj;
|
||||
PYW_GIL_GET;
|
||||
|
||||
int result;
|
||||
int ecode1 = 0 ;
|
||||
|
||||
resultobj = PyEval_CallObject(fct, args);
|
||||
|
||||
if (resultobj == NULL)
|
||||
newref_t resultobj(PyEval_CallObject(fct.o, args.o));
|
||||
if ( resultobj == NULL )
|
||||
{
|
||||
msg("IDAPython: Hex-rays python callback raised an exception.\n");
|
||||
|
||||
|
||||
// we can't do much else than clear the exception since this was not called from Python.
|
||||
// XXX: print stack trace?
|
||||
PyErr_Clear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
ecode1 = SWIG_AsVal_int(resultobj, &result);
|
||||
Py_DECREF(resultobj);
|
||||
|
||||
ecode1 = SWIG_AsVal_int(resultobj.o, &result);
|
||||
if (SWIG_IsOK(ecode1))
|
||||
return result;
|
||||
|
||||
@ -277,22 +275,22 @@ static int hexrays_python_call(PyObject *fct, PyObject *args)
|
||||
//---------------------------------------------------------------------
|
||||
static bool idaapi __python_custom_viewer_popup_item_callback(void *ud)
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
|
||||
int ret;
|
||||
PyObject *fct = (PyObject *)ud;
|
||||
|
||||
ret = hexrays_python_call(fct, NULL);
|
||||
|
||||
borref_t fct((PyObject *)ud);
|
||||
newref_t nil(NULL);
|
||||
ret = hexrays_python_call(fct, nil);
|
||||
return ret ? true : false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
static int idaapi __hexrays_python_callback(void *ud, hexrays_event_t event, va_list va)
|
||||
{
|
||||
PYW_GIL_GET;
|
||||
|
||||
int ret;
|
||||
PyObject *fct = (PyObject *)ud;
|
||||
void *argp = NULL;
|
||||
PyObject *args = NULL;
|
||||
|
||||
borref_t fct((PyObject *)ud);
|
||||
switch(event)
|
||||
{
|
||||
case hxe_maturity:
|
||||
@ -302,13 +300,9 @@ static int idaapi __hexrays_python_callback(void *ud, hexrays_event_t event, va_
|
||||
{
|
||||
cfunc_t *arg0 = va_arg(va, cfunc_t *);
|
||||
ctree_maturity_t arg1 = va_argi(va, ctree_maturity_t);
|
||||
PyObject *arg0obj = SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_cfunc_t, 0 );
|
||||
|
||||
args = Py_BuildValue("(iOi)", event, arg0obj, arg1);
|
||||
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_cfunc_t, 0 ));
|
||||
newref_t args(Py_BuildValue("(iOi)", event, arg0obj.o, arg1));
|
||||
ret = hexrays_python_call(fct, args);
|
||||
|
||||
Py_XDECREF(arg0obj);
|
||||
Py_DECREF(args);
|
||||
}
|
||||
break;
|
||||
case hxe_interr:
|
||||
@ -316,31 +310,23 @@ static int idaapi __hexrays_python_callback(void *ud, hexrays_event_t event, va_
|
||||
///< int errcode
|
||||
{
|
||||
int arg0 = va_argi(va, int);
|
||||
|
||||
args = Py_BuildValue("(ii)", event, arg0);
|
||||
newref_t args(Py_BuildValue("(ii)", event, arg0));
|
||||
ret = hexrays_python_call(fct, args);
|
||||
|
||||
Py_DECREF(args);
|
||||
}
|
||||
break;
|
||||
|
||||
case hxe_print_func:
|
||||
///< Printing ctree and generating text.
|
||||
///< cfunc_t *cfunc
|
||||
///< vc_printer_t *vp
|
||||
///< cfunc_t *cfunc
|
||||
///< vc_printer_t *vp
|
||||
///< Returns: 1 if text has been generated by the plugin
|
||||
{
|
||||
cfunc_t *arg0 = va_arg(va, cfunc_t *);
|
||||
vc_printer_t *arg1 = va_arg(va, vc_printer_t *);
|
||||
PyObject *arg0obj = SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_cfunc_t, 0 );
|
||||
PyObject *arg1obj = SWIG_NewPointerObj(SWIG_as_voidptr(arg1), SWIGTYPE_p_vc_printer_t, 0 );
|
||||
|
||||
args = Py_BuildValue("(iOO)", event, arg0obj, arg1obj);
|
||||
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_cfunc_t, 0 ));
|
||||
newref_t arg1obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg1), SWIGTYPE_p_vc_printer_t, 0 ));
|
||||
newref_t args(Py_BuildValue("(iOO)", event, arg0obj.o, arg1obj.o));
|
||||
ret = hexrays_python_call(fct, args);
|
||||
|
||||
Py_XDECREF(arg0obj);
|
||||
Py_XDECREF(arg1obj);
|
||||
Py_DECREF(args);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -350,13 +336,9 @@ static int idaapi __hexrays_python_callback(void *ud, hexrays_event_t event, va_
|
||||
///< vdui_t *vu
|
||||
{
|
||||
vdui_t *arg0 = va_arg(va, vdui_t *);
|
||||
PyObject *arg0obj = SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 );
|
||||
|
||||
args = Py_BuildValue("(iO)", event, arg0obj);
|
||||
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
|
||||
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
|
||||
ret = hexrays_python_call(fct, args);
|
||||
|
||||
Py_XDECREF(arg0obj);
|
||||
Py_DECREF(args);
|
||||
}
|
||||
break;
|
||||
case hxe_switch_pseudocode:
|
||||
@ -366,28 +348,20 @@ static int idaapi __hexrays_python_callback(void *ud, hexrays_event_t event, va_
|
||||
///< vdui_t *vu
|
||||
{
|
||||
vdui_t *arg0 = va_arg(va, vdui_t *);
|
||||
PyObject *arg0obj = SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 );
|
||||
|
||||
args = Py_BuildValue("(iO)", event, arg0obj);
|
||||
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
|
||||
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
|
||||
ret = hexrays_python_call(fct, args);
|
||||
|
||||
Py_XDECREF(arg0obj);
|
||||
Py_DECREF(args);
|
||||
}
|
||||
break;
|
||||
case hxe_refresh_pseudocode:
|
||||
///< Existing pseudocode text has been refreshed.
|
||||
///< vdui_t *vu
|
||||
///< vdui_t *vu
|
||||
///< See also hxe_text_ready, which happens earlier
|
||||
{
|
||||
vdui_t *arg0 = va_arg(va, vdui_t *);
|
||||
PyObject *arg0obj = SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 );
|
||||
|
||||
args = Py_BuildValue("(iO)", event, arg0obj);
|
||||
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
|
||||
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
|
||||
ret = hexrays_python_call(fct, args);
|
||||
|
||||
Py_XDECREF(arg0obj);
|
||||
Py_DECREF(args);
|
||||
}
|
||||
break;
|
||||
case hxe_close_pseudocode:
|
||||
@ -395,32 +369,24 @@ static int idaapi __hexrays_python_callback(void *ud, hexrays_event_t event, va_
|
||||
///< vdui_t *vu
|
||||
{
|
||||
vdui_t *arg0 = va_arg(va, vdui_t *);
|
||||
PyObject *arg0obj = SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 );
|
||||
|
||||
args = Py_BuildValue("(iO)", event, arg0obj);
|
||||
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
|
||||
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
|
||||
ret = hexrays_python_call(fct, args);
|
||||
|
||||
Py_XDECREF(arg0obj);
|
||||
Py_DECREF(args);
|
||||
}
|
||||
break;
|
||||
case hxe_keyboard:
|
||||
///< Keyboard has been hit.
|
||||
///< vdui_t *vu
|
||||
///< int key_code (VK_...)
|
||||
///< int shift_state
|
||||
///< vdui_t *vu
|
||||
///< int key_code (VK_...)
|
||||
///< int shift_state
|
||||
///< Should return: 1 if the event has been handled
|
||||
{
|
||||
vdui_t *arg0 = va_arg(va, vdui_t *);
|
||||
int arg1 = va_argi(va, int);
|
||||
int arg2 = va_argi(va, int);
|
||||
PyObject *arg0obj = SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 );
|
||||
|
||||
args = Py_BuildValue("(iOii)", event, arg0obj, arg1, arg2);
|
||||
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
|
||||
newref_t args(Py_BuildValue("(iOii)", event, arg0obj.o, arg1, arg2));
|
||||
ret = hexrays_python_call(fct, args);
|
||||
|
||||
Py_XDECREF(arg0obj);
|
||||
Py_DECREF(args);
|
||||
}
|
||||
break;
|
||||
case hxe_right_click:
|
||||
@ -428,30 +394,22 @@ static int idaapi __hexrays_python_callback(void *ud, hexrays_event_t event, va_
|
||||
///< vdui_t *vu
|
||||
{
|
||||
vdui_t *arg0 = va_arg(va, vdui_t *);
|
||||
PyObject *arg0obj = SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 );
|
||||
|
||||
args = Py_BuildValue("(iO)", event, arg0obj);
|
||||
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
|
||||
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
|
||||
ret = hexrays_python_call(fct, args);
|
||||
|
||||
Py_XDECREF(arg0obj);
|
||||
Py_DECREF(args);
|
||||
}
|
||||
break;
|
||||
case hxe_double_click:
|
||||
///< Mouse double click.
|
||||
///< vdui_t *vu
|
||||
///< int shift_state
|
||||
///< vdui_t *vu
|
||||
///< int shift_state
|
||||
///< Should return: 1 if the event has been handled
|
||||
{
|
||||
vdui_t *arg0 = va_arg(va, vdui_t *);
|
||||
int arg1 = va_argi(va, int);
|
||||
PyObject *arg0obj = SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 );
|
||||
|
||||
args = Py_BuildValue("(iOi)", event, arg0obj, arg1);
|
||||
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
|
||||
newref_t args(Py_BuildValue("(iOi)", event, arg0obj.o, arg1));
|
||||
ret = hexrays_python_call(fct, args);
|
||||
|
||||
Py_XDECREF(arg0obj);
|
||||
Py_DECREF(args);
|
||||
}
|
||||
break;
|
||||
case hxe_curpos:
|
||||
@ -460,51 +418,39 @@ static int idaapi __hexrays_python_callback(void *ud, hexrays_event_t event, va_
|
||||
///< vdui_t *vu
|
||||
{
|
||||
vdui_t *arg0 = va_arg(va, vdui_t *);
|
||||
PyObject *arg0obj = SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 );
|
||||
|
||||
args = Py_BuildValue("(iO)", event, arg0obj);
|
||||
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
|
||||
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
|
||||
ret = hexrays_python_call(fct, args);
|
||||
|
||||
Py_XDECREF(arg0obj);
|
||||
Py_DECREF(args);
|
||||
}
|
||||
break;
|
||||
case hxe_create_hint:
|
||||
///< Create a hint for the current item.
|
||||
///< vdui_t *vu
|
||||
///< qstring *result_hint
|
||||
///< int *implines
|
||||
///< Possible return values:
|
||||
///< 0: the event has not been handled
|
||||
///< vdui_t *vu
|
||||
///< qstring *result_hint
|
||||
///< int *implines
|
||||
///< Possible return values:
|
||||
///< 0: the event has not been handled
|
||||
///< 1: hint has been created (should set *implines to nonzero as well)
|
||||
///< 2: hint has been created but the standard hints must be
|
||||
///< appended by the decompiler
|
||||
{
|
||||
vdui_t *arg0 = va_arg(va, vdui_t *);
|
||||
PyObject *arg0obj = SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 );
|
||||
|
||||
args = Py_BuildValue("(iO)", event, arg0obj);
|
||||
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
|
||||
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
|
||||
ret = hexrays_python_call(fct, args);
|
||||
|
||||
Py_XDECREF(arg0obj);
|
||||
Py_DECREF(args);
|
||||
}
|
||||
break;
|
||||
case hxe_text_ready:
|
||||
///< Decompiled text is ready.
|
||||
///< vdui_t *vu
|
||||
///< vdui_t *vu
|
||||
///< This event can be used to modify the output text (sv).
|
||||
///< The text uses regular color codes (see lines.hpp)
|
||||
///< COLOR_ADDR is used to store pointers to ctree elements
|
||||
{
|
||||
vdui_t *arg0 = va_arg(va, vdui_t *);
|
||||
PyObject *arg0obj = SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 );
|
||||
|
||||
args = Py_BuildValue("(iO)", event, arg0obj);
|
||||
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
|
||||
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
|
||||
ret = hexrays_python_call(fct, args);
|
||||
|
||||
Py_XDECREF(arg0obj);
|
||||
Py_DECREF(args);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -512,7 +458,7 @@ static int idaapi __hexrays_python_callback(void *ud, hexrays_event_t event, va_
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -550,37 +496,40 @@ void __add_custom_viewer_popup_item(
|
||||
const char *hotkey,
|
||||
PyObject *custom_viewer_popup_item_callback)
|
||||
{
|
||||
Py_INCREF(custom_viewer_popup_item_callback);
|
||||
add_custom_viewer_popup_item(custom_viewer, title, hotkey, __python_custom_viewer_popup_item_callback, custom_viewer_popup_item_callback);
|
||||
PYW_GIL_GET;
|
||||
Py_INCREF(custom_viewer_popup_item_callback);
|
||||
add_custom_viewer_popup_item(custom_viewer, title, hotkey, __python_custom_viewer_popup_item_callback, custom_viewer_popup_item_callback);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
bool __install_hexrays_callback(PyObject *hx_cblist_callback)
|
||||
{
|
||||
if (install_hexrays_callback(__hexrays_python_callback, hx_cblist_callback))
|
||||
{
|
||||
Py_INCREF(hx_cblist_callback);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
PYW_GIL_GET;
|
||||
if (install_hexrays_callback(__hexrays_python_callback, hx_cblist_callback))
|
||||
{
|
||||
Py_INCREF(hx_cblist_callback);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
int __remove_hexrays_callback(PyObject *hx_cblist_callback)
|
||||
{
|
||||
int result, i;
|
||||
result = remove_hexrays_callback(__hexrays_python_callback, hx_cblist_callback);
|
||||
for (i=0;i<result;i++)
|
||||
Py_DECREF(hx_cblist_callback);
|
||||
PYW_GIL_GET;
|
||||
int result, i;
|
||||
result = remove_hexrays_callback(__hexrays_python_callback, hx_cblist_callback);
|
||||
for (i=0;i<result;i++)
|
||||
Py_DECREF(hx_cblist_callback);
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
%}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
%define %python_callback_in(CB)
|
||||
%typemap(check) CB {
|
||||
if (!PyCallable_Check($1))
|
||||
if (!PyCallable_Check($1))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "Need a callable object!");
|
||||
return NULL;
|
||||
@ -602,10 +551,10 @@ hexrays_failure_t.__str__ = lambda self: str(self.str)
|
||||
# ---------------------------------------------------------------------
|
||||
class DecompilationFailure(Exception):
|
||||
""" Raised on a decompilation error.
|
||||
|
||||
|
||||
The associated hexrays_failure_t object is stored in the
|
||||
'info' member of this exception. """
|
||||
|
||||
|
||||
def __init__(self, info):
|
||||
Exception.__init__(self, 'Decompilation failed: %s' % (str(info), ))
|
||||
self.info = info
|
||||
@ -620,15 +569,15 @@ def decompile(ea, hf=None):
|
||||
func = ea
|
||||
else:
|
||||
raise RuntimeError('arg 1 of decompile expects either ea_t or cfunc_t argument')
|
||||
|
||||
|
||||
if hf is None:
|
||||
hf = hexrays_failure_t()
|
||||
|
||||
|
||||
ptr = _decompile(func, hf)
|
||||
|
||||
|
||||
if ptr.__deref__() is None:
|
||||
raise DecompilationFailure(hf)
|
||||
|
||||
|
||||
return ptr
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
@ -674,7 +623,7 @@ def _vectors_iterator(self):
|
||||
yield self[i]
|
||||
for cls in [cinsnptrvec_t, ctree_items_t, uvalvec_t, \
|
||||
intvec_t, boolvec_t, hexwarns_t, \
|
||||
history_t, strvec_t, qvector_lvar_t,
|
||||
history_t, strvec_t, qvector_lvar_t,
|
||||
qvector_carg_t, qvector_ccase_t
|
||||
]:
|
||||
cls.__getitem__ = cls.at
|
||||
@ -683,12 +632,12 @@ for cls in [cinsnptrvec_t, ctree_items_t, uvalvec_t, \
|
||||
|
||||
def citem_to_specific_type(self):
|
||||
""" cast the citem_t object to its more specific type, either cexpr_t or cinsn_t. """
|
||||
|
||||
|
||||
if self.op >= cot_empty and self.op <= cot_last:
|
||||
return self.cexpr
|
||||
elif self.op >= cit_empty and self.op < cit_end:
|
||||
return self.cinsn
|
||||
|
||||
|
||||
raise RuntimeError('unknown op type %s' % (repr(self.op), ))
|
||||
citem_t.to_specific_type = property(citem_to_specific_type)
|
||||
|
||||
@ -711,129 +660,129 @@ cexpr_t.opname = property(property_op_to_typename)
|
||||
|
||||
def cexpr_operands(self):
|
||||
""" return a dictionary with the operands of a cexpr_t. """
|
||||
|
||||
|
||||
if self.op >= cot_comma and self.op <= cot_asgumod or \
|
||||
self.op >= cot_lor and self.op <= cot_fdiv or \
|
||||
self.op == cot_idx:
|
||||
return {'x': self.x, 'y': self.y}
|
||||
|
||||
|
||||
elif self.op == cot_tern:
|
||||
return {'x': self.x, 'y': self.y, 'z': self.z}
|
||||
|
||||
|
||||
elif self.op in [cot_fneg, cot_neg, cot_sizeof] or \
|
||||
self.op >= cot_lnot and self.op <= cot_predec:
|
||||
return {'x': self.x}
|
||||
|
||||
|
||||
elif self.op == cot_cast:
|
||||
return {'type': self.type, 'x': self.x}
|
||||
|
||||
|
||||
elif self.op == cot_call:
|
||||
return {'x': self.x, 'a': self.a}
|
||||
|
||||
|
||||
elif self.op in [cot_memref, cot_memptr]:
|
||||
return {'x': self.x, 'm': self.m}
|
||||
|
||||
|
||||
elif self.op == cot_num:
|
||||
return {'n': self.n}
|
||||
|
||||
|
||||
elif self.op == cot_fnum:
|
||||
return {'fpc': self.fpc}
|
||||
|
||||
|
||||
elif self.op == cot_str:
|
||||
return {'string': self.string}
|
||||
|
||||
|
||||
elif self.op == cot_obj:
|
||||
return {'obj_ea': self.obj_ea}
|
||||
|
||||
|
||||
elif self.op == cot_var:
|
||||
return {'v': self.v}
|
||||
|
||||
|
||||
elif self.op == cot_helper:
|
||||
return {'helper': self.helper}
|
||||
|
||||
|
||||
raise RuntimeError('unknown op type %s' % self.opname)
|
||||
cexpr_t.operands = property(cexpr_operands)
|
||||
|
||||
def cinsn_details(self):
|
||||
""" return the details pointer for the cinsn_t object depending on the value of its op member. \
|
||||
this is one of the cblock_t, cif_t, etc. objects. """
|
||||
|
||||
|
||||
if self.op not in self.op_to_typename:
|
||||
raise RuntimeError('unknown item->op type')
|
||||
|
||||
|
||||
opname = self.opname
|
||||
if opname == 'empty':
|
||||
return self
|
||||
|
||||
|
||||
if opname in ['break', 'continue']:
|
||||
return None
|
||||
|
||||
|
||||
return getattr(self, 'c' + opname)
|
||||
cinsn_t.details = property(cinsn_details)
|
||||
|
||||
def cblock_iter(self):
|
||||
|
||||
|
||||
iter = self.begin()
|
||||
for i in range(self.size()):
|
||||
yield iter.cur
|
||||
iter.next()
|
||||
|
||||
|
||||
return
|
||||
cblock_t.__iter__ = cblock_iter
|
||||
cblock_t.__len__ = cblock_t.size
|
||||
|
||||
# cblock.find(cinsn_t) -> returns the iterator positioned at the given item
|
||||
def cblock_find(self, item):
|
||||
|
||||
|
||||
iter = self.begin()
|
||||
for i in range(self.size()):
|
||||
if iter.cur == item:
|
||||
return iter
|
||||
iter.next()
|
||||
|
||||
|
||||
return
|
||||
cblock_t.find = cblock_find
|
||||
|
||||
# cblock.index(cinsn_t) -> returns the index of the given item
|
||||
def cblock_index(self, item):
|
||||
|
||||
|
||||
iter = self.begin()
|
||||
for i in range(self.size()):
|
||||
if iter.cur == item:
|
||||
return i
|
||||
iter.next()
|
||||
|
||||
|
||||
return
|
||||
cblock_t.index = cblock_index
|
||||
|
||||
# cblock.at(int) -> returns the item at the given index index
|
||||
def cblock_at(self, index):
|
||||
|
||||
|
||||
iter = self.begin()
|
||||
for i in range(self.size()):
|
||||
if i == index:
|
||||
return iter.cur
|
||||
iter.next()
|
||||
|
||||
|
||||
return
|
||||
cblock_t.at = cblock_at
|
||||
|
||||
# cblock.remove(cinsn_t)
|
||||
def cblock_remove(self, item):
|
||||
|
||||
|
||||
iter = self.find(item)
|
||||
self.erase(iter)
|
||||
|
||||
|
||||
return
|
||||
cblock_t.remove = cblock_remove
|
||||
|
||||
# cblock.insert(index, cinsn_t)
|
||||
def cblock_insert(self, index, item):
|
||||
|
||||
|
||||
pos = self.at(index)
|
||||
iter = self.find(pos)
|
||||
self.insert(iter, item)
|
||||
|
||||
|
||||
return
|
||||
cblock_t.insert = cblock_insert
|
||||
|
||||
@ -848,13 +797,13 @@ cfuncptr_t.__str__ = lambda self: str(self.__deref__())
|
||||
def cfunc_typestring(self):
|
||||
""" Get the function's return type typestring object. The full prototype \
|
||||
can be obtained via typestring._print() method. """
|
||||
|
||||
|
||||
ts = typestring()
|
||||
qt = qtype()
|
||||
|
||||
|
||||
result = self.get_func_type(ts, qt)
|
||||
if not result: return
|
||||
|
||||
|
||||
return ts
|
||||
cfunc_t.typestring = property(cfunc_typestring)
|
||||
cfuncptr_t.typestring = property(lambda self: self.__deref__().typestring)
|
||||
@ -1000,18 +949,18 @@ def _map_setdefault(self, key, default=None):
|
||||
return default
|
||||
|
||||
def _map_as_dict(maptype, name, keytype, valuetype):
|
||||
|
||||
|
||||
maptype.keytype = keytype
|
||||
maptype.valuetype = valuetype
|
||||
|
||||
|
||||
for fctname in ['begin', 'end', 'first', 'second', 'next', \
|
||||
'find', 'insert', 'erase', 'clear', 'size']:
|
||||
fct = getattr(_idaapi, name + '_' + fctname)
|
||||
setattr(maptype, '__' + fctname, fct)
|
||||
|
||||
|
||||
maptype.__len__ = maptype.size
|
||||
maptype.__getitem__ = maptype.at
|
||||
|
||||
|
||||
maptype.begin = lambda self, *args: self.__begin(self, *args)
|
||||
maptype.end = lambda self, *args: self.__end(self, *args)
|
||||
maptype.first = lambda self, *args: self.__first(*args)
|
||||
|
@ -1,9 +1,16 @@
|
||||
// Ignore kernel-only symbols
|
||||
%ignore dual_text_options_t;
|
||||
%ignore idainfo::init;
|
||||
%ignore idainfo::init_netnode;
|
||||
%ignore idainfo::precheck_idb_version;
|
||||
%ignore idainfo::retrieve;
|
||||
%ignore idainfo::read;
|
||||
%ignore idainfo::write;
|
||||
%ignore idainfo::convert_va_format;
|
||||
%ignore idainfo::upgrade_approved;
|
||||
%ignore idainfo::will_upgrade;
|
||||
%ignore idainfo::approve_upgrade;
|
||||
%ignore idainfo::show_progress;
|
||||
%ignore idainfo::align_short_demnames;
|
||||
%ignore idainfo::align_strtype;
|
||||
%ignore idainfo::align_long_demnames;
|
||||
|
1621
swig/idaapi.i
1621
swig/idaapi.i
File diff suppressed because it is too large
Load Diff
55
swig/idd.i
55
swig/idd.i
@ -14,6 +14,12 @@
|
||||
|
||||
%clear(char dtyp);
|
||||
|
||||
%pythoncode %{
|
||||
#<pycode(py_idd_2)>
|
||||
NO_PROCESS = 0xFFFFFFFF
|
||||
NO_THREAD = 0
|
||||
#</pycode(py_idd_2)>
|
||||
%}
|
||||
%{
|
||||
//<code(py_idd)>
|
||||
|
||||
@ -28,6 +34,8 @@ static bool dbg_can_query()
|
||||
//-------------------------------------------------------------------------
|
||||
static PyObject *meminfo_vec_t_to_py(meminfo_vec_t &areas)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
PyObject *py_list = PyList_New(areas.size());
|
||||
meminfo_vec_t::const_iterator it, it_end(areas.end());
|
||||
Py_ssize_t i = 0;
|
||||
@ -56,6 +64,8 @@ PyObject *py_appcall(
|
||||
PyObject *py_fields,
|
||||
PyObject *arg_list)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
if ( !PyList_Check(arg_list) )
|
||||
return NULL;
|
||||
|
||||
@ -71,11 +81,11 @@ PyObject *py_appcall(
|
||||
for ( Py_ssize_t i=0; i<nargs; i++ )
|
||||
{
|
||||
// Get argument
|
||||
PyObject *py_item = PyList_GetItem(arg_list, i);
|
||||
borref_t py_item(PyList_GetItem(arg_list, i));
|
||||
if ( (debug & IDA_DEBUG_APPCALL) != 0 )
|
||||
{
|
||||
qstring s;
|
||||
PyW_ObjectToString(py_item, &s);
|
||||
PyW_ObjectToString(py_item.o, &s);
|
||||
msg("obj[%d]->%s\n", int(i), s.c_str());
|
||||
}
|
||||
// Convert it
|
||||
@ -95,6 +105,10 @@ PyObject *py_appcall(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
error_t ret;
|
||||
idc_value_t idc_result;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
|
||||
if ( (debug & IDA_DEBUG_APPCALL) != 0 )
|
||||
{
|
||||
msg("input variables:\n"
|
||||
@ -110,8 +124,7 @@ PyObject *py_appcall(
|
||||
}
|
||||
|
||||
// Do Appcall
|
||||
idc_value_t idc_result;
|
||||
error_t ret = appcall(
|
||||
ret = appcall(
|
||||
func_ea,
|
||||
tid,
|
||||
(type_t *)type,
|
||||
@ -120,16 +133,17 @@ PyObject *py_appcall(
|
||||
idc_args.begin(),
|
||||
&idc_result);
|
||||
|
||||
Py_END_ALLOW_THREADS;
|
||||
|
||||
if ( ret != eOk )
|
||||
{
|
||||
// An exception was thrown?
|
||||
if ( ret == eExecThrow )
|
||||
{
|
||||
// Convert the result (which is a debug_event) into a Python object
|
||||
PyObject *py_appcall_exc(NULL);
|
||||
ref_t py_appcall_exc;
|
||||
idcvar_to_pyvar(idc_result, &py_appcall_exc);
|
||||
PyErr_SetObject(PyExc_OSError, py_appcall_exc);
|
||||
Py_DECREF(py_appcall_exc);
|
||||
PyErr_SetObject(PyExc_OSError, py_appcall_exc.o);
|
||||
return NULL;
|
||||
}
|
||||
// An error in the Appcall? (or an exception but AppCallOptions/DEBEV is not set)
|
||||
@ -159,7 +173,7 @@ PyObject *py_appcall(
|
||||
for ( Py_ssize_t i=0; i<nargs; i++ )
|
||||
{
|
||||
// Get argument
|
||||
PyObject *py_item = PyList_GetItem(arg_list, i);
|
||||
borref_t py_item(PyList_GetItem(arg_list, i));
|
||||
// We convert arguments but fail only on fatal errors
|
||||
// (we ignore failure because of immutable objects)
|
||||
if ( idcvar_to_pyvar(idc_args[i], &py_item) == CIP_FAILED )
|
||||
@ -169,13 +183,13 @@ PyObject *py_appcall(
|
||||
}
|
||||
}
|
||||
// Convert the result from IDC back to Python
|
||||
PyObject *py_result(NULL);
|
||||
ref_t py_result;
|
||||
if ( idcvar_to_pyvar(idc_result, &py_result) <= CIP_IMMUTABLE )
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "PyAppCall: Failed while converting IDC return value to Python return value");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QASSERT(30413, py_result.o->ob_refcnt == 1);
|
||||
if ( (debug & IDA_DEBUG_APPCALL) != 0 )
|
||||
{
|
||||
msg("return var:\n"
|
||||
@ -184,7 +198,8 @@ PyObject *py_appcall(
|
||||
VarPrint(&s, &idc_result);
|
||||
msg("%s\n-----------\n", s.c_str());
|
||||
}
|
||||
return py_result;
|
||||
py_result.incref();
|
||||
return py_result.o;
|
||||
}
|
||||
//</code(py_idd)>
|
||||
%}
|
||||
@ -212,6 +227,8 @@ def dbg_get_registers():
|
||||
*/
|
||||
static PyObject *dbg_get_registers()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
if ( dbg == NULL )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
@ -270,6 +287,8 @@ def dbg_get_thread_sreg_base(tid, sreg_value):
|
||||
*/
|
||||
static PyObject *dbg_get_thread_sreg_base(PyObject *py_tid, PyObject *py_sreg_value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
if ( !dbg_can_query() || !PyInt_Check(py_tid) || !PyInt_Check(py_sreg_value) )
|
||||
Py_RETURN_NONE;
|
||||
ea_t answer;
|
||||
@ -296,6 +315,8 @@ def dbg_read_memory(ea, sz):
|
||||
*/
|
||||
static PyObject *dbg_read_memory(PyObject *py_ea, PyObject *py_sz)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
uint64 ea, sz;
|
||||
if ( !dbg_can_query() || !PyW_GetNumber(py_ea, &ea) || !PyW_GetNumber(py_sz, &sz) )
|
||||
Py_RETURN_NONE;
|
||||
@ -333,6 +354,8 @@ def dbg_write_memory(ea, buffer):
|
||||
*/
|
||||
static PyObject *dbg_write_memory(PyObject *py_ea, PyObject *py_buf)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
uint64 ea;
|
||||
if ( !dbg_can_query() || !PyString_Check(py_buf) || !PyW_GetNumber(py_ea, &ea) )
|
||||
Py_RETURN_NONE;
|
||||
@ -357,6 +380,8 @@ def dbg_get_name():
|
||||
*/
|
||||
static PyObject *dbg_get_name()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
if ( dbg == NULL )
|
||||
Py_RETURN_NONE;
|
||||
else
|
||||
@ -378,15 +403,19 @@ def dbg_get_memory_info():
|
||||
*/
|
||||
static PyObject *dbg_get_memory_info()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
if ( !dbg_can_query() )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
// Invalidate memory
|
||||
meminfo_vec_t areas;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
invalidate_dbgmem_config();
|
||||
invalidate_dbgmem_contents(BADADDR, BADADDR);
|
||||
|
||||
meminfo_vec_t areas;
|
||||
get_dbg_memory_info(&areas);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return meminfo_vec_t_to_py(areas);
|
||||
}
|
||||
|
||||
@ -611,7 +640,7 @@ class Appcall_callable__(object):
|
||||
def __get_size(self):
|
||||
if self.__type == None:
|
||||
return -1
|
||||
r = _idaapi.get_type_size0(_idaapi.cvar.idati, self.__type)
|
||||
r = _idaapi.calc_type_size(_idaapi.cvar.idati, self.__type)
|
||||
if not r:
|
||||
return -1
|
||||
return r
|
||||
|
67
swig/idp.i
67
swig/idp.i
@ -35,6 +35,7 @@
|
||||
%ignore _py_getreg;
|
||||
%ignore free_processor_module;
|
||||
%ignore read_config_file;
|
||||
%ignore cfg_compiler_changed;
|
||||
|
||||
%ignore gen_idb_event;
|
||||
|
||||
@ -74,12 +75,17 @@ static PyObject *AssembleLine(
|
||||
{
|
||||
int inslen;
|
||||
char buf[MAXSTR];
|
||||
bool ok = false;
|
||||
if (ph.notify != NULL &&
|
||||
(inslen = ph.notify(ph.assemble, ea, cs, ip, use32, line, buf)) > 0)
|
||||
(inslen = ph.notify(ph.assemble, ea, cs, ip, use32, line, buf)) > 0)
|
||||
{
|
||||
return PyString_FromStringAndSize(buf, inslen);
|
||||
ok = true;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( ok )
|
||||
return PyString_FromStringAndSize(buf, inslen);
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@ -107,17 +113,20 @@ bool assemble(
|
||||
{
|
||||
int inslen;
|
||||
char buf[MAXSTR];
|
||||
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
bool rc = false;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
if (ph.notify != NULL)
|
||||
{
|
||||
inslen = ph.notify(ph.assemble, ea, cs, ip, use32, line, buf);
|
||||
inslen = ph.notify(ph.assemble, ea, cs, ip, use32, line, buf);
|
||||
if (inslen > 0)
|
||||
{
|
||||
patch_many_bytes(ea, buf, inslen);
|
||||
return true;
|
||||
rc = true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -359,6 +368,7 @@ def ph_get_instruc():
|
||||
static PyObject *ph_get_instruc()
|
||||
{
|
||||
Py_ssize_t i = 0;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyObject *py_result = PyTuple_New(ph.instruc_end - ph.instruc_start);
|
||||
for ( const instruc_t *p = ph.instruc + ph.instruc_start, *end = ph.instruc + ph.instruc_end;
|
||||
p != end;
|
||||
@ -382,10 +392,10 @@ def ph_get_regnames():
|
||||
static PyObject *ph_get_regnames()
|
||||
{
|
||||
Py_ssize_t i = 0;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyObject *py_result = PyList_New(ph.regsNum);
|
||||
for ( Py_ssize_t i=0; i<ph.regsNum; i++ )
|
||||
PyList_SetItem(py_result, i, PyString_FromString(ph.regNames[i]));
|
||||
|
||||
return py_result;
|
||||
}
|
||||
|
||||
@ -413,6 +423,10 @@ static PyObject *ph_get_operand_info(
|
||||
ea_t ea,
|
||||
int n)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
bool ok = false;
|
||||
idd_opinfo_t opinf;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
do
|
||||
{
|
||||
if ( dbg == NULL || n == - 1 )
|
||||
@ -427,7 +441,6 @@ static PyObject *ph_get_operand_info(
|
||||
break;
|
||||
|
||||
// Call the processor module
|
||||
idd_opinfo_t opinf;
|
||||
if ( ph.notify(ph.get_operand_info,
|
||||
ea,
|
||||
n,
|
||||
@ -438,14 +451,19 @@ static PyObject *ph_get_operand_info(
|
||||
{
|
||||
break;
|
||||
}
|
||||
return Py_BuildValue("(i" PY_FMT64 "Kii)",
|
||||
opinf.modified,
|
||||
opinf.ea,
|
||||
opinf.value.ival,
|
||||
opinf.debregidx,
|
||||
opinf.value_size);
|
||||
ok = true;
|
||||
} while (false);
|
||||
Py_RETURN_NONE;
|
||||
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( ok )
|
||||
return Py_BuildValue("(i" PY_FMT64 "Kii)",
|
||||
opinf.modified,
|
||||
opinf.ea,
|
||||
opinf.value.ival,
|
||||
opinf.debregidx,
|
||||
opinf.value_size);
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -826,6 +844,7 @@ public:
|
||||
bool /*use32*/,
|
||||
const char * /*line*/)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
};
|
||||
@ -889,6 +908,8 @@ public:
|
||||
//-------------------------------------------------------------------------
|
||||
int idaapi IDP_Callback(void *ud, int notification_code, va_list va)
|
||||
{
|
||||
// This hook gets called from the kernel. Ensure we hold the GIL.
|
||||
PYW_GIL_GET;
|
||||
IDP_Hooks *proxy = (IDP_Hooks *)ud;
|
||||
int ret = 0;
|
||||
try
|
||||
@ -910,16 +931,16 @@ int idaapi IDP_Callback(void *ud, int notification_code, va_list va)
|
||||
case processor_t::custom_outop:
|
||||
{
|
||||
op_t *op = va_arg(va, op_t *);
|
||||
PyObject *py_obj = create_idaapi_linked_class_instance(S_PY_OP_T_CLSNAME, op);
|
||||
ref_t py_obj(create_idaapi_linked_class_instance(S_PY_OP_T_CLSNAME, op));
|
||||
if ( py_obj == NULL )
|
||||
break;
|
||||
ret = proxy->custom_outop(py_obj) ? 2 : 0;
|
||||
Py_XDECREF(py_obj);
|
||||
ret = proxy->custom_outop(py_obj.o) ? 2 : 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case processor_t::custom_mnem:
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyObject *py_ret = proxy->custom_mnem();
|
||||
if ( py_ret != NULL && PyString_Check(py_ret) )
|
||||
{
|
||||
@ -1051,6 +1072,7 @@ int idaapi IDP_Callback(void *ud, int notification_code, va_list va)
|
||||
// Extract user buffer (we hardcode the MAXSTR size limit)
|
||||
uchar *bin = va_arg(va, uchar *);
|
||||
// Call python
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyObject *py_buffer = proxy->assemble(ea, cs, ip, use32, line);
|
||||
if ( py_buffer != NULL && PyString_Check(py_buffer) )
|
||||
{
|
||||
@ -1370,6 +1392,7 @@ int idaapi IDP_Callback(void *ud, int notification_code, va_list va)
|
||||
catch (Swig::DirectorException &e)
|
||||
{
|
||||
msg("Exception in IDP Hook function: %s\n", e.getMessage());
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( PyErr_Occurred() )
|
||||
PyErr_Print();
|
||||
}
|
||||
@ -1379,6 +1402,9 @@ int idaapi IDP_Callback(void *ud, int notification_code, va_list va)
|
||||
//---------------------------------------------------------------------------
|
||||
int idaapi IDB_Callback(void *ud, int notification_code, va_list va)
|
||||
{
|
||||
// This hook gets called from the kernel. Ensure we hold the GIL.
|
||||
PYW_GIL_GET;
|
||||
|
||||
class IDB_Hooks *proxy = (class IDB_Hooks *)ud;
|
||||
ea_t ea, ea2;
|
||||
bool repeatable_cmt;
|
||||
@ -1550,10 +1576,9 @@ int idaapi IDB_Callback(void *ud, int notification_code, va_list va)
|
||||
catch (Swig::DirectorException &e)
|
||||
{
|
||||
msg("Exception in IDB Hook function: %s\n", e.getMessage());
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
PyErr_Print();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
928
swig/kernwin.i
928
swig/kernwin.i
File diff suppressed because it is too large
Load Diff
25
swig/lines.i
25
swig/lines.i
@ -85,10 +85,12 @@ static void idaapi s_py_get_user_defined_prefix(
|
||||
char *buf,
|
||||
size_t bufsize)
|
||||
{
|
||||
PyObject *py_ret = PyObject_CallFunction(
|
||||
py_get_user_defined_prefix,
|
||||
PY_FMT64 "iis" PY_FMT64,
|
||||
ea, lnnum, indent, line, bufsize);
|
||||
PYW_GIL_GET;
|
||||
newref_t py_ret(
|
||||
PyObject_CallFunction(
|
||||
py_get_user_defined_prefix,
|
||||
PY_FMT64 "iis" PY_FMT64,
|
||||
ea, lnnum, indent, line, bufsize));
|
||||
|
||||
// Error? Display it
|
||||
// No error? Copy the buffer
|
||||
@ -96,14 +98,13 @@ static void idaapi s_py_get_user_defined_prefix(
|
||||
{
|
||||
Py_ssize_t py_len;
|
||||
char *py_str;
|
||||
if ( PyString_AsStringAndSize(py_ret, &py_str, &py_len) != -1 )
|
||||
if ( PyString_AsStringAndSize(py_ret.o, &py_str, &py_len) != -1 )
|
||||
{
|
||||
memcpy(buf, py_str, qmin(bufsize, py_len));
|
||||
if ( py_len < bufsize )
|
||||
buf[py_len] = '\0';
|
||||
}
|
||||
}
|
||||
Py_XDECREF(py_ret);
|
||||
}
|
||||
//</code(py_lines)>
|
||||
%}
|
||||
@ -138,6 +139,7 @@ def set_user_defined_prefix(width, callback):
|
||||
*/
|
||||
static PyObject *py_set_user_defined_prefix(size_t width, PyObject *pycb)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( width == 0 || pycb == Py_None )
|
||||
{
|
||||
// Release old callback reference
|
||||
@ -183,6 +185,7 @@ def tag_remove(colstr):
|
||||
*/
|
||||
PyObject *py_tag_remove(const char *instr)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
size_t sz = strlen(instr);
|
||||
char *buf = new char[sz + 5];
|
||||
if ( buf == NULL )
|
||||
@ -208,6 +211,7 @@ PyObject *py_tag_addr(ea_t ea)
|
||||
{
|
||||
char buf[100];
|
||||
tag_addr(buf, buf + sizeof(buf), ea);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return PyString_FromString(buf);
|
||||
}
|
||||
|
||||
@ -253,6 +257,7 @@ PyObject *py_generate_disassembly(
|
||||
bool as_stack,
|
||||
bool notags)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( max_lines <= 0 )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
@ -261,7 +266,7 @@ PyObject *py_generate_disassembly(
|
||||
int lnnum;
|
||||
int nlines = generate_disassembly(ea, lines, max_lines, &lnnum, as_stack);
|
||||
|
||||
PyObject *py_tuple = PyTuple_New(nlines);
|
||||
newref_t py_tuple(PyTuple_New(nlines));
|
||||
for ( int i=0; i<nlines; i++ )
|
||||
{
|
||||
const char *s = lines[i];
|
||||
@ -272,13 +277,11 @@ PyObject *py_generate_disassembly(
|
||||
tag_remove(s, &qbuf[0], line_len);
|
||||
s = (const char *)&qbuf[0];
|
||||
}
|
||||
PyTuple_SetItem(py_tuple, i, PyString_FromString(s));
|
||||
PyTuple_SetItem(py_tuple.o, i, PyString_FromString(s));
|
||||
qfree(lines[i]);
|
||||
}
|
||||
delete [] lines;
|
||||
PyObject *py_result = Py_BuildValue("(iO)", lnnum, py_tuple);
|
||||
Py_DECREF(py_tuple);
|
||||
return py_result;
|
||||
return Py_BuildValue("(iO)", lnnum, py_tuple.o);
|
||||
}
|
||||
//</inline(py_lines)>
|
||||
|
||||
|
@ -68,6 +68,7 @@
|
||||
%ignore IDP_DESC_START;
|
||||
%ignore IDP_DESC_END;
|
||||
%ignore get_idp_desc;
|
||||
%ignore get_idp_descs;
|
||||
%ignore init_fileregions;
|
||||
%ignore term_fileregions;
|
||||
%ignore save_fileregions;
|
||||
@ -108,6 +109,8 @@
|
||||
%ignore is_in_loader;
|
||||
%ignore get_ids_filename;
|
||||
%ignore is_embedded_dbfile_ext;
|
||||
%ignore cpp_namespaces;
|
||||
%ignore max_trusted_idb_count;
|
||||
|
||||
%ignore mem2base;
|
||||
%rename (mem2base) py_mem2base;
|
||||
@ -147,8 +150,11 @@ static int py_mem2base(PyObject *py_mem, ea_t ea, long fpos = -1)
|
||||
{
|
||||
Py_ssize_t len;
|
||||
char *buf;
|
||||
if ( PyString_AsStringAndSize(py_mem, &buf, &len) == -1 )
|
||||
return 0;
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( PyString_AsStringAndSize(py_mem, &buf, &len) == -1 )
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mem2base((void *)buf, ea, ea+len, fpos);
|
||||
}
|
||||
@ -169,6 +175,7 @@ def load_plugin(name):
|
||||
static PyObject *py_load_plugin(const char *name)
|
||||
{
|
||||
plugin_t *r = load_plugin(name);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( r == NULL )
|
||||
Py_RETURN_NONE;
|
||||
else
|
||||
@ -189,10 +196,20 @@ def run_plugin(plg):
|
||||
*/
|
||||
static bool py_run_plugin(PyObject *plg, int arg)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyCObject_Check(plg) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return run_plugin((plugin_t *)PyCObject_AsVoidPtr(plg), arg);
|
||||
{
|
||||
plugin_t *p = (plugin_t *)PyCObject_AsVoidPtr(plg);
|
||||
bool rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = run_plugin(p, arg);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
//</inline(py_loader)>
|
||||
|
98
swig/nalt.i
98
swig/nalt.i
@ -35,53 +35,35 @@ static int idaapi py_import_enum_cb(
|
||||
if ( name == NULL )
|
||||
name = get_true_name(BADADDR, ea, name_buf, sizeof(name_buf));
|
||||
|
||||
PyObject *py_name;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
ref_t py_name;
|
||||
if ( name == NULL )
|
||||
{
|
||||
py_name = Py_None;
|
||||
Py_INCREF(Py_None);
|
||||
}
|
||||
py_name = borref_t(Py_None);
|
||||
else
|
||||
{
|
||||
py_name = PyString_FromString(name);
|
||||
}
|
||||
py_name = newref_t(PyString_FromString(name));
|
||||
|
||||
PyObject *py_ord = Py_BuildValue(PY_FMT64, pyul_t(ord));
|
||||
PyObject *py_ea = Py_BuildValue(PY_FMT64, pyul_t(ea));
|
||||
PYW_GIL_ENSURE;
|
||||
PyObject *py_result = PyObject_CallFunctionObjArgs(
|
||||
(PyObject *)param,
|
||||
py_ea,
|
||||
py_name,
|
||||
py_ord,
|
||||
NULL);
|
||||
PYW_GIL_RELEASE;
|
||||
|
||||
int r = py_result != NULL && PyObject_IsTrue(py_result) ? 1 : 0;
|
||||
|
||||
Py_DECREF(py_ea);
|
||||
Py_DECREF(py_name);
|
||||
Py_DECREF(py_ord);
|
||||
Py_XDECREF(py_result);
|
||||
|
||||
return r;
|
||||
newref_t py_ord(Py_BuildValue(PY_FMT64, pyul_t(ord)));
|
||||
newref_t py_ea(Py_BuildValue(PY_FMT64, pyul_t(ea)));
|
||||
newref_t py_result(
|
||||
PyObject_CallFunctionObjArgs(
|
||||
(PyObject *)param,
|
||||
py_ea.o,
|
||||
py_name.o,
|
||||
py_ord.o,
|
||||
NULL));
|
||||
return py_result != NULL && PyObject_IsTrue(py_result.o) ? 1 : 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
switch_info_ex_t *switch_info_ex_t_get_clink(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyObject_HasAttrString(self, S_CLINK_NAME) )
|
||||
return NULL;
|
||||
|
||||
switch_info_ex_t *r;
|
||||
PyObject *attr = PyObject_GetAttrString(self, S_CLINK_NAME);
|
||||
if ( PyCObject_Check(attr) )
|
||||
r = (switch_info_ex_t *) PyCObject_AsVoidPtr(attr);
|
||||
else
|
||||
r = NULL;
|
||||
|
||||
Py_DECREF(attr);
|
||||
return r;
|
||||
newref_t attr(PyObject_GetAttrString(self, S_CLINK_NAME));
|
||||
return PyCObject_Check(attr.o) ? ((switch_info_ex_t *) PyCObject_AsVoidPtr(attr.o)) : NULL;
|
||||
}
|
||||
//</code(py_nalt)>
|
||||
%}
|
||||
@ -108,10 +90,11 @@ def get_import_module_name(path, fname, callback):
|
||||
*/
|
||||
static PyObject *py_get_import_module_name(int mod_index)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
char buf[MAXSTR];
|
||||
if ( !get_import_module_name(mod_index, buf, sizeof(buf)) )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
|
||||
return PyString_FromString(buf);
|
||||
}
|
||||
|
||||
@ -130,14 +113,16 @@ def get_switch_info_ex(ea):
|
||||
PyObject *py_get_switch_info_ex(ea_t ea)
|
||||
{
|
||||
switch_info_ex_t *ex = new switch_info_ex_t();
|
||||
PyObject *py_obj;
|
||||
if ( ::get_switch_info_ex(ea, ex, sizeof(switch_info_ex_t)) <= 0
|
||||
ref_t py_obj;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( ::get_switch_info_ex(ea, ex, sizeof(switch_info_ex_t)) <= 0
|
||||
|| (py_obj = create_idaapi_linked_class_instance(S_PY_SWIEX_CLSNAME, ex)) == NULL )
|
||||
{
|
||||
delete ex;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
return py_obj;
|
||||
py_obj.incref();
|
||||
return py_obj.o;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -151,7 +136,7 @@ def create_switch_xrefs(insn_ea, si):
|
||||
will call it for switch tables
|
||||
|
||||
Note: Custom switch information are not supported yet.
|
||||
|
||||
|
||||
@param insn_ea: address of the 'indirect jump' instruction
|
||||
@param si: switch information
|
||||
|
||||
@ -179,7 +164,7 @@ idaman bool ida_export py_create_switch_xrefs(
|
||||
def create_switch_table(insn_ea, si):
|
||||
"""
|
||||
Create switch table from the switch information
|
||||
|
||||
|
||||
@param insn_ea: address of the 'indirect jump' instruction
|
||||
@param si: switch information
|
||||
|
||||
@ -195,7 +180,7 @@ idaman bool ida_export py_create_switch_table(
|
||||
switch_info_ex_t *swi = switch_info_ex_t_get_clink(py_swi);
|
||||
if ( swi == NULL )
|
||||
return false;
|
||||
|
||||
|
||||
create_switch_table(insn_ea, swi);
|
||||
return true;
|
||||
}
|
||||
@ -254,9 +239,9 @@ def enum_import_names(mod_index, callback):
|
||||
*/
|
||||
static int py_enum_import_names(int mod_index, PyObject *py_cb)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyCallable_Check(py_cb) )
|
||||
return -1;
|
||||
|
||||
return enum_import_names(mod_index, py_import_enum_cb, py_cb);
|
||||
}
|
||||
|
||||
@ -264,12 +249,14 @@ static int py_enum_import_names(int mod_index, PyObject *py_cb)
|
||||
static PyObject *switch_info_ex_t_create()
|
||||
{
|
||||
switch_info_ex_t *inst = new switch_info_ex_t();
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return PyCObject_FromVoidPtr(inst, NULL);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
static bool switch_info_ex_t_destroy(PyObject *py_obj)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyCObject_Check(py_obj) )
|
||||
return false;
|
||||
switch_info_ex_t *inst = (switch_info_ex_t *) PyCObject_AsVoidPtr(py_obj);
|
||||
@ -295,6 +282,7 @@ static bool switch_info_ex_t_assign(PyObject *self, PyObject *other)
|
||||
static PyObject *switch_info_ex_t_get_regdtyp(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("b", (char)link->regdtyp);
|
||||
@ -304,12 +292,14 @@ static void switch_info_ex_t_set_regdtyp(PyObject *self, PyObject *value)
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
link->regdtyp = (char)PyInt_AsLong(value);
|
||||
}
|
||||
|
||||
static PyObject *switch_info_ex_t_get_flags2(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("i", link->flags2);
|
||||
@ -319,12 +309,14 @@ static void switch_info_ex_t_set_flags2(PyObject *self, PyObject *value)
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
link->flags2 = (int)PyInt_AsLong(value);
|
||||
}
|
||||
|
||||
static PyObject *switch_info_ex_t_get_jcases(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("i", link->jcases);
|
||||
@ -334,12 +326,14 @@ static void switch_info_ex_t_set_jcases(PyObject *self, PyObject *value)
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
link->jcases = (int)PyInt_AsLong(value);
|
||||
}
|
||||
|
||||
static PyObject *switch_info_ex_t_get_regnum(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("i", (int)link->regnum);
|
||||
@ -349,12 +343,14 @@ static void switch_info_ex_t_set_regnum(PyObject *self, PyObject *value)
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
link->regnum = (int)PyInt_AsLong(value);
|
||||
}
|
||||
|
||||
static PyObject *switch_info_ex_t_get_flags(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("H", (ushort)link->flags);
|
||||
@ -364,12 +360,14 @@ static void switch_info_ex_t_set_flags(PyObject *self, PyObject *value)
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
link->flags = (uint16)PyInt_AsLong(value);
|
||||
}
|
||||
|
||||
static PyObject *switch_info_ex_t_get_ncases(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue("H", (uint16)link->ncases);
|
||||
@ -379,12 +377,14 @@ static void switch_info_ex_t_set_ncases(PyObject *self, PyObject *value)
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
link->ncases = (ushort)PyInt_AsLong(value);
|
||||
}
|
||||
|
||||
static PyObject *switch_info_ex_t_get_defjump(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue(PY_FMT64, (pyul_t)link->defjump);
|
||||
@ -394,6 +394,7 @@ static void switch_info_ex_t_set_defjump(PyObject *self, PyObject *value)
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
uint64 v(0); PyW_GetNumber(value, &v);
|
||||
link->defjump = (pyul_t)v;
|
||||
}
|
||||
@ -410,6 +411,7 @@ static void switch_info_ex_t_set_jumps(PyObject *self, PyObject *value)
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
uint64 v(0); PyW_GetNumber(value, &v);
|
||||
link->jumps = (pyul_t)v;
|
||||
}
|
||||
@ -417,6 +419,7 @@ static void switch_info_ex_t_set_jumps(PyObject *self, PyObject *value)
|
||||
static PyObject *switch_info_ex_t_get_elbase(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue(PY_FMT64, (pyul_t)link->elbase);
|
||||
@ -427,6 +430,7 @@ static void switch_info_ex_t_set_elbase(PyObject *self, PyObject *value)
|
||||
if ( link == NULL )
|
||||
return;
|
||||
uint64 v(0);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyW_GetNumber(value, &v);
|
||||
link->elbase = (pyul_t)v;
|
||||
}
|
||||
@ -434,6 +438,7 @@ static void switch_info_ex_t_set_elbase(PyObject *self, PyObject *value)
|
||||
static PyObject *switch_info_ex_t_get_startea(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue(PY_FMT64, (pyul_t)link->startea);
|
||||
@ -444,6 +449,7 @@ static void switch_info_ex_t_set_startea(PyObject *self, PyObject *value)
|
||||
if ( link == NULL )
|
||||
return;
|
||||
uint64 v(0);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyW_GetNumber(value, &v);
|
||||
link->startea = (pyul_t)v;
|
||||
}
|
||||
@ -451,6 +457,7 @@ static void switch_info_ex_t_set_startea(PyObject *self, PyObject *value)
|
||||
static PyObject *switch_info_ex_t_get_custom(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue(PY_FMT64, (pyul_t)link->custom);
|
||||
@ -461,6 +468,7 @@ static void switch_info_ex_t_set_custom(PyObject *self, PyObject *value)
|
||||
if ( link == NULL )
|
||||
return;
|
||||
uint64 v(0);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyW_GetNumber(value, &v);
|
||||
link->custom = (pyul_t)v;
|
||||
}
|
||||
@ -468,6 +476,7 @@ static void switch_info_ex_t_set_custom(PyObject *self, PyObject *value)
|
||||
static PyObject *switch_info_ex_t_get_ind_lowcase(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue(PY_FMT64, (pyul_t)link->ind_lowcase);
|
||||
@ -478,6 +487,7 @@ static void switch_info_ex_t_set_ind_lowcase(PyObject *self, PyObject *value)
|
||||
if ( link == NULL )
|
||||
return;
|
||||
uint64 v(0);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyW_GetNumber(value, &v);
|
||||
link->ind_lowcase = (pyul_t)v;
|
||||
}
|
||||
@ -485,6 +495,7 @@ static void switch_info_ex_t_set_ind_lowcase(PyObject *self, PyObject *value)
|
||||
static PyObject *switch_info_ex_t_get_values_lowcase(PyObject *self)
|
||||
{
|
||||
switch_info_ex_t *link = switch_info_ex_t_get_clink(self);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
return Py_BuildValue(PY_FMT64, (pyul_t)link->values);
|
||||
@ -495,6 +506,7 @@ static void switch_info_ex_t_set_values_lowcase(PyObject *self, PyObject *value)
|
||||
if ( link == NULL )
|
||||
return;
|
||||
uint64 v(0);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
PyW_GetNumber(value, &v);
|
||||
link->values = (pyul_t)v;
|
||||
}
|
||||
|
17
swig/name.i
17
swig/name.i
@ -39,16 +39,19 @@ PyObject *py_get_debug_names(ea_t ea1, ea_t ea2)
|
||||
{
|
||||
// Get debug names
|
||||
ea_name_vec_t names;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
get_debug_names(ea1, ea2, names);
|
||||
Py_END_ALLOW_THREADS;
|
||||
PyObject *dict = Py_BuildValue("{}");
|
||||
if (dict == NULL)
|
||||
return NULL;
|
||||
|
||||
for (ea_name_vec_t::iterator it=names.begin();it!=names.end();++it)
|
||||
if (dict != NULL)
|
||||
{
|
||||
PyDict_SetItem(dict,
|
||||
Py_BuildValue(PY_FMT64, it->ea),
|
||||
PyString_FromString(it->name.c_str()));
|
||||
for (ea_name_vec_t::iterator it=names.begin();it!=names.end();++it)
|
||||
{
|
||||
PyDict_SetItem(dict,
|
||||
Py_BuildValue(PY_FMT64, it->ea),
|
||||
PyString_FromString(it->name.c_str()));
|
||||
}
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
|
@ -69,10 +69,12 @@
|
||||
%ignore netnode::set_close_flag;
|
||||
%ignore netnode::reserve_nodes;
|
||||
%ignore netnode::validate;
|
||||
%ignore netnode::upgrade16;
|
||||
%ignore netnode::upgrade;
|
||||
%ignore netnode::compress;
|
||||
%ignore netnode::inited;
|
||||
%ignore netnode::init;
|
||||
%ignore netnode::can_write;
|
||||
%ignore netnode::flush;
|
||||
%ignore netnode::get_linput;
|
||||
%ignore netnode::term;
|
||||
|
10
swig/pro.i
10
swig/pro.i
@ -98,7 +98,8 @@ $result = PyLong_FromUnsignedLongLong((unsigned long long) $1);
|
||||
%ignore BELOW_NORMAL_PRIORITY_CLASS;
|
||||
%ignore parse_command_line;
|
||||
%ignore parse_command_line2;
|
||||
%rename (parse_command_line2) py_parse_command_line;
|
||||
%ignore parse_command_line3;
|
||||
%rename (parse_command_line3) py_parse_command_line;
|
||||
%ignore qgetenv;
|
||||
%ignore qsetenv;
|
||||
%ignore qctime;
|
||||
@ -126,13 +127,6 @@ public:
|
||||
const char *c_str() const { return self->c_str(); }
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// for obscure reasons swig can't get past this one on its own, it needs a dummy declaration.
|
||||
class strvec_t {
|
||||
public:
|
||||
qstring& at(int _idx) { return self->at(_idx).line; }
|
||||
size_t size() const { return self->size(); }
|
||||
};
|
||||
|
||||
class qtype {
|
||||
public:
|
||||
|
@ -19,6 +19,43 @@
|
||||
%ignore is_ephemeral_segm;
|
||||
%ignore correct_address;
|
||||
|
||||
%{
|
||||
void segment_t_startEA_set(segment_t *segm, ea_t newea)
|
||||
{
|
||||
if ( getseg(segm->startEA) == segm )
|
||||
{
|
||||
PyErr_SetString(PyExc_AttributeError, "Can't modify startEA, please use set_segm_start() instead");
|
||||
}
|
||||
else
|
||||
{
|
||||
segm->startEA = newea;
|
||||
}
|
||||
}
|
||||
ea_t segment_t_startEA_get(segment_t *segm)
|
||||
{
|
||||
return segm->startEA;
|
||||
}
|
||||
void segment_t_endEA_set(segment_t *segm, ea_t newea)
|
||||
{
|
||||
if ( getseg(segm->startEA) == segm )
|
||||
{
|
||||
PyErr_SetString(PyExc_AttributeError, "Can't modify endEA, please use set_segm_end() instead");
|
||||
}
|
||||
else
|
||||
{
|
||||
segm->endEA = newea;
|
||||
}
|
||||
}
|
||||
ea_t segment_t_endEA_get(segment_t *segm)
|
||||
{
|
||||
return segm->endEA;
|
||||
}
|
||||
%}
|
||||
%extend segment_t
|
||||
{
|
||||
ea_t startEA;
|
||||
ea_t endEA;
|
||||
}
|
||||
%include "segment.hpp"
|
||||
|
||||
%inline %{
|
||||
|
@ -1,14 +1,14 @@
|
||||
// Ignore kernel-only symbols
|
||||
%ignore createSRarea;
|
||||
%ignore killSRareas;
|
||||
%ignore delSRarea;
|
||||
%ignore splitSRarea;
|
||||
%ignore SRareaStart;
|
||||
%ignore SRareaEnd;
|
||||
%ignore create_srarea;
|
||||
%ignore kill_srareras;
|
||||
%ignore del_srarea;
|
||||
%ignore break_srarea;
|
||||
%ignore set_srarea_start;
|
||||
%ignore set_srarea_end;
|
||||
%ignore repairSRarea;
|
||||
%ignore SRinit;
|
||||
%ignore SRterm;
|
||||
%ignore SRsave;
|
||||
%ignore init_srarea;
|
||||
%ignore term_srarea;
|
||||
%ignore save_srarea;
|
||||
|
||||
#define R_es 29
|
||||
#define R_cs 30
|
||||
|
@ -44,6 +44,7 @@
|
||||
}
|
||||
|
||||
%typemap(argout) (TYPEMAP,SIZE) {
|
||||
Py_XDECREF(resultobj);
|
||||
if (result > 0)
|
||||
{
|
||||
resultobj = PyString_FromString($1);
|
||||
@ -91,6 +92,7 @@
|
||||
/* REMOVING ssize_t return value in $symname */
|
||||
}
|
||||
%typemap(argout) (TYPEMAP,SIZE) {
|
||||
Py_XDECREF(resultobj);
|
||||
if (result > 0)
|
||||
{
|
||||
resultobj = PyString_FromStringAndSize((char *)$1, result);
|
||||
@ -117,6 +119,7 @@
|
||||
/* REMOVING ssize_t return value in $symname */
|
||||
}
|
||||
%typemap(argout) (TYPEMAP,SIZE) {
|
||||
Py_XDECREF(resultobj);
|
||||
if (result)
|
||||
{
|
||||
resultobj = PyString_FromStringAndSize((char *)$1, *$2);
|
||||
@ -151,3 +154,32 @@
|
||||
}
|
||||
$1 = ea_t($1_temp);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// Convert qstring
|
||||
%typemap(in) qstring*
|
||||
{
|
||||
char *buf;
|
||||
Py_ssize_t length;
|
||||
int success = PyString_AsStringAndSize($input, &buf, &length);
|
||||
if ( success > -1 )
|
||||
{
|
||||
$1 = new qstring(buf, length);
|
||||
}
|
||||
}
|
||||
%typemap(freearg) qstring*
|
||||
{
|
||||
delete $1;
|
||||
}
|
||||
%typemap(out) qstring*
|
||||
{
|
||||
$result = PyString_FromStringAndSize($1->c_str(), $1->length());
|
||||
}
|
||||
#ifdef __EA64__
|
||||
%apply longlong *INOUT { sval_t *value };
|
||||
%apply ulonglong *INOUT { ea_t *addr };
|
||||
%apply ulonglong *INOUT { sel_t *sel };
|
||||
#else
|
||||
%apply int *INOUT { sval_t *value };
|
||||
%apply unsigned int *INOUT { ea_t *addr };
|
||||
%apply unsigned int *INOUT { sel_t *sel };
|
||||
#endif
|
||||
|
541
swig/typeinf.i
541
swig/typeinf.i
@ -49,6 +49,8 @@
|
||||
%ignore til_add_macro;
|
||||
%ignore til_next_macro;
|
||||
|
||||
%ignore parse_subtype;
|
||||
%ignore calc_type_size;
|
||||
%ignore get_type_size;
|
||||
%ignore get_type_size0;
|
||||
%ignore skip_type;
|
||||
@ -62,6 +64,7 @@
|
||||
%ignore print_type;
|
||||
%ignore show_type;
|
||||
%ignore show_plist;
|
||||
%ignore show_bytes;
|
||||
%ignore skip_function_arg_names;
|
||||
%ignore perform_funcarg_conversion;
|
||||
%ignore get_argloc_info;
|
||||
@ -85,11 +88,17 @@
|
||||
%ignore get_named_type_size;
|
||||
|
||||
%ignore decorate_name;
|
||||
%ignore decorate_name3;
|
||||
%ignore gen_decorate_name;
|
||||
%ignore calc_bare_name;
|
||||
%ignore calc_bare_name3;
|
||||
%ignore calc_cpp_name;
|
||||
%ignore calc_c_cpp_name;
|
||||
%ignore calc_c_cpp_name3;
|
||||
%ignore predicate_t;
|
||||
%ignore local_predicate_t;
|
||||
%ignore tinfo_predicate_t;
|
||||
%ignore local_tinfo_predicate_t;
|
||||
%ignore choose_named_type;
|
||||
%ignore get_default_align;
|
||||
%ignore align_size;
|
||||
@ -123,6 +132,8 @@
|
||||
%rename (apply_type_to_stkarg) py_apply_type_to_stkarg;
|
||||
%ignore print_type;
|
||||
%rename (print_type) py_print_type;
|
||||
%rename (calc_type_size) py_calc_type_size;
|
||||
%rename (apply_type) py_apply_type;
|
||||
|
||||
%ignore use_regarg_type_cb;
|
||||
%ignore set_op_type_t;
|
||||
@ -143,29 +154,17 @@
|
||||
%ignore extend_sign;
|
||||
|
||||
// Kernel-only symbols
|
||||
%ignore init_til;
|
||||
%ignore save_til;
|
||||
%ignore term_til;
|
||||
%ignore determine_til;
|
||||
%ignore sync_from_til;
|
||||
%ignore get_tilpath;
|
||||
%ignore autoload_til;
|
||||
%ignore get_idainfo_by_type;
|
||||
%ignore apply_callee_type;
|
||||
%ignore propagate_stkargs;
|
||||
%ignore build_anon_type_name;
|
||||
%ignore type_names;
|
||||
%ignore get_compiler_id;
|
||||
%ignore reloc_info_t;
|
||||
%ignore relobj_t;
|
||||
%ignore regobj_t;
|
||||
%ignore build_func_type;
|
||||
|
||||
%ignore append_type_name;
|
||||
%ignore for_all_types_ex;
|
||||
%ignore fix_idb_type;
|
||||
%ignore pdb2ti;
|
||||
%ignore process_sdacl_padding;
|
||||
%ignore enum_type_data_t::is_signed;
|
||||
%ignore enum_type_data_t::is_unsigned;
|
||||
%ignore enum_type_data_t::get_sign;
|
||||
%ignore bitfield_type_data_t::serialize;
|
||||
%ignore func_type_data_t::serialize;
|
||||
%ignore func_type_data_t::deserialize;
|
||||
%ignore enum_type_data_t::get_enum_base_type;
|
||||
%ignore enum_type_data_t::deserialize_enum;
|
||||
%ignore valstr_deprecated_t;
|
||||
%ignore valinfo_deprecated_t;
|
||||
|
||||
%include "typeinf.hpp"
|
||||
|
||||
@ -174,6 +173,7 @@
|
||||
%rename (load_til) load_til_wrap;
|
||||
%rename (get_type_size0) py_get_type_size0;
|
||||
%rename (idc_get_type_raw) py_idc_get_type_raw;
|
||||
%rename (idc_get_local_type_raw) py_idc_get_local_type_raw;
|
||||
%rename (unpack_object_from_idb) py_unpack_object_from_idb;
|
||||
%rename (unpack_object_from_bv) py_unpack_object_from_bv;
|
||||
%rename (pack_object_to_idb) py_pack_object_to_idb;
|
||||
@ -183,22 +183,26 @@
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *idc_parse_decl(til_t *ti, const char *decl, int flags)
|
||||
{
|
||||
qtype fields, type;
|
||||
tinfo_t tif;
|
||||
qstring name;
|
||||
bool ok = parse_decl(ti, decl, &name, &type, &fields, flags);
|
||||
if ( !ok )
|
||||
Py_RETURN_NONE;
|
||||
qtype fields, type;
|
||||
bool ok = parse_decl2(ti, decl, &name, &tif, flags);
|
||||
if ( ok )
|
||||
ok = tif.serialize(&type, &fields, NULL, SUDT_FAST);
|
||||
|
||||
return Py_BuildValue("(sss)",
|
||||
name.c_str(),
|
||||
(char *)type.c_str(),
|
||||
(char *)fields.c_str());
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( ok )
|
||||
return Py_BuildValue("(sss)",
|
||||
name.c_str(),
|
||||
(char *)type.c_str(),
|
||||
(char *)fields.c_str());
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
#<pydoc>
|
||||
def get_type_size0(ti, tp):
|
||||
def calc_type_size(ti, tp):
|
||||
"""
|
||||
Returns the size of a type
|
||||
@param ti: Type info. 'idaapi.cvar.idati' can be passed.
|
||||
@ -210,25 +214,69 @@ def get_type_size0(ti, tp):
|
||||
pass
|
||||
#</pydoc>
|
||||
*/
|
||||
PyObject *py_get_type_size0(const til_t *ti, PyObject *tp)
|
||||
PyObject *py_calc_type_size(const til_t *ti, PyObject *tp)
|
||||
{
|
||||
if ( !PyString_Check(tp) )
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( PyString_Check(tp) )
|
||||
{
|
||||
// To avoid release of 'data' during Py_BEGIN|END_ALLOW_THREADS section.
|
||||
borref_t tpref(tp);
|
||||
const type_t *data = (type_t *)PyString_AsString(tp);
|
||||
size_t sz;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
tinfo_t tif;
|
||||
tif.deserialize(ti, &data, NULL, NULL);
|
||||
sz = tif.get_size();
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( sz != BADSIZE )
|
||||
return PyInt_FromLong(sz);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "String expected!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t sz = get_type_size0(ti, (type_t *)PyString_AsString(tp));
|
||||
if ( sz == BADSIZE )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
return PyInt_FromLong(sz);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
#<pydoc>
|
||||
def print_type(ea, on_line):
|
||||
def apply_type(ti, ea, tp_name, py_type, py_fields, flags)
|
||||
"""
|
||||
Apply the specified type to the address
|
||||
@param ti: Type info. 'idaapi.cvar.idati' can be passed.
|
||||
@param py_type: type string
|
||||
@param py_fields: type fields
|
||||
@param ea: the address of the object
|
||||
@param flags: combination of TINFO_... constants or 0
|
||||
@return: Boolean
|
||||
"""
|
||||
pass
|
||||
#</pydoc>
|
||||
*/
|
||||
static bool py_apply_type(til_t *ti, PyObject *py_type, PyObject *py_fields, ea_t ea, int flags)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyString_Check(py_type) && !PyString_Check(py_fields) )
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "Typestring must be passed!");
|
||||
return NULL;
|
||||
}
|
||||
const type_t *type = (const type_t *) PyString_AsString(py_type);
|
||||
const p_list *fields = (const p_list *) PyString_AsString(py_fields);
|
||||
bool rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
tinfo_t tif;
|
||||
rc = tif.deserialize(ti, &type, &fields, NULL) && apply_tinfo2(ea, tif, flags);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
#<pydoc>
|
||||
def print_type(ea, one_line):
|
||||
"""
|
||||
Returns the type of an item
|
||||
@return:
|
||||
@ -240,14 +288,13 @@ def print_type(ea, on_line):
|
||||
*/
|
||||
static PyObject *py_print_type(ea_t ea, bool one_line)
|
||||
{
|
||||
char buf[MAXSTR];
|
||||
if ( print_type2(ea, buf, sizeof(buf), one_line ? PRTYPE_1LINE : PRTYPE_MULTI) )
|
||||
{
|
||||
qstrncat(buf, ";", sizeof(buf));
|
||||
char buf[64*MAXSTR];
|
||||
int flags = PRTYPE_SEMI | (one_line ? PRTYPE_1LINE : PRTYPE_MULTI);
|
||||
bool ok = print_type2(ea, buf, sizeof(buf), one_line ? PRTYPE_1LINE : PRTYPE_MULTI);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( ok )
|
||||
return PyString_FromString(buf);
|
||||
}
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -268,17 +315,24 @@ PyObject *py_unpack_object_from_idb(
|
||||
ea_t ea,
|
||||
int pio_flags = 0)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyString_Check(py_type) && !PyString_Check(py_fields) )
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "Typestring must be passed!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// To avoid release of 'type'/'fields' during Py_BEGIN|END_ALLOW_THREADS section.
|
||||
borref_t py_type_ref(py_type);
|
||||
borref_t py_fields_ref(py_fields);
|
||||
|
||||
// Unpack
|
||||
type_t *type = (type_t *) PyString_AsString(py_type);
|
||||
p_list *fields = (p_list *) PyString_AsString(py_fields);
|
||||
idc_value_t idc_obj;
|
||||
error_t err = unpack_object_from_idb(
|
||||
error_t err;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
err = unpack_object_from_idb(
|
||||
&idc_obj,
|
||||
ti,
|
||||
type,
|
||||
@ -286,22 +340,21 @@ PyObject *py_unpack_object_from_idb(
|
||||
ea,
|
||||
NULL,
|
||||
pio_flags);
|
||||
Py_END_ALLOW_THREADS;
|
||||
|
||||
// Unpacking failed?
|
||||
if ( err != eOk )
|
||||
return Py_BuildValue("(ii)", 0, err);
|
||||
|
||||
// Convert
|
||||
PyObject *py_ret(NULL);
|
||||
ref_t py_ret;
|
||||
err = idcvar_to_pyvar(idc_obj, &py_ret);
|
||||
|
||||
// Conversion failed?
|
||||
if ( err != CIP_OK )
|
||||
return Py_BuildValue("(ii)", 0, err);
|
||||
|
||||
PyObject *py_result = Py_BuildValue("(iO)", 1, py_ret);
|
||||
Py_DECREF(py_ret);
|
||||
return py_result;
|
||||
else
|
||||
return Py_BuildValue("(iO)", 1, py_ret.o);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -330,12 +383,17 @@ PyObject *py_unpack_object_from_bv(
|
||||
PyObject *py_bytes,
|
||||
int pio_flags = 0)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyString_Check(py_type) && !PyString_Check(py_fields) && !PyString_Check(py_bytes) )
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "Incorrect argument type!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// To avoid release of 'type'/'fields' during Py_BEGIN|END_ALLOW_THREADS section.
|
||||
borref_t py_type_ref(py_type);
|
||||
borref_t py_fields_ref(py_fields);
|
||||
|
||||
// Get type strings
|
||||
type_t *type = (type_t *) PyString_AsString(py_type);
|
||||
p_list *fields = (p_list *) PyString_AsString(py_fields);
|
||||
@ -346,29 +404,30 @@ PyObject *py_unpack_object_from_bv(
|
||||
memcpy(bytes.begin(), PyString_AsString(py_bytes), bytes.size());
|
||||
|
||||
idc_value_t idc_obj;
|
||||
error_t err = unpack_object_from_bv(
|
||||
error_t err;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
err = unpack_object_from_bv(
|
||||
&idc_obj,
|
||||
ti,
|
||||
type,
|
||||
fields,
|
||||
bytes,
|
||||
pio_flags);
|
||||
Py_END_ALLOW_THREADS;
|
||||
|
||||
// Unpacking failed?
|
||||
if ( err != eOk )
|
||||
return Py_BuildValue("(ii)", 0, err);
|
||||
|
||||
// Convert
|
||||
PyObject *py_ret(NULL);
|
||||
ref_t py_ret;
|
||||
err = idcvar_to_pyvar(idc_obj, &py_ret);
|
||||
|
||||
// Conversion failed?
|
||||
if ( err != CIP_OK )
|
||||
return Py_BuildValue("(ii)", 0, err);
|
||||
|
||||
PyObject *py_result = Py_BuildValue("(iO)", 1, py_ret);
|
||||
Py_DECREF(py_ret);
|
||||
return py_result;
|
||||
return Py_BuildValue("(iO)", 1, py_ret.o);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -396,6 +455,7 @@ PyObject *py_pack_object_to_idb(
|
||||
ea_t ea,
|
||||
int pio_flags = 0)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyString_Check(py_type) && !PyString_Check(py_fields) )
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "Typestring must be passed!");
|
||||
@ -404,15 +464,24 @@ PyObject *py_pack_object_to_idb(
|
||||
|
||||
// Convert Python object to IDC object
|
||||
idc_value_t idc_obj;
|
||||
if ( !convert_pyobj_to_idc_exc(py_obj, &idc_obj) )
|
||||
borref_t py_obj_ref(py_obj);
|
||||
if ( !pyvar_to_idcvar_or_error(py_obj_ref, &idc_obj) )
|
||||
return NULL;
|
||||
|
||||
// To avoid release of 'type'/'fields' during Py_BEGIN|END_ALLOW_THREADS section.
|
||||
borref_t py_type_ref(py_type);
|
||||
borref_t py_fields_ref(py_fields);
|
||||
|
||||
// Get type strings
|
||||
type_t *type = (type_t *) PyString_AsString(py_type);
|
||||
p_list *fields = (p_list *) PyString_AsString(py_fields);
|
||||
type_t *type = (type_t *)PyString_AsString(py_type);
|
||||
p_list *fields = (p_list *)PyString_AsString(py_fields);
|
||||
|
||||
// Pack
|
||||
error_t err = pack_object_to_idb(&idc_obj, ti, type, fields, ea, pio_flags);
|
||||
// error_t err;
|
||||
error_t err;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
err = pack_object_to_idb(&idc_obj, ti, type, fields, ea, pio_flags);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return PyInt_FromLong(err);
|
||||
}
|
||||
|
||||
@ -443,6 +512,7 @@ PyObject *py_pack_object_to_bv(
|
||||
ea_t base_ea,
|
||||
int pio_flags=0)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyString_Check(py_type) && !PyString_Check(py_fields) )
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "Typestring must be passed!");
|
||||
@ -451,16 +521,23 @@ PyObject *py_pack_object_to_bv(
|
||||
|
||||
// Convert Python object to IDC object
|
||||
idc_value_t idc_obj;
|
||||
if ( !convert_pyobj_to_idc_exc(py_obj, &idc_obj) )
|
||||
borref_t py_obj_ref(py_obj);
|
||||
if ( !pyvar_to_idcvar_or_error(py_obj_ref, &idc_obj) )
|
||||
return NULL;
|
||||
|
||||
// To avoid release of 'type'/'fields' during Py_BEGIN|END_ALLOW_THREADS section.
|
||||
borref_t py_type_ref(py_type);
|
||||
borref_t py_fields_ref(py_fields);
|
||||
|
||||
// Get type strings
|
||||
type_t *type = (type_t *) PyString_AsString(py_type);
|
||||
p_list *fields = (p_list *) PyString_AsString(py_fields);
|
||||
type_t *type = (type_t *)PyString_AsString(py_type);
|
||||
p_list *fields = (p_list *)PyString_AsString(py_fields);
|
||||
|
||||
// Pack
|
||||
relobj_t bytes;
|
||||
error_t err = pack_object_to_bv(
|
||||
error_t err;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
err = pack_object_to_bv(
|
||||
&idc_obj,
|
||||
ti,
|
||||
type,
|
||||
@ -468,174 +545,212 @@ PyObject *py_pack_object_to_bv(
|
||||
&bytes,
|
||||
NULL,
|
||||
pio_flags);
|
||||
do
|
||||
{
|
||||
if ( err != eOk )
|
||||
break;
|
||||
if ( !bytes.relocate(base_ea, inf.mf) )
|
||||
{
|
||||
if ( err == eOk && !bytes.relocate(base_ea, inf.mf) )
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( err == eOk )
|
||||
return Py_BuildValue("(is#)", 1, bytes.begin(), bytes.size());
|
||||
} while ( false );
|
||||
return Py_BuildValue("(ii)", 0, err);
|
||||
else
|
||||
return Py_BuildValue("(ii)", 0, err);
|
||||
}
|
||||
//</inline(py_typeinf)>
|
||||
til_t * load_til(const char *tildir, const char *name)
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
/* Parse types from a string or file. See ParseTypes() in idc.py */
|
||||
int idc_parse_types(const char *input, int flags)
|
||||
{
|
||||
char errbuf[4096];
|
||||
til_t *res;
|
||||
int hti = ((flags >> 4) & 7) << HTI_PAK_SHIFT;
|
||||
|
||||
res = load_til(tildir, name, errbuf, sizeof(errbuf));
|
||||
if ((flags & 1) != 0)
|
||||
hti |= HTI_FIL;
|
||||
|
||||
if (!res)
|
||||
return parse_decls(idati, input, (flags & 2) == 0 ? msg : NULL, hti);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *py_idc_get_type_raw(ea_t ea)
|
||||
{
|
||||
qtype type, fields;
|
||||
bool ok = get_tinfo(ea, &type, &fields);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( ok )
|
||||
return Py_BuildValue("(ss)", (char *)type.c_str(), (char *)fields.c_str());
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *py_idc_get_local_type_raw(int ordinal)
|
||||
{
|
||||
const type_t *type;
|
||||
const p_list *fields;
|
||||
bool ok = get_numbered_type(idati, ordinal, &type, &fields);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( ok )
|
||||
return Py_BuildValue("(ss)", (char *)type, (char *)fields);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
char *idc_guess_type(ea_t ea, char *buf, size_t bufsize)
|
||||
{
|
||||
tinfo_t tif;
|
||||
if ( guess_tinfo2(ea, &tif) )
|
||||
{
|
||||
qstring out;
|
||||
if ( tif.print(&out) )
|
||||
return qstrncpy(buf, out.begin(), bufsize);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
char *idc_get_type(ea_t ea, char *buf, size_t bufsize)
|
||||
{
|
||||
tinfo_t tif;
|
||||
if ( get_tinfo2(ea, &tif) )
|
||||
{
|
||||
qstring out;
|
||||
if ( tif.print(&out) )
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, errbuf);
|
||||
return NULL;
|
||||
qstrncpy(buf, out.c_str(), bufsize);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
int idc_set_local_type(int ordinal, const char *dcl, int flags)
|
||||
{
|
||||
if (dcl == NULL || dcl[0] == '\0')
|
||||
{
|
||||
if ( !del_numbered_type(idati, ordinal) )
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tinfo_t tif;
|
||||
qstring name;
|
||||
if ( !parse_decl2(idati, dcl, &name, &tif, flags) )
|
||||
return 0;
|
||||
|
||||
if ( ordinal <= 0 )
|
||||
{
|
||||
if ( !name.empty() )
|
||||
ordinal = get_type_ordinal(idati, name.begin());
|
||||
|
||||
if ( ordinal <= 0 )
|
||||
ordinal = alloc_type_ordinal(idati);
|
||||
}
|
||||
|
||||
return res;
|
||||
if ( tif.set_numbered_type(idati, ordinal, 0, name.c_str()) != TERR_OK )
|
||||
return 0;
|
||||
}
|
||||
return ordinal;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
int idc_get_local_type(int ordinal, int flags, char *buf, size_t maxsize)
|
||||
{
|
||||
tinfo_t tif;
|
||||
if ( !tif.get_numbered_type(idati, ordinal) )
|
||||
{
|
||||
buf[0] = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
qstring res;
|
||||
const char *name = get_numbered_type_name(idati, ordinal);
|
||||
if ( !tif.print(&res, name, flags, 2, 40) )
|
||||
{
|
||||
buf[0] = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
qstrncpy(buf, res.begin(), maxsize);
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *idc_print_type(PyObject *py_type, PyObject *py_fields, const char *name, int flags)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyString_Check(py_type) && !PyString_Check(py_fields) )
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "Typestring must be passed!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// To avoid release of 'type'/'fields' during Py_BEGIN|END_ALLOW_THREADS section.
|
||||
borref_t py_type_ref(py_type);
|
||||
borref_t py_fields_ref(py_fields);
|
||||
|
||||
qstring res;
|
||||
const type_t *type = (type_t *)PyString_AsString(py_type);
|
||||
const p_list *fields = (p_list *)PyString_AsString(py_fields);
|
||||
bool ok;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
tinfo_t tif;
|
||||
ok = tif.deserialize(idati, &type, &fields, NULL)
|
||||
&& tif.print(&res, name, flags, 2, 40);
|
||||
Py_END_ALLOW_THREADS;
|
||||
if ( ok )
|
||||
return PyString_FromString(res.begin());
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
char idc_get_local_type_name(int ordinal, char *buf, size_t bufsize)
|
||||
{
|
||||
const char *name = get_numbered_type_name(idati, ordinal);
|
||||
if ( name == NULL )
|
||||
return false;
|
||||
|
||||
qstrncpy(buf, name, bufsize);
|
||||
return true;
|
||||
}
|
||||
|
||||
//</inline(py_typeinf)>
|
||||
til_t *load_til(const char *tildir, const char *name)
|
||||
{
|
||||
char errbuf[MAXSTR];
|
||||
til_t *res = load_til(tildir, name, errbuf, sizeof(errbuf));
|
||||
if ( res == NULL )
|
||||
PyErr_SetString(PyExc_RuntimeError, errbuf);
|
||||
return res;
|
||||
}
|
||||
%}
|
||||
|
||||
%rename (load_til_header) load_til_header_wrap;
|
||||
%inline %{
|
||||
til_t * load_til_header_wrap(const char *tildir, const char *name)
|
||||
til_t *load_til_header_wrap(const char *tildir, const char *name)
|
||||
{
|
||||
char errbuf[4096];
|
||||
til_t *res;
|
||||
|
||||
res = load_til_header(tildir, name, errbuf, sizeof(errbuf));;
|
||||
|
||||
if (!res)
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, errbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return res;
|
||||
char errbuf[MAXSTR];
|
||||
til_t *res = load_til_header(tildir, name, errbuf, sizeof(errbuf));;
|
||||
if ( res == NULL )
|
||||
PyErr_SetString(PyExc_RuntimeError, errbuf);
|
||||
return res;
|
||||
}
|
||||
%}
|
||||
|
||||
%cstring_output_maxsize(char *buf, size_t maxsize);
|
||||
|
||||
%inline %{
|
||||
/* Parse types from a string or file. See ParseTypes() in idc.py */
|
||||
int idc_parse_types(const char *input, int flags)
|
||||
{
|
||||
int hti = ((flags >> 4) & 7) << HTI_PAK_SHIFT;
|
||||
%pythoncode %{
|
||||
#<pycode(py_typeinf)>
|
||||
|
||||
if ((flags & 1) != 0)
|
||||
hti |= HTI_FIL;
|
||||
def get_type_size0(ti, tp):
|
||||
"""
|
||||
DEPRECATED. Please use calc_type_size instead
|
||||
Returns the size of a type
|
||||
@param ti: Type info. 'idaapi.cvar.idati' can be passed.
|
||||
@param tp: type string
|
||||
@return:
|
||||
- None on failure
|
||||
- The size of the type
|
||||
"""
|
||||
return calc_type_size(ti, tp)
|
||||
|
||||
return parse_decls(idati, input, (flags & 2) == 0 ? msg : NULL, hti);
|
||||
}
|
||||
#</pycode(py_typeinf)>
|
||||
|
||||
PyObject *py_idc_get_type_raw(ea_t ea)
|
||||
{
|
||||
qtype type, fields;
|
||||
if (get_tinfo(ea, &type, &fields))
|
||||
{
|
||||
return Py_BuildValue("(ss)", (char *)type.c_str(), (char *)fields.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
char *idc_get_type(ea_t ea, char *buf, size_t bufsize)
|
||||
{
|
||||
qtype type, fnames;
|
||||
|
||||
if (get_tinfo(ea, &type, &fnames))
|
||||
{
|
||||
int code = print_type_to_one_line(buf, bufsize, idati, type.c_str(),
|
||||
NULL, NULL, fnames.c_str());
|
||||
if (code == T_NORMAL)
|
||||
return buf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *idc_guess_type(ea_t ea, char *buf, size_t bufsize)
|
||||
{
|
||||
qtype type, fnames;
|
||||
|
||||
if (guess_tinfo(ea, &type, &fnames))
|
||||
{
|
||||
int code = print_type_to_one_line(buf, bufsize, idati, type.c_str(),
|
||||
NULL, NULL, fnames.c_str());
|
||||
if (code == T_NORMAL)
|
||||
return buf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int idc_set_local_type(int ordinal, const char *dcl, int flags)
|
||||
{
|
||||
if (dcl == NULL || dcl[0] == '\0')
|
||||
{
|
||||
if (!del_numbered_type(idati, ordinal))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
qstring name;
|
||||
qtype type;
|
||||
qtype fields;
|
||||
|
||||
if (!parse_decl(idati, dcl, &name, &type, &fields, flags))
|
||||
return 0;
|
||||
|
||||
if (ordinal <= 0)
|
||||
{
|
||||
if (!name.empty())
|
||||
ordinal = get_type_ordinal(idati, name.c_str());
|
||||
|
||||
if (ordinal <= 0)
|
||||
ordinal = alloc_type_ordinal(idati);
|
||||
}
|
||||
|
||||
if (!set_numbered_type(idati, ordinal, 0, name.c_str(), type.c_str(), fields.c_str()))
|
||||
return 0;
|
||||
}
|
||||
return ordinal;
|
||||
}
|
||||
|
||||
int idc_get_local_type(int ordinal, int flags, char *buf, size_t maxsize)
|
||||
{
|
||||
const type_t *type;
|
||||
const p_list *fields;
|
||||
|
||||
if (!get_numbered_type(idati, ordinal, &type, &fields))
|
||||
{
|
||||
buf[0] = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
qstring res;
|
||||
const char *name = get_numbered_type_name(idati, ordinal);
|
||||
|
||||
if (print_type_to_qstring(&res, NULL, 2, 40, flags, idati, type, name, NULL, fields) <= 0)
|
||||
{
|
||||
buf[0] = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
qstrncpy(buf, res.c_str(), maxsize);
|
||||
return true;
|
||||
}
|
||||
|
||||
char idc_get_local_type_name(int ordinal, char *buf, size_t bufsize)
|
||||
{
|
||||
const char *name = get_numbered_type_name(idati, ordinal);
|
||||
|
||||
if (name == NULL)
|
||||
return false;
|
||||
|
||||
qstrncpy(buf, name, bufsize);
|
||||
return true;
|
||||
}
|
||||
%}
|
||||
|
94
swig/ua.i
94
swig/ua.i
@ -60,6 +60,8 @@ def init_output_buffer(size = MAXSTR):
|
||||
*/
|
||||
PyObject *py_init_output_buffer(size_t size = MAXSTR)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
// Let Python allocate a writable string buffer for us
|
||||
PyObject *py_str = PyString_FromStringAndSize(NULL, size);
|
||||
if ( py_str == NULL )
|
||||
@ -98,6 +100,7 @@ PyObject *py_decode_preceding_insn(ea_t ea)
|
||||
{
|
||||
bool farref;
|
||||
ea_t r = decode_preceding_insn(ea, &farref);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return Py_BuildValue("(" PY_FMT64 "i)", pyul_t(r), farref ? 1 : 0);
|
||||
}
|
||||
|
||||
@ -142,6 +145,7 @@ def get_stkvar(op, v):
|
||||
*/
|
||||
PyObject *py_get_stkvar(PyObject *py_op, PyObject *py_v)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *op = op_t_get_clink(py_op);
|
||||
uint64 v;
|
||||
if ( op == NULL || !PyW_GetNumber(py_v, &v) )
|
||||
@ -175,6 +179,7 @@ def add_stkvar3(op, v, flags):
|
||||
*/
|
||||
bool py_add_stkvar3(PyObject *py_op, PyObject *py_v, int flags)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *op = op_t_get_clink(py_op);
|
||||
uint64 v;
|
||||
return ( op == NULL || !PyW_GetNumber(py_v, &v) || !add_stkvar3(*op, sval_t(v), flags)) ? false : true;
|
||||
@ -217,11 +222,24 @@ bool py_apply_type_to_stkarg(
|
||||
const char *name)
|
||||
{
|
||||
uint64 v;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *op = op_t_get_clink(py_op);
|
||||
if ( op == NULL || !PyW_GetNumber(py_uv, &v) || !PyString_Check(py_type))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return apply_type_to_stkarg(*op, uval_t(v), (type_t *) PyString_AsString(py_type), name);
|
||||
{
|
||||
const type_t *t = (type_t *) PyString_AsString(py_type);
|
||||
tinfo_t tif;
|
||||
tif.deserialize(idati, &t);
|
||||
borref_t br(py_op);
|
||||
bool rc;
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
rc = apply_tinfo_to_stkarg(*op, uval_t(v), tif, name);
|
||||
Py_END_ALLOW_THREADS;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -238,6 +256,7 @@ def OutImmChar(op, outflags = 0):
|
||||
*/
|
||||
static void py_OutImmChar(PyObject *x)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *op = op_t_get_clink(x);
|
||||
if ( op != NULL )
|
||||
OutImmChar(*op);
|
||||
@ -258,6 +277,7 @@ def ua_stkvar2(op, outflags = 0):
|
||||
*/
|
||||
static bool py_ua_stkvar2(PyObject *x, adiff_t v, int flags)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *op = op_t_get_clink(x);
|
||||
return op == NULL ? false : ua_stkvar2(*op, v, flags);
|
||||
}
|
||||
@ -277,6 +297,7 @@ def ua_add_off_drefs(op, type):
|
||||
*/
|
||||
ea_t py_ua_add_off_drefs(PyObject *py_op, dref_t type)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *op = op_t_get_clink(py_op);
|
||||
return op == NULL ? BADADDR : ua_add_off_drefs(*op, type);
|
||||
}
|
||||
@ -295,6 +316,7 @@ def ua_add_off_drefs2(op, type, outf):
|
||||
*/
|
||||
ea_t py_ua_add_off_drefs2(PyObject *py_op, dref_t type, int outf)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *op = op_t_get_clink(py_op);
|
||||
return op == NULL ? BADADDR : ua_add_off_drefs2(*op, type, outf);
|
||||
}
|
||||
@ -320,6 +342,7 @@ bool py_out_name_expr(
|
||||
ea_t ea,
|
||||
PyObject *py_off)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *op = op_t_get_clink(py_op);
|
||||
uint64 v(0);
|
||||
adiff_t off;
|
||||
@ -327,13 +350,14 @@ bool py_out_name_expr(
|
||||
off = adiff_t(v);
|
||||
else
|
||||
off = BADADDR;
|
||||
|
||||
|
||||
return op == NULL ? false : out_name_expr(*op, ea, off);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static PyObject *insn_t_get_op_link(PyObject *py_insn_lnk, int i)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( i < 0 || i >= UA_MAXOP || !PyCObject_Check(py_insn_lnk) )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
@ -347,18 +371,21 @@ static PyObject *insn_t_get_op_link(PyObject *py_insn_lnk, int i)
|
||||
//-------------------------------------------------------------------------
|
||||
static PyObject *insn_t_create()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return PyCObject_FromVoidPtr(new insn_t(), NULL);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static PyObject *op_t_create()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return PyCObject_FromVoidPtr(new op_t(), NULL);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static bool op_t_assign(PyObject *self, PyObject *other)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *lhs = op_t_get_clink(self);
|
||||
op_t *rhs = op_t_get_clink(other);
|
||||
if (lhs == NULL || rhs == NULL)
|
||||
@ -371,6 +398,7 @@ static bool op_t_assign(PyObject *self, PyObject *other)
|
||||
//-------------------------------------------------------------------------
|
||||
static bool insn_t_assign(PyObject *self, PyObject *other)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *lhs = insn_t_get_clink(self);
|
||||
insn_t *rhs = insn_t_get_clink(other);
|
||||
if (lhs == NULL || rhs == NULL)
|
||||
@ -383,6 +411,7 @@ static bool insn_t_assign(PyObject *self, PyObject *other)
|
||||
//-------------------------------------------------------------------------
|
||||
static bool op_t_destroy(PyObject *py_obj)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyCObject_Check(py_obj) )
|
||||
return false;
|
||||
|
||||
@ -395,6 +424,7 @@ static bool op_t_destroy(PyObject *py_obj)
|
||||
//-------------------------------------------------------------------------
|
||||
static bool insn_t_destroy(PyObject *py_obj)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( !PyCObject_Check(py_obj) )
|
||||
return false;
|
||||
|
||||
@ -406,13 +436,16 @@ static bool insn_t_destroy(PyObject *py_obj)
|
||||
// Returns a C link to the global 'cmd' variable
|
||||
static PyObject *py_get_global_cmd_link()
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return PyCObject_FromVoidPtr(&::cmd, NULL);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static PyObject *insn_t_is_canon_insn(int itype)
|
||||
{
|
||||
if ( ph.is_canon_insn(itype) )
|
||||
bool ok = ph.is_canon_insn(itype);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( ok )
|
||||
Py_RETURN_TRUE;
|
||||
else
|
||||
Py_RETURN_FALSE;
|
||||
@ -421,13 +454,17 @@ static PyObject *insn_t_is_canon_insn(int itype)
|
||||
//-------------------------------------------------------------------------
|
||||
static PyObject *insn_t_get_canon_feature(int itype)
|
||||
{
|
||||
return Py_BuildValue("I", ph.is_canon_insn(itype) ? ph.instruc[itype-ph.instruc_start].feature : 0);
|
||||
uint32 v = ph.is_canon_insn(itype) ? ph.instruc[itype-ph.instruc_start].feature : 0;
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
return Py_BuildValue("I", v);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static PyObject *insn_t_get_canon_mnem(int itype)
|
||||
{
|
||||
if ( ph.is_canon_insn(itype) )
|
||||
bool ok = ph.is_canon_insn(itype);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
if ( ok )
|
||||
return Py_BuildValue("s", ph.instruc[itype-ph.instruc_start].name);
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
@ -436,6 +473,7 @@ static PyObject *insn_t_get_canon_mnem(int itype)
|
||||
//-------------------------------------------------------------------------
|
||||
static PyObject *insn_t_get_cs(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -444,10 +482,11 @@ static PyObject *insn_t_get_cs(PyObject *self)
|
||||
|
||||
static void insn_t_set_cs(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
|
||||
|
||||
uint64 v(0);
|
||||
PyW_GetNumber(value, &v);
|
||||
link->cs = ea_t(v);
|
||||
@ -455,6 +494,7 @@ static void insn_t_set_cs(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *insn_t_get_ip(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -463,6 +503,7 @@ static PyObject *insn_t_get_ip(PyObject *self)
|
||||
|
||||
static void insn_t_set_ip(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -473,6 +514,7 @@ static void insn_t_set_ip(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *insn_t_get_ea(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -481,6 +523,7 @@ static PyObject *insn_t_get_ea(PyObject *self)
|
||||
|
||||
static void insn_t_set_ea(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -491,6 +534,7 @@ static void insn_t_set_ea(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *insn_t_get_itype(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -499,6 +543,7 @@ static PyObject *insn_t_get_itype(PyObject *self)
|
||||
|
||||
static void insn_t_set_itype(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -507,6 +552,7 @@ static void insn_t_set_itype(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *insn_t_get_size(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -515,6 +561,7 @@ static PyObject *insn_t_get_size(PyObject *self)
|
||||
|
||||
static void insn_t_set_size(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -523,6 +570,7 @@ static void insn_t_set_size(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *insn_t_get_auxpref(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -531,6 +579,7 @@ static PyObject *insn_t_get_auxpref(PyObject *self)
|
||||
|
||||
static void insn_t_set_auxpref(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -539,6 +588,7 @@ static void insn_t_set_auxpref(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *insn_t_get_segpref(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -547,6 +597,7 @@ static PyObject *insn_t_get_segpref(PyObject *self)
|
||||
|
||||
static void insn_t_set_segpref(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -555,6 +606,7 @@ static void insn_t_set_segpref(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *insn_t_get_insnpref(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -563,6 +615,7 @@ static PyObject *insn_t_get_insnpref(PyObject *self)
|
||||
|
||||
static void insn_t_set_insnpref(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -571,6 +624,7 @@ static void insn_t_set_insnpref(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *insn_t_get_flags(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -579,6 +633,7 @@ static PyObject *insn_t_get_flags(PyObject *self)
|
||||
|
||||
static void insn_t_set_flags(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
insn_t *link = insn_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -588,6 +643,7 @@ static void insn_t_set_flags(PyObject *self, PyObject *value)
|
||||
//-------------------------------------------------------------------------
|
||||
static PyObject *op_t_get_n(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -604,6 +660,7 @@ static void op_t_set_n(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_type(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -612,6 +669,7 @@ static PyObject *op_t_get_type(PyObject *self)
|
||||
|
||||
static void op_t_set_type(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -620,6 +678,7 @@ static void op_t_set_type(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_offb(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -628,6 +687,7 @@ static PyObject *op_t_get_offb(PyObject *self)
|
||||
|
||||
static void op_t_set_offb(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -636,6 +696,7 @@ static void op_t_set_offb(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_offo(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -644,6 +705,7 @@ static PyObject *op_t_get_offo(PyObject *self)
|
||||
|
||||
static void op_t_set_offo(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -652,6 +714,7 @@ static void op_t_set_offo(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_flags(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -660,6 +723,7 @@ static PyObject *op_t_get_flags(PyObject *self)
|
||||
|
||||
static void op_t_set_flags(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -668,6 +732,7 @@ static void op_t_set_flags(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_dtyp(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -676,6 +741,7 @@ static PyObject *op_t_get_dtyp(PyObject *self)
|
||||
|
||||
static void op_t_set_dtyp(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -684,6 +750,7 @@ static void op_t_set_dtyp(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_reg_phrase(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -691,6 +758,7 @@ static PyObject *op_t_get_reg_phrase(PyObject *self)
|
||||
}
|
||||
static void op_t_set_reg_phrase(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -699,6 +767,7 @@ static void op_t_set_reg_phrase(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_value(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -707,6 +776,7 @@ static PyObject *op_t_get_value(PyObject *self)
|
||||
|
||||
static void op_t_set_value(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -715,6 +785,7 @@ static void op_t_set_value(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_addr(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -723,6 +794,7 @@ static PyObject *op_t_get_addr(PyObject *self)
|
||||
|
||||
static void op_t_set_addr(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -733,6 +805,7 @@ static void op_t_set_addr(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_specval(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -741,6 +814,7 @@ static PyObject *op_t_get_specval(PyObject *self)
|
||||
|
||||
static void op_t_set_specval(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -751,6 +825,7 @@ static void op_t_set_specval(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_specflag1(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -759,6 +834,7 @@ static PyObject *op_t_get_specflag1(PyObject *self)
|
||||
|
||||
static void op_t_set_specflag1(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -767,6 +843,7 @@ static void op_t_set_specflag1(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_specflag2(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -775,6 +852,7 @@ static PyObject *op_t_get_specflag2(PyObject *self)
|
||||
|
||||
static void op_t_set_specflag2(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -783,6 +861,7 @@ static void op_t_set_specflag2(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_specflag3(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -791,6 +870,7 @@ static PyObject *op_t_get_specflag3(PyObject *self)
|
||||
|
||||
static void op_t_set_specflag3(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
@ -799,6 +879,7 @@ static void op_t_set_specflag3(PyObject *self, PyObject *value)
|
||||
|
||||
static PyObject *op_t_get_specflag4(PyObject *self)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
Py_RETURN_NONE;
|
||||
@ -807,6 +888,7 @@ static PyObject *op_t_get_specflag4(PyObject *self)
|
||||
|
||||
static void op_t_set_specflag4(PyObject *self, PyObject *value)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
op_t *link = op_t_get_clink(self);
|
||||
if ( link == NULL )
|
||||
return;
|
||||
|
1008
swig/view.i
Normal file
1008
swig/view.i
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user