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
merge done from the gofrontend repository.

View File

@ -114,6 +114,9 @@
/* Define to 1 if you have the <linux/netlink.h> header file. */
#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. */
#undef HAVE_LINUX_REBOOT_H

2
libgo/configure vendored
View File

@ -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"

View File

@ -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

View File

@ -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)))
}

View File

@ -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'/^ *//'`

View File

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