2019-01-03 01:28:15 +08:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
import os
|
|
|
|
import glob
|
|
|
|
import sys
|
|
|
|
|
2019-01-19 22:07:38 +08:00
|
|
|
values = ['E', 'e', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'L', 'p', 'V']
|
2019-01-03 01:28:15 +08:00
|
|
|
def splitchar(s):
|
|
|
|
ret = [len(s)]
|
|
|
|
i = 0
|
|
|
|
for c in s:
|
|
|
|
i = i + 1
|
|
|
|
if i == 2:
|
|
|
|
continue
|
|
|
|
ret.append(values.index(c))
|
|
|
|
return ret
|
|
|
|
|
2019-06-24 02:35:42 +08:00
|
|
|
def value(define):
|
|
|
|
return define[9:-1] if define.startswith("!") else define[8:-1]
|
|
|
|
|
|
|
|
def splitdef(dnf, defines):
|
|
|
|
cunjs = dnf.split(" || ")
|
|
|
|
clauses = [c.split(" && ") for c in cunjs]
|
|
|
|
|
|
|
|
ret = [len(cunjs)]
|
|
|
|
|
|
|
|
for cunj in clauses:
|
|
|
|
for c in cunj:
|
|
|
|
ret.append(len(c))
|
|
|
|
for cunj in clauses:
|
|
|
|
for c in cunj:
|
|
|
|
ret.append(defines.index(value(c)) * 2 + (1 if c.startswith("!") else 0))
|
|
|
|
ret.append(0)
|
|
|
|
return ret
|
|
|
|
|
|
|
|
def invert(define):
|
|
|
|
return define[1:] if define.startswith("!") else ("!" + define)
|
|
|
|
|
2019-06-22 23:46:46 +08:00
|
|
|
def main(root, defines):
|
2019-01-03 01:28:15 +08:00
|
|
|
# Initialize variables: gbl for all values, vals for file-per-file values, redirects for redirections
|
2019-06-23 22:21:31 +08:00
|
|
|
gbl = {}
|
2019-01-03 01:28:15 +08:00
|
|
|
vals = {}
|
|
|
|
redirects = {}
|
|
|
|
|
|
|
|
# First read the files inside the headers
|
|
|
|
for filepath in glob.glob(os.path.join(root, "src", "wrapped*_private.h")):
|
|
|
|
filename = filepath.split("/")[-1]
|
2019-06-23 22:21:31 +08:00
|
|
|
locval = {}
|
|
|
|
dependants = []
|
2019-01-03 01:28:15 +08:00
|
|
|
with open(filepath, 'r') as file:
|
|
|
|
for line in file:
|
|
|
|
ln = line.strip()
|
2019-06-22 23:46:46 +08:00
|
|
|
# If the line is a `#' line (#ifdef LD80BITS/#ifndef LD80BITS/header)
|
|
|
|
if ln.startswith("#"):
|
|
|
|
preproc_cmd = ln[1:].strip()
|
|
|
|
try:
|
|
|
|
if preproc_cmd.startswith("if defined(GO)"):
|
|
|
|
continue #if defined(GO) && defined(GOM)...
|
|
|
|
elif preproc_cmd.startswith("if !(defined(GO)"):
|
|
|
|
continue #if !(defined(GO) && defined(GOM)...)
|
|
|
|
elif preproc_cmd.startswith("error"):
|
|
|
|
continue #error meh!
|
|
|
|
elif preproc_cmd.startswith("endif"):
|
2019-06-23 22:21:31 +08:00
|
|
|
if dependants != []:
|
|
|
|
dependants.pop()
|
2019-06-22 23:46:46 +08:00
|
|
|
elif preproc_cmd.startswith("ifdef"):
|
2019-06-24 02:35:42 +08:00
|
|
|
if preproc_cmd[5:].strip() not in defines:
|
|
|
|
raise KeyError(preproc_cmd[5:].strip())
|
2019-06-23 22:21:31 +08:00
|
|
|
dependants.append("defined(" + preproc_cmd[5:].strip() + ")")
|
2019-06-22 23:46:46 +08:00
|
|
|
elif preproc_cmd.startswith("ifndef"):
|
2019-06-24 02:35:42 +08:00
|
|
|
if preproc_cmd[5:].strip() not in defines:
|
|
|
|
raise KeyError(preproc_cmd[5:].strip())
|
2019-06-23 22:27:09 +08:00
|
|
|
dependants.append("!defined(" + preproc_cmd[6:].strip() + ")")
|
2019-06-22 23:46:46 +08:00
|
|
|
elif preproc_cmd.startswith("else"):
|
2019-06-24 02:35:42 +08:00
|
|
|
dependants[-1] = invert(dependants[-1])
|
2019-06-22 23:46:46 +08:00
|
|
|
else:
|
|
|
|
raise NotImplementedError("Unknown preprocessor directive: {0} ({1}:{2})".format(
|
|
|
|
preproc_cmd.split(" ")[0], filename, line[:-1]
|
|
|
|
))
|
|
|
|
except KeyError as k:
|
|
|
|
raise NotImplementedError("Unknown key: {0} ({1}:{2})".format(
|
|
|
|
k.args[0], filename, line[:-1]
|
2019-06-23 22:21:31 +08:00
|
|
|
), k)
|
2019-01-03 01:28:15 +08:00
|
|
|
# If the line is a `GO...' line (GO/GOM/GO2/...)...
|
2019-06-23 22:21:31 +08:00
|
|
|
elif ln.startswith("GO"):
|
2019-01-03 01:28:15 +08:00
|
|
|
# ... then look at the second parameter of the line
|
|
|
|
ln = ln.split(",")[1].split(")")[0].strip()
|
2019-06-23 00:01:54 +08:00
|
|
|
|
|
|
|
if ln[1] not in ["F"]:
|
|
|
|
raise NotImplementedError("Bad middle letter {0} ({1}:{2})".format(ln[1], filename, line[:-1]))
|
2019-01-03 01:28:15 +08:00
|
|
|
if any(c not in values for c in ln[2:]) or (('v' in ln[2:]) and (len(ln) > 3)):
|
|
|
|
old = ln
|
|
|
|
# This needs more work
|
|
|
|
acceptables = ['v', 'o', '0', '1'] + values
|
|
|
|
if any(c not in acceptables for c in ln[2:]):
|
2019-06-23 00:01:54 +08:00
|
|
|
raise NotImplementedError("{0} ({1}:{2})".format(ln[2:], filename, line[:-1]))
|
2019-01-03 01:28:15 +08:00
|
|
|
# Ok, this is acceptable: there is 0, 1, stdout and void
|
|
|
|
ln = (ln
|
|
|
|
.replace("v", "") # void -> nothing
|
|
|
|
.replace("o", "p") # stdout -> pointer
|
|
|
|
.replace("0", "p") # 0 -> pointer
|
|
|
|
.replace("1", "i")) # 1 -> integer
|
2019-06-23 22:21:31 +08:00
|
|
|
redirects.setdefault(" && ".join(dependants), {})
|
|
|
|
redirects[" && ".join(dependants)][old] = ln
|
2019-01-03 01:28:15 +08:00
|
|
|
# Simply append the function name if it's not yet existing
|
2019-06-23 22:21:31 +08:00
|
|
|
locval.setdefault(" && ".join(dependants), [])
|
|
|
|
gbl.setdefault(" && ".join(dependants), [])
|
|
|
|
if ln not in locval[" && ".join(dependants)]:
|
|
|
|
locval[" && ".join(dependants)].append(ln)
|
|
|
|
if ln not in gbl[" && ".join(dependants)]:
|
|
|
|
gbl[" && ".join(dependants)].append(ln)
|
2019-01-03 01:28:15 +08:00
|
|
|
|
|
|
|
# Sort the file local values and add it to the dictionary
|
2019-06-23 22:21:31 +08:00
|
|
|
for k in locval:
|
2019-06-24 02:35:42 +08:00
|
|
|
locval[k].sort(key=splitchar)
|
2019-01-03 01:28:15 +08:00
|
|
|
vals[filename] = locval
|
|
|
|
|
2019-06-23 22:21:31 +08:00
|
|
|
gbl_vals = {}
|
|
|
|
for k in gbl:
|
2019-06-24 02:35:42 +08:00
|
|
|
ks = k.split(" && ")
|
2019-06-23 22:21:31 +08:00
|
|
|
for v in gbl[k]:
|
2019-06-24 02:35:42 +08:00
|
|
|
if k == "":
|
|
|
|
gbl_vals[v] = []
|
2019-06-23 22:21:31 +08:00
|
|
|
continue
|
|
|
|
if gbl_vals.has_key(v):
|
2019-06-24 02:35:42 +08:00
|
|
|
if gbl_vals[v] == []:
|
|
|
|
continue
|
2019-06-23 22:21:31 +08:00
|
|
|
for other_key in gbl_vals[v]:
|
|
|
|
other_key_vals = other_key.split(" && ")
|
|
|
|
for other_key_val in other_key_vals:
|
2019-06-24 02:35:42 +08:00
|
|
|
if other_key_val not in ks:
|
2019-06-23 22:21:31 +08:00
|
|
|
break
|
|
|
|
else:
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
gbl_vals[v].append(k)
|
|
|
|
else:
|
|
|
|
gbl_vals[v] = [k]
|
2019-06-24 02:35:42 +08:00
|
|
|
for v in gbl_vals:
|
|
|
|
for k in gbl_vals[v]:
|
|
|
|
if " && ".join([invert(v2) for v2 in k.split(" && ")]) in gbl_vals[v]:
|
|
|
|
gbl_vals[v] = []
|
|
|
|
break
|
2019-06-23 22:21:31 +08:00
|
|
|
gbl = {}
|
2019-06-24 02:35:42 +08:00
|
|
|
gbl_idxs = []
|
2019-06-23 22:21:31 +08:00
|
|
|
for k in gbl_vals:
|
2019-06-24 02:35:42 +08:00
|
|
|
if len(gbl_vals[k]) == 1:
|
|
|
|
key = gbl_vals[k][0]
|
|
|
|
else:
|
|
|
|
key = "(" + (") || (".join(gbl_vals[k])) + ")"
|
2019-06-23 22:21:31 +08:00
|
|
|
gbl[key] = gbl.get(key, []) + [k]
|
2019-06-24 02:35:42 +08:00
|
|
|
if (key not in gbl_idxs) and (key != "()"):
|
|
|
|
gbl_idxs.append(key)
|
|
|
|
gbl_idxs.sort(key=lambda v: splitdef(v, defines))
|
2019-06-23 22:21:31 +08:00
|
|
|
|
|
|
|
redirects_vals = {}
|
|
|
|
for k in redirects:
|
2019-06-24 02:35:42 +08:00
|
|
|
ks = k.split(" && ")
|
2019-06-23 22:21:31 +08:00
|
|
|
for v in redirects[k]:
|
2019-06-24 02:35:42 +08:00
|
|
|
if k == "":
|
|
|
|
redirects_vals[(v, redirects[k][v])] = []
|
|
|
|
continue
|
|
|
|
if redirects_vals.has_key((v, redirects[k][v])):
|
|
|
|
if redirects_vals[(v, redirects[k][v])] == []:
|
|
|
|
continue
|
|
|
|
for other_key in redirects_vals[(v, redirects[k][v])]:
|
2019-06-23 22:21:31 +08:00
|
|
|
if other_key == "()":
|
|
|
|
break
|
|
|
|
other_key_vals = other_key.split(" && ")
|
|
|
|
for other_key_val in other_key_vals:
|
2019-06-24 02:35:42 +08:00
|
|
|
if other_key_val not in ks:
|
2019-06-23 22:21:31 +08:00
|
|
|
break
|
|
|
|
else:
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
redirects_vals[(v, redirects[k][v])].append(k)
|
|
|
|
else:
|
|
|
|
redirects_vals[(v, redirects[k][v])] = [k]
|
|
|
|
redirects = {}
|
2019-06-24 02:35:42 +08:00
|
|
|
redirects_idxs = []
|
2019-06-23 22:21:31 +08:00
|
|
|
for k, v in redirects_vals:
|
|
|
|
key = "(" + (") || (".join(redirects_vals[(k, v)])) + ")"
|
|
|
|
val = redirects.get(key, {})
|
|
|
|
val[k] = v
|
|
|
|
redirects[key] = val
|
2019-06-24 02:35:42 +08:00
|
|
|
if (key not in redirects_idxs) and (key != "()"):
|
|
|
|
redirects_idxs.append(key)
|
|
|
|
redirects_idxs.sort(key=lambda v: splitdef(v, defines))
|
2019-06-23 22:21:31 +08:00
|
|
|
|
2019-01-03 01:28:15 +08:00
|
|
|
# Sort the table
|
2019-06-23 22:21:31 +08:00
|
|
|
for k in gbl:
|
|
|
|
gbl[k].sort(key=lambda v: splitchar(v))
|
2019-01-03 01:28:15 +08:00
|
|
|
|
|
|
|
def length(s):
|
|
|
|
l = len(s)
|
|
|
|
if l < 10:
|
|
|
|
ret = "0" + str(l)
|
|
|
|
else:
|
|
|
|
ret = str(l)
|
|
|
|
return ret
|
|
|
|
|
|
|
|
# Now the files rebuilding part
|
|
|
|
# File headers and guards
|
|
|
|
files_headers = {
|
|
|
|
"wrapper.c": """/*****************************************************************
|
2019-06-23 22:21:31 +08:00
|
|
|
* File automatically generated by rebuild_wrappers.py (v1.1.0.03)
|
2019-01-03 01:28:15 +08:00
|
|
|
*****************************************************************/
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
#include "wrapper.h"
|
|
|
|
#include "x86emu_private.h"
|
|
|
|
#include "x87emu_private.h"
|
|
|
|
#include "regs.h"
|
2019-01-19 16:27:00 +08:00
|
|
|
#include "x86emu.h"
|
2019-01-03 01:28:15 +08:00
|
|
|
|
|
|
|
typedef union ui64_s {
|
|
|
|
int64_t i;
|
|
|
|
uint64_t u;
|
|
|
|
uint32_t d[2];
|
|
|
|
} ui64_t;
|
|
|
|
|
2019-02-24 20:58:31 +08:00
|
|
|
#ifdef USE_FLOAT
|
|
|
|
#define ST0val ST0.f
|
|
|
|
#else
|
|
|
|
#define ST0val ST0.d
|
|
|
|
#endif
|
|
|
|
|
2019-01-03 01:28:15 +08:00
|
|
|
""",
|
|
|
|
"wrapper.h": """/*****************************************************************
|
2019-06-23 22:21:31 +08:00
|
|
|
* File automatically generated by rebuild_wrappers.py (v1.1.0.03)
|
2019-01-03 01:28:15 +08:00
|
|
|
*****************************************************************/
|
|
|
|
#ifndef __WRAPPER_H_
|
|
|
|
#define __WRAPPER_H_
|
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
typedef struct x86emu_s x86emu_t;
|
|
|
|
|
|
|
|
// the generic wrapper pointer functions
|
|
|
|
typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
|
|
|
|
|
|
|
|
// list of defined wrapper
|
|
|
|
// v = void, i = int32, u = uint32, U/I= (u)int64
|
|
|
|
// p = pointer, P = callback
|
|
|
|
// f = float, d = double, D = long double, L = fake long double
|
2019-01-19 22:07:38 +08:00
|
|
|
// V = vaargs, E = current x86emu struct, e = ref to current x86emu struct
|
2019-01-03 01:28:15 +08:00
|
|
|
// 0 = constant 0, 1 = constant 1
|
|
|
|
// o = stdout
|
|
|
|
// C = unsigned byte c = char
|
|
|
|
// W = unsigned short w = short
|
|
|
|
// Q = ...
|
|
|
|
// S8 = struct, 8 bytes
|
|
|
|
|
|
|
|
"""
|
|
|
|
}
|
|
|
|
files_guards = {"wrapper.c": """""",
|
|
|
|
"wrapper.h": """
|
|
|
|
#endif //__WRAPPER_H_
|
|
|
|
"""
|
|
|
|
}
|
|
|
|
|
|
|
|
# Transform strings into arrays
|
2019-06-23 22:21:31 +08:00
|
|
|
for k in gbl:
|
|
|
|
gbl[k] = [[c for c in v] for v in gbl[k]]
|
2019-01-03 01:28:15 +08:00
|
|
|
|
|
|
|
# Rewrite the wrapper.h file:
|
|
|
|
with open(os.path.join(root, "src", "wrapper.h"), 'w') as file:
|
|
|
|
file.write(files_headers["wrapper.h"])
|
2019-06-23 22:21:31 +08:00
|
|
|
for v in gbl["()"]:
|
2019-01-03 01:28:15 +08:00
|
|
|
file.write("void " + ''.join(v) + "(x86emu_t *emu, uintptr_t fnc);\n")
|
2019-06-24 02:35:42 +08:00
|
|
|
for k in gbl_idxs:
|
2019-06-23 22:21:31 +08:00
|
|
|
if k != "()":
|
|
|
|
file.write("\n#if " + k + "\n")
|
|
|
|
for v in gbl[k]:
|
|
|
|
file.write("void " + ''.join(v) + "(x86emu_t *emu, uintptr_t fnc);\n")
|
|
|
|
file.write("#endif\n")
|
|
|
|
file.write("\n")
|
|
|
|
for v in redirects["()"]:
|
2019-01-03 01:28:15 +08:00
|
|
|
file.write("void " + ''.join(v) + "(x86emu_t *emu, uintptr_t fnc);\n")
|
2019-06-24 02:35:42 +08:00
|
|
|
for k in redirects_idxs:
|
2019-06-23 22:21:31 +08:00
|
|
|
if k != "()":
|
|
|
|
file.write("\n#if " + k + "\n")
|
|
|
|
for v in redirects[k]:
|
|
|
|
file.write("void " + ''.join(v) + "(x86emu_t *emu, uintptr_t fnc);\n")
|
|
|
|
file.write("#endif\n")
|
2019-01-03 01:28:15 +08:00
|
|
|
file.write(files_guards["wrapper.h"])
|
|
|
|
|
|
|
|
# Rewrite the wrapper.c file:
|
|
|
|
with open(os.path.join(root, "src", "wrapper.c"), 'w') as file:
|
|
|
|
file.write(files_headers["wrapper.c"])
|
|
|
|
|
|
|
|
# First part: typedefs
|
2019-06-23 22:21:31 +08:00
|
|
|
for v in gbl["()"]:
|
2019-06-23 00:01:54 +08:00
|
|
|
# E e v c w i I C W u U f d D L p V
|
2019-01-19 22:07:38 +08:00
|
|
|
types = ["x86emu_t*", "x86emu_t**", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "long double", "double", "void*", "void*"]
|
2019-01-03 02:14:26 +08:00
|
|
|
if len(values) != len(types):
|
2019-06-23 00:01:54 +08:00
|
|
|
raise NotImplementedError("len(values) = {lenval} != len(types) = {lentypes}".format(lenval=len(values), lentypes=len(types)))
|
2019-01-03 01:28:15 +08:00
|
|
|
|
|
|
|
file.write("typedef " + types[values.index(v[0])] + " (*" + ''.join(v) + "_t)"
|
|
|
|
+ "(" + ', '.join(types[values.index(t)] for t in v[2:]) + ");\n")
|
2019-06-24 02:35:42 +08:00
|
|
|
for k in gbl_idxs:
|
2019-06-23 22:21:31 +08:00
|
|
|
if k != "()":
|
|
|
|
file.write("\n#if " + k + "\n")
|
|
|
|
for v in gbl[k]:
|
|
|
|
# E e v c w i I C W u U f d D L p V
|
|
|
|
types = ["x86emu_t*", "x86emu_t**", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "long double", "double", "void*", "void*"]
|
|
|
|
if len(values) != len(types):
|
|
|
|
raise NotImplementedError("len(values) = {lenval} != len(types) = {lentypes}".format(lenval=len(values), lentypes=len(types)))
|
|
|
|
|
|
|
|
file.write("typedef " + types[values.index(v[0])] + " (*" + ''.join(v) + "_t)"
|
|
|
|
+ "(" + ', '.join(types[values.index(t)] for t in v[2:]) + ");\n")
|
|
|
|
file.write("#endif\n")
|
2019-01-03 01:28:15 +08:00
|
|
|
|
2019-06-24 02:35:42 +08:00
|
|
|
file.write("\n")
|
2019-01-03 01:28:15 +08:00
|
|
|
# Next part: function definitions
|
|
|
|
|
|
|
|
# Helper functions to write the function definitions
|
|
|
|
def function_args(args, d=4):
|
|
|
|
if len(args) == 0:
|
|
|
|
return ""
|
|
|
|
if d % 4 != 0:
|
2019-06-24 02:35:42 +08:00
|
|
|
raise ValueError("{d} is not a multiple of 4. Did you try passing a V and something else?".format(d=d))
|
2019-01-03 01:28:15 +08:00
|
|
|
|
|
|
|
if args[0] == "0":
|
|
|
|
return "(void*)(R_ESP + {p}), ".format(p=d) + function_args(args[1:], d + 4)
|
2019-06-24 02:35:42 +08:00
|
|
|
elif args[0] == "1":
|
2019-01-03 01:28:15 +08:00
|
|
|
return "1, " + function_args(args[1:], d)
|
|
|
|
|
|
|
|
arg = [
|
|
|
|
"emu, ", # E
|
2019-06-23 00:01:54 +08:00
|
|
|
"&emu, ", # e
|
2019-01-03 01:28:15 +08:00
|
|
|
"", # v
|
|
|
|
"*(int8_t*)(R_ESP + {p}), ", # c
|
|
|
|
"*(int16_t*)(R_ESP + {p}), ", # w
|
|
|
|
"*(int32_t*)(R_ESP + {p}), ", # i
|
|
|
|
"*(int64_t*)(R_ESP + {p}), ", # I
|
|
|
|
"*(uint8_t*)(R_ESP + {p}), ", # C
|
|
|
|
"*(uint16_t*)(R_ESP + {p}), ", # W
|
|
|
|
"*(uint32_t*)(R_ESP + {p}), ", # u
|
|
|
|
"*(uint64_t*)(R_ESP + {p}), ", # U
|
|
|
|
"*(float*)(R_ESP + {p}), ", # f
|
|
|
|
"*(double*)(R_ESP + {p}), ", # d
|
|
|
|
"*(long double*)(R_ESP + {p}), ", # D
|
2019-01-19 16:27:00 +08:00
|
|
|
"FromLD((void*)(R_ESP + {p})), ", # L
|
2019-01-03 01:28:15 +08:00
|
|
|
"*(void**)(R_ESP + {p}), ", # p
|
2019-06-23 00:01:54 +08:00
|
|
|
"(void*)(R_ESP + {p}), " # V
|
2019-01-03 01:28:15 +08:00
|
|
|
]
|
2019-06-23 00:01:54 +08:00
|
|
|
# E e v c w i I C W u U f d D L p V
|
2019-01-19 22:07:38 +08:00
|
|
|
deltas = [0, 0, 4, 4, 4, 4, 8, 4, 4, 4, 8, 4, 8, 12, 12, 4, 0]
|
2019-01-03 01:28:15 +08:00
|
|
|
if len(values) != len(arg):
|
|
|
|
raise NotImplementedError("len(values) = {lenval} != len(arg) = {lenarg}".format(lenval=len(values), lenarg=len(arg)))
|
|
|
|
if len(values) != len(deltas):
|
|
|
|
raise NotImplementedError("len(values) = {lenval} != len(deltas) = {lendeltas}".format(lenval=len(values), lendeltas=len(deltas)))
|
|
|
|
return arg[values.index(args[0])].format(p=d) + function_args(args[1:], d + deltas[values.index(args[0])])
|
|
|
|
|
|
|
|
def function_writer(f, N, W, rettype, args):
|
|
|
|
f.write("void {0}(x86emu_t *emu, uintptr_t fcn) {2} {1} fn = ({1})fcn; ".format(N, W, "{"))
|
|
|
|
vals = [
|
|
|
|
"\n#error Invalid return type: emulator\n", # E
|
2019-01-19 22:07:38 +08:00
|
|
|
"\n#error Invalid return type: &emulator\n", # e
|
2019-01-03 01:28:15 +08:00
|
|
|
"fn({0});", # v
|
|
|
|
"R_EAX=fn({0});", # c
|
|
|
|
"R_EAX=fn({0});", # w
|
|
|
|
"R_EAX=fn({0});", # i
|
|
|
|
"ui64_t r; r.i=fn({0}); R_EAX=r.d[0]; R_EDX=r.d[1];", # I
|
|
|
|
"R_EAX=(unsigned char)fn({0});", # C
|
|
|
|
"R_EAX=(unsigned short)fn({0});", # W
|
|
|
|
"R_EAX=(uint32_t)fn({0});", # u
|
|
|
|
"ui64_t r; r.u=(uint64_t)fn({0}); R_EAX=r.d[0]; R_EDX=r.d[1];", # U
|
2019-06-23 22:21:31 +08:00
|
|
|
"float fl=fn({0}); fpu_do_push(emu); ST0val = fl;", # f
|
|
|
|
"double db=fn({0}); fpu_do_push(emu); ST0val = db;", # d
|
|
|
|
"long double ld=fn({0}); fpu_do_push(emu); ST0val = ld;", # D
|
|
|
|
"double db=fn({0}); fpu_do_push(emu); ST0val = db;", # L
|
2019-01-03 01:28:15 +08:00
|
|
|
"R_EAX=(uintptr_t)fn({0});", # p
|
|
|
|
"\n#error Invalid return type: va_list\n", # V
|
|
|
|
]
|
|
|
|
if len(values) != len(vals):
|
|
|
|
raise NotImplementedError("len(values) = {lenval} != len(vals) = {lenvals}".format(lenval=len(values), lenvals=len(vals)))
|
|
|
|
f.write(vals[values.index(rettype)].format(function_args(args)[:-2]) + " }\n")
|
|
|
|
|
2019-06-23 22:21:31 +08:00
|
|
|
for v in gbl["()"]:
|
2019-01-03 01:28:15 +08:00
|
|
|
function_writer(file, ''.join(v), ''.join(v) + "_t", v[0], v[2:])
|
2019-06-24 02:35:42 +08:00
|
|
|
for k in gbl_idxs:
|
2019-06-23 22:21:31 +08:00
|
|
|
if k != "()":
|
|
|
|
file.write("\n#if " + k + "\n")
|
|
|
|
for v in gbl[k]:
|
|
|
|
function_writer(file, ''.join(v), ''.join(v) + "_t", v[0], v[2:])
|
|
|
|
file.write("#endif\n")
|
|
|
|
file.write("\n")
|
|
|
|
for v in redirects["()"]:
|
|
|
|
function_writer(file, v, redirects["()"][v] + "_t", v[0], v[2:])
|
2019-06-24 02:35:42 +08:00
|
|
|
for k in redirects_idxs:
|
2019-06-23 22:21:31 +08:00
|
|
|
if k != "()":
|
|
|
|
file.write("\n#if " + k + "\n")
|
|
|
|
for v in redirects[k]:
|
|
|
|
function_writer(file, v, redirects[k][v] + "_t", v[0], v[2:])
|
|
|
|
file.write("#endif\n")
|
2019-01-03 01:28:15 +08:00
|
|
|
|
|
|
|
file.write(files_guards["wrapper.c"])
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2019-06-24 02:35:42 +08:00
|
|
|
if main(sys.argv[1], sys.argv[2:]) != 0:
|
2019-01-03 01:28:15 +08:00
|
|
|
exit(2)
|
|
|
|
exit(0)
|