mirror of
https://github.com/idapython/src
synced 2026-06-08 14:47:00 +00:00
193 lines
5.3 KiB
Python
193 lines
5.3 KiB
Python
|
|
import re
|
|
|
|
try:
|
|
from argparse import ArgumentParser
|
|
except:
|
|
print "Failed to import module 'argparse'. Upgrade to Python 2.7, copy argparse.py to this directory or try 'apt-get install python-argparse'"
|
|
raise
|
|
|
|
parser = ArgumentParser(description='Patch calling conventions for some functions, so it builds on windows')
|
|
parser.add_argument("-f", "--file", required=True)
|
|
parser.add_argument("-v", "--verbose", default=False, action="store_true")
|
|
args = parser.parse_args()
|
|
|
|
outlines = []
|
|
STAT_SEEKING = 1
|
|
STAT_COLLECTING = 2
|
|
|
|
start_collecting_re = re.compile(r"^SWIG_init\(void\)")
|
|
end_collecting_re = re.compile(r"^\s*/\* Initialize threading \*/")
|
|
|
|
# SWIG_Python_SetConstant(d, "BADADDR",SWIG_From_unsigned_SS_int(static_cast< unsigned int >(ea_t(-1))));
|
|
set_constant_re = re.compile(r"^\s*SWIG_Python_SetConstant\(\s*d\s*,([^,]*),(.*)\);$")
|
|
|
|
# Supported types we can simply expression for
|
|
# SWIG_From_int(static_cast< int >(0x00C0))
|
|
pyobj_expr_int = re.compile(r"SWIG_From_int\(static_cast<\s*int\s*>\((.*)\)\)")
|
|
# SWIG_From_unsigned_SS_int(static_cast< unsigned int >((1u << 16)))
|
|
pyobj_expr_uint = re.compile(r"SWIG_From_unsigned_SS_int\(static_cast<\s*unsigned\s+int\s*>\((.*)\)\)")
|
|
# SWIG_From_long(static_cast< long >(0x00002000L))
|
|
pyobj_expr_long = re.compile(r"SWIG_From_long\(static_cast<\s*long\s*>\((.*)\)\)")
|
|
# SWIG_From_unsigned_SS_long(static_cast< unsigned long >(0xF0000000LU))
|
|
pyobj_expr_ulong = re.compile(r"SWIG_From_unsigned_SS_long\(static_cast<\s*unsigned\s+long\s*>\((.*)\)\)")
|
|
# SWIG_FromCharPtr("\22")
|
|
pyobj_expr_str = re.compile(r"SWIG_FromCharPtr\((.*)\)")
|
|
|
|
|
|
status = STAT_SEEKING
|
|
class Foldable(object):
|
|
def __init__(self, re, enum, initializer, replacement):
|
|
self.re = re
|
|
self.enum = enum
|
|
self.initializer = initializer
|
|
self.replacement = replacement
|
|
self.found_any = False
|
|
|
|
subexprs = {
|
|
"i" : Foldable(
|
|
pyobj_expr_int,
|
|
"cit_int",
|
|
"i",
|
|
"SWIG_From_int(static_cast< int >(ci.val.i))"),
|
|
"u" : Foldable(
|
|
pyobj_expr_uint,
|
|
"cit_uint",
|
|
"u",
|
|
"SWIG_From_unsigned_SS_int(static_cast< unsigned int >(ci.val.u))"),
|
|
"l" : Foldable(
|
|
pyobj_expr_long,
|
|
"cit_long",
|
|
"l",
|
|
"SWIG_From_long(static_cast< long >(ci.val.l))"),
|
|
"ul" : Foldable(
|
|
pyobj_expr_ulong,
|
|
"cit_ulong",
|
|
"ul",
|
|
"SWIG_From_unsigned_SS_long(static_cast< unsigned long >(ci.val.ul))"),
|
|
"s" : Foldable(
|
|
pyobj_expr_str,
|
|
"cit_charptr",
|
|
"s",
|
|
"SWIG_FromCharPtr(ci.val.s)"),
|
|
}
|
|
|
|
def generate_constants(constants):
|
|
# now, generate the array & loop
|
|
outlines.append("""
|
|
/* 'SetConstant' replacement */
|
|
union ida_local cival_t
|
|
{
|
|
PyObject *o;
|
|
int i;
|
|
unsigned int u;
|
|
long l;
|
|
unsigned long ul;
|
|
const char *s;
|
|
};
|
|
|
|
enum cit_t
|
|
{
|
|
cit_int = 1,
|
|
cit_uint,
|
|
cit_long,
|
|
cit_ulong,
|
|
cit_charptr,
|
|
cit_obj,
|
|
};
|
|
|
|
static const ida_local struct ci_t
|
|
{
|
|
const char *name;
|
|
cival_t val;
|
|
cit_t type;
|
|
} cis[%d] = {
|
|
""" % len(constants))
|
|
|
|
for c in constants:
|
|
name = c[0]
|
|
expr = c[1]
|
|
init = "o"
|
|
citype = "cit_obj"
|
|
|
|
# Analyze expression. If it is one of the
|
|
# supported types, let's simplify the code.
|
|
for kind in subexprs.keys():
|
|
subexpr = subexprs[kind]
|
|
sematch = subexpr.re.search(expr)
|
|
if sematch:
|
|
citype = subexpr.enum
|
|
expr = sematch.group(1)
|
|
init = subexpr.initializer
|
|
subexpr.found_any = True
|
|
break
|
|
outlines.append("\t{%s, {%s: (%s)}, %s},\n" % (name, init, expr, citype))
|
|
|
|
outlines.append("""
|
|
};
|
|
|
|
for ( size_t _cidx = 0; _cidx < qnumber(cis); ++_cidx )
|
|
{
|
|
const ci_t &ci = cis[_cidx];
|
|
PyObject *o = NULL;
|
|
switch ( ci.type )
|
|
{
|
|
""")
|
|
|
|
for kind in subexprs.keys():
|
|
subexpr = subexprs[kind]
|
|
if subexpr.found_any:
|
|
outlines.append("""
|
|
case %s:
|
|
o = %s;
|
|
break;
|
|
""" % (subexpr.enum, subexpr.replacement))
|
|
|
|
outlines.append("""
|
|
case cit_obj:
|
|
o = ci.val.o;
|
|
break;
|
|
default: INTERR(0);
|
|
}
|
|
SWIG_Python_SetConstant(d, ci.name, o);
|
|
}
|
|
""")
|
|
|
|
with open(args.file, "rb") as f:
|
|
constants = []
|
|
|
|
for line in f:
|
|
if status == STAT_SEEKING:
|
|
outlines.append(line)
|
|
if start_collecting_re.match(line):
|
|
status = STAT_COLLECTING
|
|
if args.verbose:
|
|
print "Starting to collect at line: '%s'" % line
|
|
elif status == STAT_COLLECTING:
|
|
if end_collecting_re.match(line):
|
|
outlines.append(line)
|
|
|
|
if len(constants):
|
|
generate_constants(constants)
|
|
|
|
status = STAT_SEEKING
|
|
if args.verbose:
|
|
print "Done collecting at line: '%s'" % line
|
|
else:
|
|
match = set_constant_re.search(line)
|
|
if match:
|
|
tpl = (match.group(1), match.group(2))
|
|
constants.append(tpl)
|
|
if args.verbose:
|
|
print "Found 'SetConstant' expression: %s => %s" % tpl
|
|
else:
|
|
outlines.append(line)
|
|
|
|
import tempfile
|
|
temp = tempfile.NamedTemporaryFile(delete=False)
|
|
temp.write("".join(outlines))
|
|
temp.close()
|
|
|
|
import shutil
|
|
shutil.move(temp.name, args.file)
|