From 8d4b68a7c4091c99c8d591e93efae5748a7ced13 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 21 Jun 2017 21:42:41 +0000 Subject: [PATCH] libgo, syscall: fix ptrace implementation on MIPS On MIPS, the correct structure for PtraceRegs is 'struct pt_regs' which is declared in linux/ptrace.h. Previously no PtraceRegs structure was created on MIPS because 'struct user_regs_struct' doesn't exist there. Fallback to using pt_regs when the PtraceRegs structure is generated in mksysinfo.sh, then adjust syscall_linux_mipsx.go to read the program counter from the correct field. In addition, implement PtraceGetRegs and PtraceSetRegs on all 3 ABI variants. syscall_linux_mips64x.go can now be removed since the ptrace code on all 3 ABIs is identical. Reviewed-on: https://go-review.googlesource.com/46150 From-SVN: r249472 --- gcc/go/gofrontend/MERGE | 2 +- libgo/config.h.in | 3 +++ libgo/configure | 2 +- libgo/configure.ac | 2 +- libgo/go/syscall/syscall_linux_mipsx.go | 20 +++++++++++++++++--- libgo/mksysinfo.sh | 4 ++++ libgo/sysinfo.c | 3 +++ 7 files changed, 30 insertions(+), 6 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 0eeac9b25d4..5ef0cc0c78c 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -6449e2832eef94eacf89c88fa16bede637f729ba +b2bebba1f8a8185546c47f8460a3d5c2e31d0434 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/libgo/config.h.in b/libgo/config.h.in index 17afd76ca6c..57560cd0e5f 100644 --- a/libgo/config.h.in +++ b/libgo/config.h.in @@ -114,6 +114,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_NETLINK_H +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_PTRACE_H + /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_REBOOT_H diff --git a/libgo/configure b/libgo/configure index 556387a180f..0700b7b6bb6 100755 --- a/libgo/configure +++ b/libgo/configure @@ -14782,7 +14782,7 @@ $as_echo "#define HAVE_GETIPINFO 1" >>confdefs.h fi -for ac_header in port.h sched.h semaphore.h sys/file.h sys/mman.h syscall.h sys/epoll.h sys/event.h sys/inotify.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h sys/select.h sys/socket.h net/if.h net/if_arp.h net/route.h netpacket/packet.h sys/prctl.h sys/mount.h sys/vfs.h sys/statfs.h sys/timex.h sys/sysinfo.h utime.h linux/ether.h linux/fs.h linux/reboot.h netinet/icmp6.h netinet/in_syst.h netinet/ip.h netinet/ip_mroute.h netinet/if_ether.h +for ac_header in port.h sched.h semaphore.h sys/file.h sys/mman.h syscall.h sys/epoll.h sys/event.h sys/inotify.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h sys/select.h sys/socket.h net/if.h net/if_arp.h net/route.h netpacket/packet.h sys/prctl.h sys/mount.h sys/vfs.h sys/statfs.h sys/timex.h sys/sysinfo.h utime.h linux/ether.h linux/fs.h linux/ptrace.h linux/reboot.h netinet/icmp6.h netinet/in_syst.h netinet/ip.h netinet/ip_mroute.h netinet/if_ether.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" diff --git a/libgo/configure.ac b/libgo/configure.ac index 5a1032f4dab..d16547f4487 100644 --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -580,7 +580,7 @@ AC_C_BIGENDIAN GCC_CHECK_UNWIND_GETIPINFO -AC_CHECK_HEADERS(port.h sched.h semaphore.h sys/file.h sys/mman.h syscall.h sys/epoll.h sys/event.h sys/inotify.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h sys/select.h sys/socket.h net/if.h net/if_arp.h net/route.h netpacket/packet.h sys/prctl.h sys/mount.h sys/vfs.h sys/statfs.h sys/timex.h sys/sysinfo.h utime.h linux/ether.h linux/fs.h linux/reboot.h netinet/icmp6.h netinet/in_syst.h netinet/ip.h netinet/ip_mroute.h netinet/if_ether.h) +AC_CHECK_HEADERS(port.h sched.h semaphore.h sys/file.h sys/mman.h syscall.h sys/epoll.h sys/event.h sys/inotify.h sys/ptrace.h sys/syscall.h sys/user.h sys/utsname.h sys/select.h sys/socket.h net/if.h net/if_arp.h net/route.h netpacket/packet.h sys/prctl.h sys/mount.h sys/vfs.h sys/statfs.h sys/timex.h sys/sysinfo.h utime.h linux/ether.h linux/fs.h linux/ptrace.h linux/reboot.h netinet/icmp6.h netinet/in_syst.h netinet/ip.h netinet/ip_mroute.h netinet/if_ether.h) AC_CHECK_HEADERS([linux/filter.h linux/if_addr.h linux/if_ether.h linux/if_tun.h linux/netlink.h linux/rtnetlink.h], [], [], [#ifdef HAVE_SYS_SOCKET_H diff --git a/libgo/go/syscall/syscall_linux_mipsx.go b/libgo/go/syscall/syscall_linux_mipsx.go index af319ac345f..06dd1ea2bc3 100644 --- a/libgo/go/syscall/syscall_linux_mipsx.go +++ b/libgo/go/syscall/syscall_linux_mipsx.go @@ -3,10 +3,24 @@ // license that can be found in the LICENSE file. // +build linux -// +build mips mipsle +// +build mips mipsle mips64 mips64le mips64p32 mips64p32le package syscall -func (r *PtraceRegs) PC() uint64 { return uint64(r.Regs[64]) } +import "unsafe" -func (r *PtraceRegs) SetPC(pc uint64) { r.Regs[64] = uint32(pc) } +func (r *PtraceRegs) PC() uint64 { + return r.Cp0_epc +} + +func (r *PtraceRegs) SetPC(pc uint64) { + r.Cp0_epc = pc +} + +func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) { + return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) +} + +func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) { + return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) +} diff --git a/libgo/mksysinfo.sh b/libgo/mksysinfo.sh index 1220b3ac617..8fd8eadefc6 100755 --- a/libgo/mksysinfo.sh +++ b/libgo/mksysinfo.sh @@ -317,9 +317,13 @@ if test "$regs" = ""; then upcase_fields "__user_psw_struct" "PtracePsw" >> ${OUT} || true upcase_fields "__user_fpregs_struct" "PtraceFpregs" >> ${OUT} || true upcase_fields "__user_per_struct" "PtracePer" >> ${OUT} || true + else + # mips* + regs=`grep '^type _pt_regs struct' gen-sysinfo.go || true` fi fi if test "$regs" != ""; then + regs=`echo $regs | sed -e 's/type _pt_regs struct//'` regs=`echo $regs | sed -e 's/type __*user_regs_struct struct //' -e 's/[{}]//g'` regs=`echo $regs | sed -e s'/^ *//'` diff --git a/libgo/sysinfo.c b/libgo/sysinfo.c index 235941b6211..a1afc7d119c 100644 --- a/libgo/sysinfo.c +++ b/libgo/sysinfo.c @@ -102,6 +102,9 @@ #if defined(HAVE_LINUX_NETLINK_H) #include #endif +#if defined(HAVE_LINUX_PTRACE_H) +#include +#endif #if defined(HAVE_LINUX_RTNETLINK_H) #include #endif -- 2.30.2