9 def __init__(self
, guest
, host
, logger
=None, table
=None):
11 path
= pathlib
.Path(inspect
.getfile(self
.__class
__))
12 path
= (path
.parent
/ "syscalls.json")
13 with
open(path
, "r", encoding
="UTF-8") as stream
:
14 table
= json
.load(stream
)
15 if not isinstance(table
, dict):
16 raise ValueError("dict instance expected")
17 if "sysnums" not in table
or "sysargs" not in table
:
18 raise ValueError("sysnums and sysargs keys expected")
21 logger
= lambda *args
, **kwargs
: None
24 yield from sysnums
["x86-32"]["i386"].items()
27 yield from sysnums
["x86-64"]["common"].items()
28 yield from sysnums
["x86-64"]["64"].items()
31 yield from sysnums
["ppc"]["nospu"].items()
32 yield from sysnums
["ppc"]["common"].items()
33 yield from sysnums
["ppc"]["32"].items()
36 yield from sysnums
["ppc"]["nospu"].items()
37 yield from sysnums
["ppc"]["common"].items()
38 yield from sysnums
["ppc"]["64"].items()
46 sysnums
= table
["sysnums"]
47 sysargs
= table
["sysargs"]
49 self
.__guest
= dict(arch
[guest
](sysnums
))
50 self
.__host
= dict(arch
[host
](sysnums
))
51 self
.__parameters
= sysargs
52 self
.__logger
= logger
53 self
.__libc
= ctypes
.CDLL(None)
55 return super().__init
__()
57 def __getattr__(self
, entry
):
58 if entry
.startswith("compat_sys_"):
59 identifier
= entry
[len("compat_sys_"):]
60 elif entry
.startswith("sys_"):
61 identifier
= entry
[len("sys_"):]
63 raise AttributeError(entry
)
65 if entry
not in self
.__parameters
:
66 raise AttributeError(entry
)
68 if identifier
not in self
.__guest
:
69 raise AttributeError(entry
)
70 identifier
= int(self
.__guest
[identifier
])
72 def syscall(identifier
, *arguments
):
73 parameters
= tuple(self
.__parameters
[entry
].items())
74 if len(arguments
) != len(parameters
):
75 raise ValueError("conflict between arguments and parameters")
77 identifier
= str(identifier
)
78 identifier
= self
.__guest
[identifier
][0]
79 guest
= int(self
.__guest
[identifier
])
80 host
= int(self
.__host
[identifier
])
81 self
.__logger
(f
"{identifier} {guest} => {host}")
82 for index
in range(len(arguments
)):
83 value
= arguments
[index
]
84 if not isinstance(value
, int):
85 raise ValueError("integer argument expected")
86 name
= parameters
[index
][0]
87 ctype
= parameters
[index
][1]
88 self
.__logger
(f
" 0x{value:016x} {name} ({ctype})")
90 syscall
= self
.__libc
.syscall
91 syscall
.restype
= ctypes
.c_long
92 syscall
.argtypes
= ([ctypes
.c_long
] * len(arguments
))
94 return int(syscall(ctypes
.c_ulong(host
)))
96 return functools
.partial(syscall
, identifier
)
98 def __call__(self
, identifier
, *arguments
):
99 if not isinstance(identifier
, int):
100 raise ValueError(identifier
)
102 identifier
= str(identifier
)
103 entry
= self
.__guest
[identifier
][1][0]
104 syscall
= getattr(self
, entry
)
106 return syscall(*arguments
)