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
This commit is contained in:
Ian Lance Taylor 2017-06-21 21:42:41 +00:00
parent 4ded86690e
commit 8d4b68a7c4
7 changed files with 30 additions and 6 deletions

View file

@ -1,4 +1,4 @@
6449e2832eef94eacf89c88fa16bede637f729ba b2bebba1f8a8185546c47f8460a3d5c2e31d0434
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.

View file

@ -114,6 +114,9 @@
/* Define to 1 if you have the <linux/netlink.h> header file. */ /* Define to 1 if you have the <linux/netlink.h> header file. */
#undef HAVE_LINUX_NETLINK_H #undef HAVE_LINUX_NETLINK_H
/* Define to 1 if you have the <linux/ptrace.h> header file. */
#undef HAVE_LINUX_PTRACE_H
/* Define to 1 if you have the <linux/reboot.h> header file. */ /* Define to 1 if you have the <linux/reboot.h> header file. */
#undef HAVE_LINUX_REBOOT_H #undef HAVE_LINUX_REBOOT_H

2
libgo/configure vendored
View file

@ -14782,7 +14782,7 @@ $as_echo "#define HAVE_GETIPINFO 1" >>confdefs.h
fi 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 : do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` 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" ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"

View file

@ -580,7 +580,7 @@ AC_C_BIGENDIAN
GCC_CHECK_UNWIND_GETIPINFO 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], [], [], 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 [#ifdef HAVE_SYS_SOCKET_H

View file

@ -3,10 +3,24 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build linux // +build linux
// +build mips mipsle // +build mips mipsle mips64 mips64le mips64p32 mips64p32le
package syscall 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)))
}

View file

@ -317,9 +317,13 @@ if test "$regs" = ""; then
upcase_fields "__user_psw_struct" "PtracePsw" >> ${OUT} || true upcase_fields "__user_psw_struct" "PtracePsw" >> ${OUT} || true
upcase_fields "__user_fpregs_struct" "PtraceFpregs" >> ${OUT} || true upcase_fields "__user_fpregs_struct" "PtraceFpregs" >> ${OUT} || true
upcase_fields "__user_per_struct" "PtracePer" >> ${OUT} || true upcase_fields "__user_per_struct" "PtracePer" >> ${OUT} || true
else
# mips*
regs=`grep '^type _pt_regs struct' gen-sysinfo.go || true`
fi fi
fi fi
if test "$regs" != ""; then if test "$regs" != ""; then
regs=`echo $regs | sed -e 's/type _pt_regs struct//'`
regs=`echo $regs | regs=`echo $regs |
sed -e 's/type __*user_regs_struct struct //' -e 's/[{}]//g'` sed -e 's/type __*user_regs_struct struct //' -e 's/[{}]//g'`
regs=`echo $regs | sed -e s'/^ *//'` regs=`echo $regs | sed -e s'/^ *//'`

View file

@ -102,6 +102,9 @@
#if defined(HAVE_LINUX_NETLINK_H) #if defined(HAVE_LINUX_NETLINK_H)
#include <linux/netlink.h> #include <linux/netlink.h>
#endif #endif
#if defined(HAVE_LINUX_PTRACE_H)
#include <linux/ptrace.h>
#endif
#if defined(HAVE_LINUX_RTNETLINK_H) #if defined(HAVE_LINUX_RTNETLINK_H)
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#endif #endif