68bef552b7e3eb1163cbf2f50469b993160bd6f6
8 def __init__(self
, entry
, guest
, host
, parameters
):
9 if not isinstance(entry
, str):
10 raise ValueError(entry
)
11 if not isinstance(guest
, int):
12 raise ValueError(guest
)
13 if not isinstance(parameters
, tuple):
14 raise ValueError(parameters
)
19 self
.__parameters
= parameters
21 return super().__init
__()
36 return f
"{self.__class__.__name__}({self.entry} {self.guest}=>{self.host})"
38 def __call__(self
, *arguments
):
39 if len(arguments
) != len(self
.__parameters
):
40 raise ValueError("conflict between arguments and parameters")
42 for index
in range(len(arguments
)):
43 value
= arguments
[index
]
44 if not isinstance(value
, int):
45 raise ValueError("integer argument expected")
47 libc
= ctypes
.CDLL(None)
48 syscall
= libc
.syscall
49 restype
= syscall
.restype
50 argtypes
= syscall
.argtypes
51 syscall
.restype
= ctypes
.c_long
52 syscall
.argtypes
= ([ctypes
.c_long
] * len(arguments
))
53 res
= int(syscall(ctypes
.c_ulong(self
.host
), *map(ctypes
.c_ulong
, arguments
)))
54 syscall
.restype
= restype
55 syscall
.argtypes
= argtypes
59 class UnimplementedSyscall(Syscall
):
60 def __init__(self
, guest
):
61 return super().__init
__(entry
="sys_ni_syscall", guest
=guest
, host
=-1, parameters
=tuple())
64 class UnknownSyscall(Syscall
):
65 def __init__(self
, entry
, guest
):
66 return super().__init
__(entry
=entry
, guest
=guest
, host
=-1, parameters
=tuple())
68 def __call__(self
, *arguments
):
73 def __init__(self
, guest
, host
, logger
=None, table
=None):
75 path
= (pathlib
.Path(__file__
).parent
/ "syscalls.json")
76 with
open(path
, "r", encoding
="UTF-8") as stream
:
77 table
= json
.load(stream
)
78 if not isinstance(table
, dict):
79 raise ValueError("dict instance expected")
80 if "sysnums" not in table
or "sysargs" not in table
:
81 raise ValueError("sysnums and sysargs keys expected")
84 logger
= lambda *args
, **kwargs
: None
87 yield from sysnums
["x86-32"]["i386"].items()
90 yield from sysnums
["x86-64"]["common"].items()
91 yield from sysnums
["x86-64"]["64"].items()
94 yield from sysnums
["ppc"]["nospu"].items()
95 yield from sysnums
["ppc"]["common"].items()
96 yield from sysnums
["ppc"]["32"].items()
99 yield from sysnums
["ppc"]["nospu"].items()
100 yield from sysnums
["ppc"]["common"].items()
101 yield from sysnums
["ppc"]["64"].items()
103 def riscv32(sysnums
):
104 yield from sysnums
["generic"]["arch32"].items()
106 def riscv64(sysnums
):
107 yield from sysnums
["generic"]["arch64"].items()
117 sysnums
= table
["sysnums"]
118 sysargs
= table
["sysargs"]
120 self
.__guest
= dict(arch
[guest
](sysnums
))
121 self
.__host
= dict(arch
[host
](sysnums
))
122 self
.__parameters
= sysargs
123 self
.__logger
= logger
124 self
.__libc
= ctypes
.CDLL(None)
126 return super().__init
__()
129 identifiers
= sorted(map(int, filter(str.isnumeric
, self
.__guest
)))
130 for identifier
in identifiers
:
131 entry
= self
.__guest
[str(identifier
)][1][0]
132 name
= self
.__guest
[str(identifier
)][0]
133 syscall
= getattr(self
, entry
, None)
135 if entry
== "sys_ni_syscall":
136 syscall
= UnimplementedSyscall(guest
=identifier
)
138 syscall
= UnknownSyscall(entry
=entry
, guest
=identifier
)
141 def __getitem__(self
, identifier
):
142 if not isinstance(identifier
, int):
143 raise ValueError(identifier
)
145 identifier
= str(identifier
)
146 entry
= self
.__guest
[identifier
][1][0]
148 return getattr(self
, entry
)
150 def __getattr__(self
, entry
):
151 if entry
.startswith("compat_sys_"):
152 identifier
= entry
[len("compat_sys_"):]
153 elif entry
.startswith("sys_"):
154 identifier
= entry
[len("sys_"):]
156 raise AttributeError(entry
)
158 if entry
not in self
.__parameters
:
159 raise AttributeError(entry
)
161 if identifier
not in self
.__guest
:
162 raise AttributeError(entry
)
164 if identifier
not in self
.__host
:
165 raise AttributeError(entry
)
167 guest
= int(self
.__guest
[identifier
])
168 host
= int(self
.__host
[identifier
])
169 parameters
= tuple(self
.__parameters
[entry
].items())
171 return Syscall(entry
=entry
, guest
=guest
, host
=host
, parameters
=parameters
)
173 def __call__(self
, identifier
, *arguments
):
174 syscall
= self
[identifier
]
176 return syscall(*arguments
)