From 5f9944b9de97ed790c34495b32d2cfbd91078a5b Mon Sep 17 00:00:00 2001 From: Dmitry Selyutin Date: Mon, 18 Sep 2023 23:24:27 +0300 Subject: [PATCH] syscalls: refactor calls chain --- src/openpower/syscalls/__init__.py | 85 +++++++++++++++++------------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/src/openpower/syscalls/__init__.py b/src/openpower/syscalls/__init__.py index abb06db1..38798220 100644 --- a/src/openpower/syscalls/__init__.py +++ b/src/openpower/syscalls/__init__.py @@ -54,44 +54,53 @@ class Dispatcher: return super().__init__() - def __getattr__(self, identifier): - return functools.partial(self.__call__, identifier) + def __getattr__(self, entry): + if entry.startswith("compat_sys_"): + identifier = entry[len("compat_sys_"):] + elif entry.startswith("sys_"): + identifier = entry[len("sys_"):] + else: + raise AttributeError(entry) + + if entry not in self.__parameters: + raise AttributeError(entry) + + if identifier not in self.__guest: + raise AttributeError(entry) + identifier = int(self.__guest[identifier]) + + def syscall(identifier, *arguments): + parameters = tuple(self.__parameters[entry].items()) + if len(arguments) != len(parameters): + raise ValueError("conflict between arguments and parameters") - def __call__(self, identifier, *arguments): - if isinstance(identifier, int): identifier = str(identifier) - if identifier not in self.__guest: - raise KeyError(identifier) - entry = self.__guest[identifier][1][0] identifier = self.__guest[identifier][0] - else: - if not isinstance(identifier, str): - raise ValueError(identifier) - entry = identifier - if not entry.startswith(("compat_sys_", "sys_")): - entry = f"sys_{entry}" - - if ((identifier not in self.__guest) or - (identifier not in self.__host)): - raise KeyError(identifier) - - parameters = tuple(self.__parameters[entry].items()) - if len(arguments) != len(parameters): - raise ValueError("conflict between arguments and parameters") - - guest = int(self.__guest[identifier]) - host = int(self.__host[identifier]) - self.__logger(f"{identifier} {guest} => {host}") - for index in range(len(arguments)): - value = arguments[index] - if not isinstance(value, int): - raise ValueError("integer argument expected") - name = parameters[index][0] - ctype = parameters[index][1] - self.__logger(f" 0x{value:016x} {name} ({ctype})") - - syscall = self.__libc.syscall - syscall.restype = ctypes.c_long - syscall.argtypes = ([ctypes.c_long] * len(arguments)) - - return int(syscall(ctypes.c_ulong(host))) + guest = int(self.__guest[identifier]) + host = int(self.__host[identifier]) + self.__logger(f"{identifier} {guest} => {host}") + for index in range(len(arguments)): + value = arguments[index] + if not isinstance(value, int): + raise ValueError("integer argument expected") + name = parameters[index][0] + ctype = parameters[index][1] + self.__logger(f" 0x{value:016x} {name} ({ctype})") + + syscall = self.__libc.syscall + syscall.restype = ctypes.c_long + syscall.argtypes = ([ctypes.c_long] * len(arguments)) + + return int(syscall(ctypes.c_ulong(host))) + + return functools.partial(syscall, identifier) + + def __call__(self, identifier, *arguments): + if not isinstance(identifier, int): + raise ValueError(identifier) + + identifier = str(identifier) + entry = self.__guest[identifier][1][0] + syscall = getattr(self, entry) + + return syscall(*arguments) -- 2.30.2