From 7a42fa50d3d08cf0c50ec39e3d9892b9ec6ae428278375ff84fc42e28abe1412 Mon Sep 17 00:00:00 2001 From: Dirk Mueller Date: Wed, 13 Jan 2021 08:59:50 +0000 Subject: [PATCH] Accepting request 862824 from home:Guillaume_G:branches:openSUSE:Factory:ARM - Backport patch to add aarch64 support: * add-aarch64-support.patch - Update to 0.9.7: * Add missing module to install directives - Update to 0.9.6: * Drop Python 2.7 support. six dependency is no longer needed * Add close_fds and pass_fds to createChild() function * Enhance strace.py output for open flags and open optional parameters * Add support for PowerPC 64-bit (ppc64) OBS-URL: https://build.opensuse.org/request/show/862824 OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-python-ptrace?expand=0&rev=16 --- add-aarch64-support.patch | 769 +++++++++++++++++++++++++++++++++++ python-ptrace-0.9.5.tar.gz | 3 - python-ptrace-0.9.7.tar.gz | 3 + python-python-ptrace.changes | 17 + python-python-ptrace.spec | 11 +- 5 files changed, 794 insertions(+), 9 deletions(-) create mode 100644 add-aarch64-support.patch delete mode 100644 python-ptrace-0.9.5.tar.gz create mode 100644 python-ptrace-0.9.7.tar.gz diff --git a/add-aarch64-support.patch b/add-aarch64-support.patch new file mode 100644 index 0000000..3d24ebf --- /dev/null +++ b/add-aarch64-support.patch @@ -0,0 +1,769 @@ +diff --git a/doc/changelog.rst b/doc/changelog.rst +index d181d3d..c8a3955 100644 +--- a/doc/changelog.rst ++++ b/doc/changelog.rst +@@ -3,6 +3,13 @@ + Changelog + ========= + ++python-ptrace 0.9.8 ++------------------- ++ ++* Added Arm 64bit (AArch64) support. ++* Implemented PTRACE_GETREGSET and PTRACE_SETREGSET required on AArch64 and ++ available on Linux. ++ + python-ptrace 0.9.7 (2020-08-10) + -------------------------------- + +diff --git a/doc/conf.py b/doc/conf.py +index 0923dc1..2bbe8c0 100644 +--- a/doc/conf.py ++++ b/doc/conf.py +@@ -41,7 +41,7 @@ copyright = u'2014, Victor Stinner' + # built documents. + # + # The short X.Y version. +-version = release = '0.9.7' ++version = release = '0.9.8' + + # The language for content autogenerated by Sphinx. Refer to documentation + # for a list of supported languages. +diff --git a/ptrace/binding/__init__.py b/ptrace/binding/__init__.py +index 497c5af..eb0374c 100644 +--- a/ptrace/binding/__init__.py ++++ b/ptrace/binding/__init__.py +@@ -1,7 +1,7 @@ + from ptrace.binding.func import ( # noqa + HAS_PTRACE_SINGLESTEP, HAS_PTRACE_EVENTS, + HAS_PTRACE_IO, HAS_PTRACE_SIGINFO, HAS_PTRACE_GETREGS, +- REGISTER_NAMES, ++ HAS_PTRACE_GETREGSET, REGISTER_NAMES, + ptrace_attach, ptrace_traceme, + ptrace_detach, ptrace_kill, + ptrace_cont, ptrace_syscall, +@@ -24,5 +24,5 @@ if HAS_PTRACE_IO: + ptrace_io_desc, + PIOD_READ_D, PIOD_WRITE_D, + PIOD_READ_I, PIOD_WRITE_I) +-if HAS_PTRACE_GETREGS: ++if HAS_PTRACE_GETREGS or HAS_PTRACE_GETREGSET: + from ptrace.binding.func import ptrace_getregs # noqa +diff --git a/ptrace/binding/cpu.py b/ptrace/binding/cpu.py +index 19fde86..d4d8053 100644 +--- a/ptrace/binding/cpu.py ++++ b/ptrace/binding/cpu.py +@@ -1,5 +1,5 @@ + from ptrace.cpu_info import ( +- CPU_POWERPC, CPU_INTEL, CPU_X86_64, CPU_I386, CPU_ARM) ++ CPU_POWERPC, CPU_INTEL, CPU_X86_64, CPU_I386, CPU_ARM32, CPU_AARCH64) + + CPU_INSTR_POINTER = None + CPU_STACK_POINTER = None +@@ -10,10 +10,14 @@ if CPU_POWERPC: + CPU_INSTR_POINTER = "nip" + # FIXME: Is it the right register? + CPU_STACK_POINTER = 'gpr1' +-elif CPU_ARM: ++elif CPU_ARM32: + CPU_INSTR_POINTER = 'r15' + CPU_STACK_POINTER = 'r14' + CPU_FRAME_POINTER = 'r11' ++elif CPU_AARCH64: ++ CPU_INSTR_POINTER = 'pc' ++ CPU_STACK_POINTER = 'sp' ++ CPU_FRAME_POINTER = 'r29' + elif CPU_X86_64: + CPU_INSTR_POINTER = "rip" + CPU_STACK_POINTER = "rsp" +diff --git a/ptrace/binding/func.py b/ptrace/binding/func.py +index 612bc75..bc4bf4d 100644 +--- a/ptrace/binding/func.py ++++ b/ptrace/binding/func.py +@@ -1,9 +1,9 @@ + from os import strerror +-from ctypes import addressof, c_int, get_errno, set_errno ++from ctypes import addressof, c_int, get_errno, set_errno, sizeof + from ptrace import PtraceError + from ptrace.ctypes_tools import formatAddress + from ptrace.os_tools import RUNNING_LINUX, RUNNING_BSD, RUNNING_OPENBSD +-from ptrace.cpu_info import CPU_64BITS, CPU_WORD_SIZE, CPU_POWERPC ++from ptrace.cpu_info import CPU_64BITS, CPU_WORD_SIZE, CPU_POWERPC, CPU_AARCH64 + + if RUNNING_OPENBSD: + from ptrace.binding.openbsd_struct import ( +@@ -17,7 +17,7 @@ elif RUNNING_BSD: + elif RUNNING_LINUX: + from ptrace.binding.linux_struct import ( + user_regs_struct as ptrace_registers_t, +- user_fpregs_struct, siginfo) ++ user_fpregs_struct, siginfo, iovec_struct) + if not CPU_64BITS: + from ptrace.binding.linux_struct import user_fpxregs_struct + else: +@@ -29,6 +29,9 @@ HAS_PTRACE_EVENTS = False + HAS_PTRACE_IO = False + HAS_PTRACE_SIGINFO = False + HAS_PTRACE_GETREGS = False ++HAS_PTRACE_GETREGSET = False ++HAS_PTRACE_SETREGS = False ++HAS_PTRACE_SETREGSET = False + + # Special flags that are required to wait for cloned processes (threads) + # See wait(2) +@@ -79,9 +82,18 @@ elif RUNNING_BSD: + PTRACE_IO = 12 + else: + # Linux +- HAS_PTRACE_GETREGS = True +- PTRACE_GETREGS = 12 +- PTRACE_SETREGS = 13 ++ if not CPU_AARCH64: ++ HAS_PTRACE_GETREGS = True ++ HAS_PTRACE_SETREGS = True ++ PTRACE_GETREGS = 12 ++ PTRACE_SETREGS = 13 ++ ++ HAS_PTRACE_GETREGSET = True ++ HAS_PTRACE_SETREGSET = True ++ PTRACE_GETREGSET = 0x4204 ++ PTRACE_SETREGSET = 0x4205 ++ NT_PRSTATUS = 1 ++ + PTRACE_ATTACH = 16 + PTRACE_DETACH = 17 + PTRACE_SYSCALL = 24 +@@ -263,8 +275,25 @@ if RUNNING_LINUX: + ptrace(PTRACE_GETREGS, pid, 0, addressof(regs)) + return regs + +- def ptrace_setregs(pid, regs): +- ptrace(PTRACE_SETREGS, pid, 0, addressof(regs)) ++ elif HAS_PTRACE_GETREGSET: ++ def ptrace_getregs(pid): ++ regs = ptrace_registers_t() ++ iov = iovec_struct() ++ setattr(iov, "buf", addressof(regs)) ++ setattr(iov, "len", sizeof(regs)) ++ ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, addressof(iov)) ++ return regs ++ ++ if HAS_PTRACE_SETREGS: ++ def ptrace_setregs(pid, regs): ++ ptrace(PTRACE_SETREGS, pid, 0, addressof(regs)) ++ ++ elif HAS_PTRACE_SETREGSET: ++ def ptrace_setregs(pid, regs): ++ iov = iovec_struct() ++ setattr(iov, "buf", addressof(regs)) ++ setattr(iov, "len", sizeof(regs)) ++ ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, addressof(iov)) + + if HAS_PTRACE_SINGLESTEP: + def ptrace_singlestep(pid): +diff --git a/ptrace/binding/linux_struct.py b/ptrace/binding/linux_struct.py +index 728b30a..1bcc20c 100644 +--- a/ptrace/binding/linux_struct.py ++++ b/ptrace/binding/linux_struct.py +@@ -1,7 +1,7 @@ + from ctypes import (Structure, Union, sizeof, + c_char, c_ushort, c_int, c_uint, c_ulong, c_void_p, +- c_uint16, c_uint32, c_uint64) +-from ptrace.cpu_info import CPU_64BITS, CPU_PPC32, CPU_PPC64, CPU_ARM ++ c_uint16, c_uint32, c_uint64, c_size_t) ++from ptrace.cpu_info import CPU_64BITS, CPU_PPC32, CPU_PPC64, CPU_ARM32, CPU_AARCH64 + + pid_t = c_int + uid_t = c_ushort +@@ -12,7 +12,15 @@ clock_t = c_uint + # arch/$ARCH/include/uapi/asm/ptrace.h + + +-class user_regs_struct(Structure): ++class register_structure(Structure): ++ def __str__(self): ++ regs = {} ++ for reg in self.__class__._fields_: ++ regs.update({reg[0]: getattr(self, reg[0])}) ++ return str(regs) ++ ++ ++class user_regs_struct(register_structure): + if CPU_PPC32: + _fields_ = ( + ("gpr0", c_ulong), +@@ -107,8 +115,14 @@ class user_regs_struct(Structure): + ("dsisr", c_ulong), + ("result", c_ulong), + ) +- elif CPU_ARM: ++ elif CPU_ARM32: + _fields_ = tuple(("r%i" % reg, c_ulong) for reg in range(18)) ++ elif CPU_AARCH64: ++ _fields_ = tuple([*[("r%i" % reg, c_ulong) for reg in range(31)], ++ ('sp', c_ulong), ++ ('pc', c_ulong), ++ ('pstate', c_ulong)] ++ ) + elif CPU_64BITS: + _fields_ = ( + ("r15", c_ulong), +@@ -167,7 +181,7 @@ class user_regs_struct(Structure): + ) + + +-class user_fpregs_struct(Structure): ++class user_fpregs_struct(register_structure): + if CPU_64BITS: + _fields_ = ( + ("cwd", c_uint16), +@@ -196,7 +210,7 @@ class user_fpregs_struct(Structure): + + + if not CPU_64BITS: +- class user_fpxregs_struct(Structure): ++ class user_fpxregs_struct(register_structure): + _fields_ = ( + ("cwd", c_ushort), + ("swd", c_ushort), +@@ -252,3 +266,10 @@ class siginfo(Structure): + ("_sifields", _sifields_t) + ) + _anonymous_ = ("_sifields",) ++ ++ ++class iovec_struct(Structure): ++ _fields_ = ( ++ ("buf", c_void_p), ++ ("len", c_size_t) ++ ) +diff --git a/ptrace/cpu_info.py b/ptrace/cpu_info.py +index 810effe..e8cd7b2 100644 +--- a/ptrace/cpu_info.py ++++ b/ptrace/cpu_info.py +@@ -39,7 +39,8 @@ if HAS_UNAME: + CPU_PPC64 = (_machine in ('ppc64', 'ppc64le')) + CPU_I386 = (_machine in ("i386", "i686")) # compatible Intel 32 bits + CPU_X86_64 = (_machine in ("x86_64", "amd64")) # compatible Intel 64 bits +- CPU_ARM = _machine.startswith('arm') ++ CPU_ARM32 = _machine.startswith('arm') ++ CPU_AARCH64 = (_machine == 'aarch64') + del _machine + else: + # uname() fallback for Windows +@@ -48,7 +49,8 @@ else: + CPU_PPC64 = False + CPU_I386 = False + CPU_X86_64 = False +- CPU_ARM = False ++ CPU_ARM32 = False ++ CPU_AARCH64 = False + bits, linkage = architecture() + if bits == '32bit': + CPU_I386 = True +@@ -59,3 +61,4 @@ else: + + CPU_INTEL = (CPU_I386 or CPU_X86_64) + CPU_POWERPC = (CPU_PPC32 or CPU_PPC64) ++CPU_ARM = (CPU_ARM32 or CPU_AARCH64) +diff --git a/ptrace/debugger/process.py b/ptrace/debugger/process.py +index 12f4431..e3e2906 100644 +--- a/ptrace/debugger/process.py ++++ b/ptrace/debugger/process.py +@@ -1,6 +1,7 @@ + from ptrace.binding import ( + HAS_PTRACE_SINGLESTEP, HAS_PTRACE_EVENTS, + HAS_PTRACE_SIGINFO, HAS_PTRACE_IO, HAS_PTRACE_GETREGS, ++ HAS_PTRACE_GETREGSET, + ptrace_attach, ptrace_detach, + ptrace_cont, ptrace_syscall, + ptrace_setregs, +@@ -45,7 +46,7 @@ if HAS_PTRACE_EVENTS: + PTRACE_EVENT_EXEC) + NEW_PROCESS_EVENT = ( + PTRACE_EVENT_FORK, PTRACE_EVENT_VFORK, PTRACE_EVENT_CLONE) +-if HAS_PTRACE_GETREGS: ++if HAS_PTRACE_GETREGS or HAS_PTRACE_GETREGSET: + from ptrace.binding import ptrace_getregs + else: + from ptrace.binding import ptrace_peekuser, ptrace_registers_t +@@ -411,7 +412,7 @@ class PtraceProcess(object): + raise ProcessError(self, "Unknown ptrace event: %r" % event) + + def getregs(self): +- if HAS_PTRACE_GETREGS: ++ if HAS_PTRACE_GETREGS or HAS_PTRACE_GETREGSET: + return ptrace_getregs(self.pid) + else: + # FIXME: Optimize getreg() when used with this function +diff --git a/ptrace/syscall/linux/aarch64.py b/ptrace/syscall/linux/aarch64.py +new file mode 100644 +index 0000000..8e522fb +--- /dev/null ++++ b/ptrace/syscall/linux/aarch64.py +@@ -0,0 +1,317 @@ ++# From https://github.com/hrw/syscalls-table/ ++ ++SYSCALL_NAMES = { ++ 0: "io_setup", ++ 1: "io_destroy", ++ 2: "io_submit", ++ 3: "io_cancel", ++ 4: "io_getevents", ++ 5: "setxattr", ++ 6: "lsetxattr", ++ 7: "fsetxattr", ++ 8: "getxattr", ++ 9: "lgetxattr", ++ 10: "fgetxattr", ++ 11: "listxattr", ++ 12: "llistxattr", ++ 13: "flistxattr", ++ 14: "removexattr", ++ 15: "lremovexattr", ++ 16: "fremovexattr", ++ 17: "getcwd", ++ 18: "lookup_dcookie", ++ 19: "eventfd2", ++ 20: "epoll_create1", ++ 21: "epoll_ctl", ++ 22: "epoll_pwait", ++ 23: "dup", ++ 24: "dup3", ++ 25: "fcntl", ++ 26: "inotify_init1", ++ 27: "inotify_add_watch", ++ 28: "inotify_rm_watch", ++ 29: "ioctl", ++ 30: "ioprio_set", ++ 31: "ioprio_get", ++ 32: "flock", ++ 33: "mknodat", ++ 34: "mkdirat", ++ 35: "unlinkat", ++ 36: "symlinkat", ++ 37: "linkat", ++ 38: "renameat", ++ 39: "umount2", ++ 40: "mount", ++ 41: "pivot_root", ++ 42: "nfsservctl", ++ 43: "statfs", ++ 44: "fstatfs", ++ 45: "truncate", ++ 46: "ftruncate", ++ 47: "fallocate", ++ 48: "faccessat", ++ 49: "chdir", ++ 50: "fchdir", ++ 51: "chroot", ++ 52: "fchmod", ++ 53: "fchmodat", ++ 54: "fchownat", ++ 55: "fchown", ++ 56: "openat", ++ 57: "close", ++ 58: "vhangup", ++ 59: "pipe2", ++ 60: "quotactl", ++ 61: "getdents64", ++ 62: "lseek", ++ 63: "read", ++ 64: "write", ++ 65: "readv", ++ 66: "writev", ++ 67: "pread64", ++ 68: "pwrite64", ++ 69: "preadv", ++ 70: "pwritev", ++ 71: "sendfile", ++ 72: "pselect6", ++ 73: "ppoll", ++ 74: "signalfd4", ++ 75: "vmsplice", ++ 76: "splice", ++ 77: "tee", ++ 78: "readlinkat", ++ 79: "newfstatat", ++ 80: "fstat", ++ 81: "sync", ++ 82: "fsync", ++ 83: "fdatasync", ++ 84: "sync_file_range", ++ 85: "timerfd_create", ++ 86: "timerfd_settime", ++ 87: "timerfd_gettime", ++ 88: "utimensat", ++ 89: "acct", ++ 90: "capget", ++ 91: "capset", ++ 92: "personality", ++ 93: "exit", ++ 94: "exit_group", ++ 95: "waitid", ++ 96: "set_tid_address", ++ 97: "unshare", ++ 98: "futex", ++ 99: "set_robust_list", ++ 100: "get_robust_list", ++ 101: "nanosleep", ++ 102: "getitimer", ++ 103: "setitimer", ++ 104: "kexec_load", ++ 105: "init_module", ++ 106: "delete_module", ++ 107: "timer_create", ++ 108: "timer_gettime", ++ 109: "timer_getoverrun", ++ 110: "timer_settime", ++ 111: "timer_delete", ++ 112: "clock_settime", ++ 113: "clock_gettime", ++ 114: "clock_getres", ++ 115: "clock_nanosleep", ++ 116: "syslog", ++ 117: "ptrace", ++ 118: "sched_setparam", ++ 119: "sched_setscheduler", ++ 120: "sched_getscheduler", ++ 121: "sched_getparam", ++ 122: "sched_setaffinity", ++ 123: "sched_getaffinity", ++ 124: "sched_yield", ++ 125: "sched_get_priority_max", ++ 126: "sched_get_priority_min", ++ 127: "sched_rr_get_interval", ++ 128: "restart_syscall", ++ 129: "kill", ++ 130: "tkill", ++ 131: "tgkill", ++ 132: "sigaltstack", ++ 133: "rt_sigsuspend", ++ 134: "rt_sigaction", ++ 135: "rt_sigprocmask", ++ 136: "rt_sigpending", ++ 137: "rt_sigtimedwait", ++ 138: "rt_sigqueueinfo", ++ 139: "rt_sigreturn", ++ 140: "setpriority", ++ 141: "getpriority", ++ 142: "reboot", ++ 143: "setregid", ++ 144: "setgid", ++ 145: "setreuid", ++ 146: "setuid", ++ 147: "setresuid", ++ 148: "getresuid", ++ 149: "setresgid", ++ 150: "getresgid", ++ 151: "setfsuid", ++ 152: "setfsgid", ++ 153: "times", ++ 154: "setpgid", ++ 155: "getpgid", ++ 156: "getsid", ++ 157: "setsid", ++ 158: "getgroups", ++ 159: "setgroups", ++ 160: "uname", ++ 161: "sethostname", ++ 162: "setdomainname", ++ 163: "getrlimit", ++ 164: "setrlimit", ++ 165: "getrusage", ++ 166: "umask", ++ 167: "prctl", ++ 168: "getcpu", ++ 169: "gettimeofday", ++ 170: "settimeofday", ++ 171: "adjtimex", ++ 172: "getpid", ++ 173: "getppid", ++ 174: "getuid", ++ 175: "geteuid", ++ 176: "getgid", ++ 177: "getegid", ++ 178: "gettid", ++ 179: "sysinfo", ++ 180: "mq_open", ++ 181: "mq_unlink", ++ 182: "mq_timedsend", ++ 183: "mq_timedreceive", ++ 184: "mq_notify", ++ 185: "mq_getsetattr", ++ 186: "msgget", ++ 187: "msgctl", ++ 188: "msgrcv", ++ 189: "msgsnd", ++ 190: "semget", ++ 191: "semctl", ++ 192: "semtimedop", ++ 193: "semop", ++ 194: "shmget", ++ 195: "shmctl", ++ 196: "shmat", ++ 197: "shmdt", ++ 198: "socket", ++ 199: "socketpair", ++ 200: "bind", ++ 201: "listen", ++ 202: "accept", ++ 203: "connect", ++ 204: "getsockname", ++ 205: "getpeername", ++ 206: "sendto", ++ 207: "recvfrom", ++ 208: "setsockopt", ++ 209: "getsockopt", ++ 210: "shutdown", ++ 211: "sendmsg", ++ 212: "recvmsg", ++ 213: "readahead", ++ 214: "brk", ++ 215: "munmap", ++ 216: "mremap", ++ 217: "add_key", ++ 218: "request_key", ++ 219: "keyctl", ++ 220: "clone", ++ 221: "execve", ++ 222: "mmap", ++ 223: "fadvise64", ++ 224: "swapon", ++ 225: "swapoff", ++ 226: "mprotect", ++ 227: "msync", ++ 228: "mlock", ++ 229: "munlock", ++ 230: "mlockall", ++ 231: "munlockall", ++ 232: "mincore", ++ 233: "madvise", ++ 234: "remap_file_pages", ++ 235: "mbind", ++ 236: "get_mempolicy", ++ 237: "set_mempolicy", ++ 238: "migrate_pages", ++ 239: "move_pages", ++ 240: "rt_tgsigqueueinfo", ++ 241: "perf_event_open", ++ 242: "accept4", ++ 243: "recvmmsg", ++ 260: "wait4", ++ 261: "prlimit64", ++ 262: "fanotify_init", ++ 263: "fanotify_mark", ++ 264: "name_to_handle_at", ++ 265: "open_by_handle_at", ++ 266: "clock_adjtime", ++ 267: "syncfs", ++ 268: "setns", ++ 269: "sendmmsg", ++ 270: "process_vm_readv", ++ 271: "process_vm_writev", ++ 272: "kcmp", ++ 273: "finit_module", ++ 274: "sched_setattr", ++ 275: "sched_getattr", ++ 276: "renameat2", ++ 277: "seccomp", ++ 278: "getrandom", ++ 279: "memfd_create", ++ 280: "bpf", ++ 281: "execveat", ++ 282: "userfaultfd", ++ 283: "membarrier", ++ 284: "mlock2", ++ 285: "copy_file_range", ++ 286: "preadv2", ++ 287: "pwritev2", ++ 288: "pkey_mprotect", ++ 289: "pkey_alloc", ++ 290: "pkey_free", ++ 291: "statx", ++ 292: "io_pgetevents", ++ 293: "rseq", ++ 294: "kexec_file_load", ++ 424: "pidfd_send_signal", ++ 425: "io_uring_setup", ++ 426: "io_uring_enter", ++ 427: "io_uring_register", ++ 428: "open_tree", ++ 429: "move_mount", ++ 430: "fsopen", ++ 431: "fsconfig", ++ 432: "fsmount", ++ 433: "fspick", ++ 434: "pidfd_open", ++ 435: "clone3", ++ 436: "close_range", ++ 437: "openat2", ++ 438: "pidfd_getfd", ++ 439: "faccessat2", ++} ++ ++SOCKET_SYSCALL_NAMES = set(( ++ "socket", ++ "socketpair", ++ "connect", ++ "sendto", ++ "recvfrom", ++ "sendmsg", ++ "recvmsg", ++ "bind", ++ "listen", ++ "accept", ++ "getsockname", ++ "getpeername", ++ "getsockopt", ++ "setsockopt", ++ "shutdown", ++)) +diff --git a/ptrace/syscall/names.py b/ptrace/syscall/names.py +index e60d7e0..fb4e6c6 100644 +--- a/ptrace/syscall/names.py ++++ b/ptrace/syscall/names.py +@@ -1,4 +1,4 @@ +-from ptrace.cpu_info import CPU_X86_64, CPU_I386, CPU_PPC64, CPU_PPC32 ++from ptrace.cpu_info import CPU_X86_64, CPU_I386, CPU_PPC64, CPU_PPC32, CPU_AARCH64 + from ptrace.os_tools import RUNNING_LINUX, RUNNING_FREEBSD + if RUNNING_LINUX: + if CPU_X86_64: +@@ -9,6 +9,8 @@ if RUNNING_LINUX: + from ptrace.syscall.linux.powerpc64 import SYSCALL_NAMES, SOCKET_SYSCALL_NAMES + elif CPU_PPC32: + from ptrace.syscall.linux.powerpc32 import SYSCALL_NAMES, SOCKET_SYSCALL_NAMES ++ elif CPU_AARCH64: ++ from ptrace.syscall.linux.aarch64 import SYSCALL_NAMES, SOCKET_SYSCALL_NAMES + else: + raise NotImplementedError("Unsupported CPU architecture") + +diff --git a/ptrace/syscall/ptrace_syscall.py b/ptrace/syscall/ptrace_syscall.py +index dd7db5e..14d9408 100644 +--- a/ptrace/syscall/ptrace_syscall.py ++++ b/ptrace/syscall/ptrace_syscall.py +@@ -1,7 +1,7 @@ + from os import strerror + from errno import errorcode + +-from ptrace.cpu_info import CPU_X86_64, CPU_POWERPC, CPU_I386, CPU_ARM ++from ptrace.cpu_info import CPU_X86_64, CPU_POWERPC, CPU_I386, CPU_ARM32, CPU_AARCH64 + from ptrace.ctypes_tools import ulong2long, formatAddress, formatWordHex + from ptrace.func_call import FunctionCall + from ptrace.syscall import SYSCALL_NAMES, SYSCALL_PROTOTYPES, SyscallArgument +@@ -12,8 +12,10 @@ from ptrace.binding.cpu import CPU_INSTR_POINTER + + if CPU_POWERPC: + SYSCALL_REGISTER = "gpr0" +-elif CPU_ARM: ++elif CPU_ARM32: + SYSCALL_REGISTER = "r7" ++elif CPU_AARCH64: ++ SYSCALL_REGISTER = "r8" + elif RUNNING_LINUX: + if CPU_X86_64: + SYSCALL_REGISTER = "orig_rax" +@@ -25,7 +27,9 @@ else: + else: + SYSCALL_REGISTER = "eax" + +-if CPU_ARM: ++if CPU_ARM32: ++ RETURN_VALUE_REGISTER = "r0" ++elif CPU_AARCH64: + RETURN_VALUE_REGISTER = "r0" + elif CPU_I386: + RETURN_VALUE_REGISTER = "eax" +@@ -84,8 +88,10 @@ class PtraceSyscall(FunctionCall): + def readArgumentValues(self, regs): + if CPU_X86_64: + return (regs.rdi, regs.rsi, regs.rdx, regs.r10, regs.r8, regs.r9) +- if CPU_ARM: ++ if CPU_ARM32: + return (regs.r0, regs.r1, regs.r2, regs.r3, regs.r4, regs.r5, regs.r6) ++ if CPU_AARCH64: ++ return (regs.r0, regs.r1, regs.r2, regs.r3, regs.r4, regs.r5, regs.r6, regs.r7) + if RUNNING_BSD: + sp = self.process.getStackPointer() + return [self.process.readWord(sp + index * CPU_WORD_SIZE) +diff --git a/ptrace/version.py b/ptrace/version.py +index e273531..531d737 100644 +--- a/ptrace/version.py ++++ b/ptrace/version.py +@@ -1,5 +1,5 @@ + PACKAGE = "python-ptrace" +-VERSION = (0, 9, 7) ++VERSION = (0, 9, 8) + __version__ = '.'.join(map(str, VERSION)) + WEBSITE = "http://python-ptrace.readthedocs.io/" + LICENSE = "GNU GPL v2" +diff --git a/tests/test_strace.py b/tests/test_strace.py +index f529637..19537f6 100755 +--- a/tests/test_strace.py ++++ b/tests/test_strace.py +@@ -6,13 +6,13 @@ import sys + import tempfile + import unittest + ++STRACE = os.path.normpath( ++ os.path.join(os.path.dirname(__file__), '..', 'strace.py')) + +-STRACE = os.path.normpath(os.path.join( +- os.path.dirname(__file__), '..', 'strace.py')) ++AARCH64 = (getattr(os.uname(), 'machine', None) == 'aarch64') + + + class TestStrace(unittest.TestCase): +- + def strace(self, *args): + """ Strace the given command and return the strace output. """ + with tempfile.NamedTemporaryFile(mode='wb+') as temp: +@@ -56,29 +56,34 @@ class TestStrace(unittest.TestCase): + + def test_open(self): + code = 'open(%a).close()' % __file__ +- self.assert_syscall(code, +- br"^open(at)?\(.*test_strace\.pyc?', O_RDONLY(\|O_CLOEXEC)?") ++ self.assert_syscall( ++ code, br"^open(at)?\(.*test_strace\.pyc?', O_RDONLY(\|O_CLOEXEC)?") + + def test_chdir(self): +- self.assert_syscall( +- "import os; os.chdir('directory')", +- br"^chdir\('directory'\)\s+= -2 ENOENT") ++ self.assert_syscall("import os; os.chdir('directory')", ++ br"^chdir\('directory'\)\s+= -2 ENOENT") + + def test_rename(self): +- self.assert_syscall( +- "import os; os.rename('oldpath', 'newpath')", +- br"^rename\('oldpath', 'newpath'\)") ++ pattern = br"^rename\('oldpath', 'newpath'\)" ++ if AARCH64: ++ pattern = br"^renameat\(.*'oldpath'.*'newpath'\)" ++ self.assert_syscall("import os; os.rename('oldpath', 'newpath')", ++ pattern) + + def test_link(self): +- self.assert_syscall( +- "import os; os.link('oldpath', 'newpath')", +- br"^link\('oldpath', 'newpath'\)") ++ pattern = br"^link\('oldpath', 'newpath'\)" ++ if AARCH64: ++ pattern = br"^linkat\(.*'oldpath'.*'newpath'.*\)" ++ self.assert_syscall("import os; os.link('oldpath', 'newpath')", ++ pattern) + + def test_symlink(self): ++ pattern = br"^symlink\('target', 'linkpath'\)" ++ if AARCH64: ++ pattern = br"^symlinkat\(.*'target'.*'linkpath'\)" + try: +- self.assert_syscall( +- "import os; os.symlink('target', 'linkpath')", +- br"^symlink\('target', 'linkpath'\)") ++ self.assert_syscall("import os; os.symlink('target', 'linkpath')", ++ pattern) + finally: + try: + os.unlink('linkpath') diff --git a/python-ptrace-0.9.5.tar.gz b/python-ptrace-0.9.5.tar.gz deleted file mode 100644 index 31c90dd..0000000 --- a/python-ptrace-0.9.5.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:839bf66bf577e43e9d32c0b7570fff5cdb470a7cf160f5d893effcefc42a78cc -size 97887 diff --git a/python-ptrace-0.9.7.tar.gz b/python-ptrace-0.9.7.tar.gz new file mode 100644 index 0000000..fd55b75 --- /dev/null +++ b/python-ptrace-0.9.7.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9bef768ccb508004be49ae24ea5639ade45c116bd02925faa2054765a6c0e3a3 +size 100597 diff --git a/python-python-ptrace.changes b/python-python-ptrace.changes index 2db84f3..0e6bdb9 100644 --- a/python-python-ptrace.changes +++ b/python-python-ptrace.changes @@ -1,3 +1,20 @@ +------------------------------------------------------------------- +Wed Jan 13 07:33:18 UTC 2021 - Guillaume GARDET + +- Backport patch to add aarch64 support: + * add-aarch64-support.patch + +------------------------------------------------------------------- +Wed Jan 13 07:28:20 UTC 2021 - Guillaume GARDET + +- Update to 0.9.7: + * Add missing module to install directives +- Update to 0.9.6: + * Drop Python 2.7 support. six dependency is no longer needed + * Add close_fds and pass_fds to createChild() function + * Enhance strace.py output for open flags and open optional parameters + * Add support for PowerPC 64-bit (ppc64) + ------------------------------------------------------------------- Thu Sep 10 12:37:13 UTC 2020 - Guillaume GARDET diff --git a/python-python-ptrace.spec b/python-python-ptrace.spec index fd2686b..a391f8c 100644 --- a/python-python-ptrace.spec +++ b/python-python-ptrace.spec @@ -1,7 +1,7 @@ # # spec file for package python-python-ptrace # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -20,23 +20,21 @@ %define pkg_name python-ptrace %define skip_python2 1 Name: python-%{pkg_name} -Version: 0.9.5 +Version: 0.9.7 Release: 0 Summary: Python binding for ptrace License: GPL-2.0-only Group: Development/Languages/Python URL: https://github.com/vstinner/python-ptrace Source: https://github.com/haypo/%{pkg_name}/archive/%{version}.tar.gz#!./%{pkg_name}-%{version}.tar.gz +# PATCH-FIX-UPSTREAM - https://github.com/vstinner/python-ptrace/pull/59 +Patch1: add-aarch64-support.patch BuildRequires: %{python_module devel} BuildRequires: %{python_module setuptools} -BuildRequires: %{python_module six} BuildRequires: fdupes BuildRequires: python-rpm-macros -Requires: python-six Requires(post): update-alternatives Requires(postun): update-alternatives -# aarch64 is not yet supported - https://github.com/vstinner/python-ptrace/issues/57 -ExcludeArch: aarch64 %python_subpackages %description @@ -44,6 +42,7 @@ python-ptrace is a debugger using ptrace written in Python. %prep %setup -q -n %{pkg_name}-%{version} +%patch1 -p1 sed -i 's/\x0D$//' doc/*.rst chmod 0644 examples/*.py