mirror of
https://github.com/golang/sys.git
synced 2026-02-08 19:56:04 +03:00
unix: add functions PtraceGetRegSetArm64 and PtraceSetRegSetArm64
Since arm64 GNU/Linux version 2.6.34, PTRACE_GETREGS was replaced by PTRACE_GETREGSET, in order to get or set the general purpose and floating-point register values, PTRACE_GETREGSET/PTRACE_SETREGSET request type and a proper "NT_XXX" constant values should be used. For the sake of not breaking the existing API, we added two functions PtraceGetRegSetArm64 and PtraceSetRegSetArm64, they take an additional argument "addr", and use PTRACE_GETREGSET and PTRACE_SETREGSET request types respectively. Change-Id: I14c55733e15cea4b7d775187b1018fcb2880d6a9 Reviewed-on: https://go-review.googlesource.com/c/sys/+/204418 Run-TryBot: eric fang <eric.fang@arm.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
committed by
Ian Lance Taylor
parent
ce4227a45e
commit
bc7efcf3b8
@@ -144,12 +144,16 @@ var targets = []target{
|
||||
}
|
||||
|
||||
// ptracePairs is a list of pairs of targets that can, in some cases,
|
||||
// run each other's binaries.
|
||||
var ptracePairs = []struct{ a1, a2 string }{
|
||||
{"386", "amd64"},
|
||||
{"arm", "arm64"},
|
||||
{"mips", "mips64"},
|
||||
{"mipsle", "mips64le"},
|
||||
// run each other's binaries. 'archName' is the combined name of 'a1'
|
||||
// and 'a2', which is used in the file name. Generally we use an 'x'
|
||||
// suffix in the file name to indicate that the file works for both
|
||||
// big-endian and little-endian, here we use 'nn' to indicate that this
|
||||
// file is suitable for 32-bit and 64-bit.
|
||||
var ptracePairs = []struct{ a1, a2, archName string }{
|
||||
{"386", "amd64", "x86"},
|
||||
{"arm", "arm64", "armnn"},
|
||||
{"mips", "mips64", "mipsnn"},
|
||||
{"mipsle", "mips64le", "mipsnnle"},
|
||||
}
|
||||
|
||||
func main() {
|
||||
@@ -186,7 +190,7 @@ func main() {
|
||||
fmt.Printf("----- GENERATING ptrace pairs -----\n")
|
||||
ok := true
|
||||
for _, p := range ptracePairs {
|
||||
if err := generatePtracePair(p.a1, p.a2); err != nil {
|
||||
if err := generatePtracePair(p.a1, p.a2, p.archName); err != nil {
|
||||
fmt.Printf("%v\n***** FAILURE: %s/%s *****\n\n", err, p.a1, p.a2)
|
||||
ok = false
|
||||
}
|
||||
@@ -545,8 +549,9 @@ func (t *target) mksyscallFlags() (flags []string) {
|
||||
// type for each one. It writes a new file defining the types
|
||||
// PtraceRegsArch1 and PtraceRegsArch2 and the corresponding functions
|
||||
// Ptrace{Get,Set}Regs{arch1,arch2}. This permits debugging the other
|
||||
// binary on a native system.
|
||||
func generatePtracePair(arch1, arch2 string) error {
|
||||
// binary on a native system. 'archName' is the combined name of 'arch1'
|
||||
// and 'arch2', which is used in the file name.
|
||||
func generatePtracePair(arch1, arch2, archName string) error {
|
||||
def1, err := ptraceDef(arch1)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -555,12 +560,12 @@ func generatePtracePair(arch1, arch2 string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := os.Create(fmt.Sprintf("zptrace%s_linux.go", arch1))
|
||||
f, err := os.Create(fmt.Sprintf("zptrace_%s_linux.go", archName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buf := bufio.NewWriter(f)
|
||||
fmt.Fprintf(buf, "// Code generated by linux/mkall.go generatePtracePair(%s, %s). DO NOT EDIT.\n", arch1, arch2)
|
||||
fmt.Fprintf(buf, "// Code generated by linux/mkall.go generatePtracePair(%q, %q). DO NOT EDIT.\n", arch1, arch2)
|
||||
fmt.Fprintf(buf, "\n")
|
||||
fmt.Fprintf(buf, "// +build linux\n")
|
||||
fmt.Fprintf(buf, "// +build %s %s\n", arch1, arch2)
|
||||
@@ -572,6 +577,10 @@ func generatePtracePair(arch1, arch2 string) error {
|
||||
writeOnePtrace(buf, arch1, def1)
|
||||
fmt.Fprintf(buf, "\n")
|
||||
writeOnePtrace(buf, arch2, def2)
|
||||
if arch2 == "arm64" {
|
||||
fmt.Fprintf(buf, "\n")
|
||||
writeOnePtraceRegSet(buf, arch2)
|
||||
}
|
||||
if err := buf.Flush(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -617,6 +626,23 @@ func writeOnePtrace(w io.Writer, arch, def string) {
|
||||
fmt.Fprintf(w, "}\n")
|
||||
}
|
||||
|
||||
// writeOnePtraceRegSet writes out the ptrace definitions of PTRACE_GETREGSET and
|
||||
// PTRACE_SETREGSET request type.
|
||||
func writeOnePtraceRegSet(w io.Writer, arch string) {
|
||||
uarch := string(unicode.ToUpper(rune(arch[0]))) + arch[1:]
|
||||
fmt.Fprintf(w, "// PtraceGetRegSet%s fetches the registers used by %s binaries.\n", uarch, arch)
|
||||
fmt.Fprintf(w, "func PtraceGetRegSet%s(pid, addr int, regsout *PtraceRegs%s) error {\n", uarch, uarch)
|
||||
fmt.Fprintf(w, "\tiovec := Iovec{(*byte)(unsafe.Pointer(regsout)), uint64(unsafe.Sizeof(*regsout))}\n")
|
||||
fmt.Fprintf(w, "\treturn ptrace(PTRACE_GETREGSET, pid, uintptr(addr), uintptr(unsafe.Pointer(&iovec)))\n")
|
||||
fmt.Fprintf(w, "}\n")
|
||||
fmt.Fprintf(w, "\n")
|
||||
fmt.Fprintf(w, "// PtraceSetRegSet%s sets the registers used by %s binaries.\n", uarch, arch)
|
||||
fmt.Fprintf(w, "func PtraceSetRegSet%s(pid, addr int, regs *PtraceRegs%s) error {\n", uarch, uarch)
|
||||
fmt.Fprintf(w, "\tiovec := Iovec{(*byte)(unsafe.Pointer(regs)), uint64(unsafe.Sizeof(*regs))}\n")
|
||||
fmt.Fprintf(w, "\treturn ptrace(PTRACE_SETREGSET, pid, uintptr(addr), uintptr(unsafe.Pointer(&iovec)))\n")
|
||||
fmt.Fprintf(w, "}\n")
|
||||
}
|
||||
|
||||
// cCode is compiled for the target architecture, and the resulting data section is carved for
|
||||
// the statically initialized bit masks.
|
||||
const cCode = `
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by linux/mkall.go generatePtracePair(arm, arm64). DO NOT EDIT.
|
||||
// Code generated by linux/mkall.go generatePtracePair("arm", "arm64"). DO NOT EDIT.
|
||||
|
||||
// +build linux
|
||||
// +build arm arm64
|
||||
@@ -39,3 +39,15 @@ func PtraceGetRegsArm64(pid int, regsout *PtraceRegsArm64) error {
|
||||
func PtraceSetRegsArm64(pid int, regs *PtraceRegsArm64) error {
|
||||
return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))
|
||||
}
|
||||
|
||||
// PtraceGetRegSetArm64 fetches the registers used by arm64 binaries.
|
||||
func PtraceGetRegSetArm64(pid, addr int, regsout *PtraceRegsArm64) error {
|
||||
iovec := Iovec{(*byte)(unsafe.Pointer(regsout)), uint64(unsafe.Sizeof(*regsout))}
|
||||
return ptrace(PTRACE_GETREGSET, pid, uintptr(addr), uintptr(unsafe.Pointer(&iovec)))
|
||||
}
|
||||
|
||||
// PtraceSetRegSetArm64 sets the registers used by arm64 binaries.
|
||||
func PtraceSetRegSetArm64(pid, addr int, regs *PtraceRegsArm64) error {
|
||||
iovec := Iovec{(*byte)(unsafe.Pointer(regs)), uint64(unsafe.Sizeof(*regs))}
|
||||
return ptrace(PTRACE_SETREGSET, pid, uintptr(addr), uintptr(unsafe.Pointer(&iovec)))
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by linux/mkall.go generatePtracePair(mips, mips64). DO NOT EDIT.
|
||||
// Code generated by linux/mkall.go generatePtracePair("mips", "mips64"). DO NOT EDIT.
|
||||
|
||||
// +build linux
|
||||
// +build mips mips64
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by linux/mkall.go generatePtracePair(mipsle, mips64le). DO NOT EDIT.
|
||||
// Code generated by linux/mkall.go generatePtracePair("mipsle", "mips64le"). DO NOT EDIT.
|
||||
|
||||
// +build linux
|
||||
// +build mipsle mips64le
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by linux/mkall.go generatePtracePair(386, amd64). DO NOT EDIT.
|
||||
// Code generated by linux/mkall.go generatePtracePair("386", "amd64"). DO NOT EDIT.
|
||||
|
||||
// +build linux
|
||||
// +build 386 amd64
|
||||
Reference in New Issue
Block a user