17 "aarch64_be": "aarch64",
24 def __init__(self
, entry
, guest
, host
, parameters
):
25 if not isinstance(entry
, str):
26 raise ValueError(entry
)
27 if not isinstance(guest
, int):
28 raise ValueError(guest
)
29 if not isinstance(parameters
, tuple):
30 raise ValueError(parameters
)
35 self
.__parameters
= parameters
37 return super().__init
__()
52 return len(self
.__parameters
)
55 return f
"{self.__class__.__name__}({self.entry} {self.guest}=>{self.host})"
57 def __call__(self
, *arguments
):
58 if len(arguments
) < len(self
):
59 raise ValueError("conflict between arguments and parameters")
61 for index
in range(len(arguments
)):
62 value
= arguments
[index
]
63 if not isinstance(value
, int):
64 raise ValueError("integer argument expected")
66 libc
= ctypes
.CDLL(None)
67 syscall
= libc
.syscall
68 restype
= syscall
.restype
69 argtypes
= syscall
.argtypes
70 syscall
.restype
= ctypes
.c_long
71 syscall
.argtypes
= ([ctypes
.c_long
] * len(arguments
))
72 res
= int(syscall(ctypes
.c_long(self
.host
), *map(ctypes
.c_long
, arguments
)))
73 syscall
.restype
= restype
74 syscall
.argtypes
= argtypes
78 class UnimplementedSyscall(Syscall
):
79 def __init__(self
, guest
):
80 return super().__init
__(entry
="sys_ni_syscall", guest
=guest
, host
=-1, parameters
=tuple())
82 def __call__(self
, *arguments
):
86 class UnknownSyscall(Syscall
):
87 def __init__(self
, entry
, guest
):
88 return super().__init
__(entry
=entry
, guest
=guest
, host
=-1, parameters
=tuple())
90 def __call__(self
, *arguments
):
95 def __init__(self
, guest
, host
, logger
=None, table
=None):
97 path
= (pathlib
.Path(__file__
).parent
/ "syscalls.json")
98 with
open(path
, "r", encoding
="UTF-8") as stream
:
99 table
= json
.load(stream
)
100 if not isinstance(table
, dict):
101 raise ValueError("dict instance expected")
102 if "sysnums" not in table
or "sysargs" not in table
:
103 raise ValueError("sysnums and sysargs keys expected")
106 logger
= lambda *args
, **kwargs
: None
108 guest
= ARCH
.get(guest
, guest
)
109 host
= ARCH
.get(host
, host
)
112 yield from sysnums
["x86-32"]["i386"].items()
115 yield from sysnums
["x86-64"]["common"].items()
116 yield from sysnums
["x86-64"]["64"].items()
119 yield from sysnums
["arm"]["common"].items()
121 def aarch64(sysnums
):
122 yield from sysnums
["generic"]["arch64"].items()
125 yield from sysnums
["ppc"]["nospu"].items()
126 yield from sysnums
["ppc"]["common"].items()
127 yield from sysnums
["ppc"]["32"].items()
130 yield from sysnums
["ppc"]["nospu"].items()
131 yield from sysnums
["ppc"]["common"].items()
132 yield from sysnums
["ppc"]["64"].items()
134 def riscv32(sysnums
):
135 yield from sysnums
["generic"]["arch32"].items()
137 def riscv64(sysnums
):
138 yield from sysnums
["generic"]["arch64"].items()
150 sysnums
= table
["sysnums"]
151 sysargs
= table
["sysargs"]
153 self
.__guest
= dict(arch
[guest
](sysnums
))
154 self
.__host
= dict(arch
[host
](sysnums
))
155 self
.__parameters
= sysargs
156 self
.__logger
= logger
157 self
.__libc
= ctypes
.CDLL(None)
159 return super().__init
__()
162 identifiers
= sorted(map(int, filter(str.isnumeric
, self
.__guest
)))
163 for identifier
in identifiers
:
164 entry
= self
.__guest
[str(identifier
)][1][0]
165 name
= self
.__guest
[str(identifier
)][0]
166 syscall
= getattr(self
, entry
, None)
168 if entry
== "sys_ni_syscall":
169 syscall
= UnimplementedSyscall(guest
=identifier
)
171 syscall
= UnknownSyscall(entry
=entry
, guest
=identifier
)
174 def __getitem__(self
, identifier
):
175 if not isinstance(identifier
, int):
176 raise ValueError(identifier
)
178 identifier
= str(identifier
)
179 entry
= self
.__guest
[identifier
][1][0]
181 return getattr(self
, entry
)
183 def __getattr__(self
, entry
):
184 if entry
.startswith("compat_sys_"):
185 identifier
= entry
[len("compat_sys_"):]
186 elif entry
.startswith("sys_"):
187 identifier
= entry
[len("sys_"):]
189 raise AttributeError(entry
)
191 if entry
not in self
.__parameters
:
192 raise AttributeError(entry
)
194 if identifier
not in self
.__guest
:
195 raise AttributeError(entry
)
197 if identifier
not in self
.__host
:
198 raise AttributeError(entry
)
200 guest
= int(self
.__guest
[identifier
])
201 host
= int(self
.__host
[identifier
])
202 parameters
= tuple(self
.__parameters
[entry
].items())
204 return Syscall(entry
=entry
, guest
=guest
, host
=host
, parameters
=parameters
)
206 def __call__(self
, identifier
, *arguments
):
207 syscall
= self
[identifier
]
209 return syscall(*arguments
)