# HG changeset patch # User Sofian Brabez # Date 1371942500 -7200 # Node ID a4f76dafe53531978a476c974dabde56ddfbaa5a # Parent 56909cb770fea8e2ac535775ca83594a490548e5 syscall: add dummy ptrace(2) support for syscall package and regenerate z* for GOOS=freebsd GOARCH=amd64 diff --git a/src/pkg/archive/tar/stat_atimespec.go b/src/pkg/archive/tar/stat_atimespec.go --- a/src/pkg/archive/tar/stat_atimespec.go +++ b/src/pkg/archive/tar/stat_atimespec.go @@ -12,9 +12,9 @@ ) func statAtime(st *syscall.Stat_t) time.Time { - return time.Unix(st.Atimespec.Unix()) + return time.Unix(st.Atim.Unix()) } func statCtime(st *syscall.Stat_t) time.Time { - return time.Unix(st.Ctimespec.Unix()) + return time.Unix(st.Ctim.Unix()) } diff --git a/src/pkg/os/stat_freebsd.go b/src/pkg/os/stat_freebsd.go --- a/src/pkg/os/stat_freebsd.go +++ b/src/pkg/os/stat_freebsd.go @@ -19,7 +19,7 @@ fs := &fileStat{ name: basename(name), size: int64(st.Size), - modTime: timespecToTime(st.Mtimespec), + modTime: timespecToTime(st.Mtim), sys: st, } fs.mode = FileMode(st.Mode & 0777) @@ -57,5 +57,5 @@ // For testing. func atime(fi FileInfo) time.Time { - return timespecToTime(fi.Sys().(*syscall.Stat_t).Atimespec) + return timespecToTime(fi.Sys().(*syscall.Stat_t).Atim) } diff --git a/src/pkg/syscall/mkerrors.sh b/src/pkg/syscall/mkerrors.sh --- a/src/pkg/syscall/mkerrors.sh +++ b/src/pkg/syscall/mkerrors.sh @@ -40,20 +40,21 @@ includes_FreeBSD=' #include #include +#include +#include +#include #include #include #include -#include #include -#include #include #include #include #include #include -#include #include #include +#include ' includes_Linux=' diff --git a/src/pkg/syscall/syscall_bsd.go b/src/pkg/syscall/syscall_bsd.go --- a/src/pkg/syscall/syscall_bsd.go +++ b/src/pkg/syscall/syscall_bsd.go @@ -620,3 +620,132 @@ func Munmap(b []byte) (err error) { return mapper.Munmap(b) } + +//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) + +func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) { + // The peek requests are machine-size oriented, so we wrap it + // to retrieve arbitrary-length data. + + // The ptrace syscall differs from glibc's ptrace. + // Peeks returns the word in *data, not as the return value. + + var buf [sizeofPtr]byte + + // Leading edge. PEEKTEXT/PEEKDATA don't require aligned + // access (PEEKUSER warns that it might), but if we don't + // align our reads, we might straddle an unmapped page + // boundary and not get the bytes leading up to the page + // boundary. + n := 0 + if addr%sizeofPtr != 0 { + err = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) + if err != nil { + return 0, err + } + n += copy(out, buf[addr%sizeofPtr:]) + out = out[n:] + } + + // Remainder. + for len(out) > 0 { + // We use an internal buffer to guarantee alignment. + // It's not documented if this is necessary, but we're paranoid. + err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0]))) + if err != nil { + return n, err + } + copied := copy(out, buf[0:]) + n += copied + out = out[copied:] + } + + return n, nil +} + +func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) { + return ptracePeek(PT_READ_I, pid, addr, out) +} + +func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) { + return ptracePeek(PT_READ_D, pid, addr, out) +} +func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) { + // As for ptracePeek, we need to align our accesses to deal + // with the possibility of straddling an invalid page. + + // Leading edge. + n := 0 + if addr%sizeofPtr != 0 { + var buf [sizeofPtr]byte + err = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) + if err != nil { + return 0, err + } + n += copy(buf[addr%sizeofPtr:], data) + word := *((*uintptr)(unsafe.Pointer(&buf[0]))) + err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word) + if err != nil { + return 0, err + } + data = data[n:] + } + + // Interior. + for len(data) > sizeofPtr { + word := *((*uintptr)(unsafe.Pointer(&data[0]))) + err = ptrace(pokeReq, pid, addr+uintptr(n), word) + if err != nil { + return n, err + } + n += sizeofPtr + data = data[sizeofPtr:] + } + + // Trailing edge. + if len(data) > 0 { + var buf [sizeofPtr]byte + err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0]))) + if err != nil { + return n, err + } + copy(buf[0:], data) + word := *((*uintptr)(unsafe.Pointer(&buf[0]))) + err = ptrace(pokeReq, pid, addr+uintptr(n), word) + if err != nil { + return n, err + } + n += len(data) + } + + return n, nil +} + +func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) { + return ptracePoke(PT_WRITE_I, PT_READ_I, pid, addr, data) +} + +func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) { + return ptracePoke(PT_WRITE_D, PT_READ_D, pid, addr, data) +} + +func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) { + return ptrace(PT_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) +} + +func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) { + return ptrace(PT_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) +} + +func PtraceCont(pid int, signal int) (err error) { + return ptrace(PT_CONTINUE, pid, 0, uintptr(signal)) +} + +func PtraceSyscall(pid int, signal int) (err error) { + return ptrace(PT_SYSCALL, pid, 0, uintptr(signal)) +} +func PtraceSingleStep(pid int) (err error) { return ptrace(PT_STEP, pid, 0, 0) } + +func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) } + +func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) } diff --git a/src/pkg/syscall/types_freebsd.go b/src/pkg/syscall/types_freebsd.go --- a/src/pkg/syscall/types_freebsd.go +++ b/src/pkg/syscall/types_freebsd.go @@ -41,6 +41,7 @@ #include #include #include +#include enum { sizeofPtr = sizeof(void*), @@ -59,6 +60,9 @@ char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)]; }; + +typedef struct reg PtraceRegs; + */ import "C" @@ -181,6 +185,11 @@ SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter ) +// Ptrace + +// Register structures +type PtraceRegs C.PtraceRegs + // Ptrace requests const ( diff --git a/src/pkg/syscall/zerrors_freebsd_amd64.go b/src/pkg/syscall/zerrors_freebsd_amd64.go --- a/src/pkg/syscall/zerrors_freebsd_amd64.go +++ b/src/pkg/syscall/zerrors_freebsd_amd64.go @@ -332,10 +332,11 @@ DLT_LINUX_SLL = 0x71 DLT_LOOP = 0x6c DLT_LTALK = 0x72 - DLT_MATCHING_MAX = 0xf2 + DLT_MATCHING_MAX = 0xf6 DLT_MATCHING_MIN = 0x68 DLT_MFR = 0xb6 DLT_MOST = 0xd3 + DLT_MPEG_2_TS = 0xf3 DLT_MPLS = 0xdb DLT_MTP2 = 0x8c DLT_MTP2_WITH_PHDR = 0x8b @@ -343,7 +344,9 @@ DLT_MUX27010 = 0xec DLT_NETANALYZER = 0xf0 DLT_NETANALYZER_TRANSPARENT = 0xf1 + DLT_NFC_LLCP = 0xf5 DLT_NFLOG = 0xef + DLT_NG40 = 0xf4 DLT_NULL = 0x0 DLT_PCI_EXP = 0x7d DLT_PFLOG = 0x75 @@ -438,7 +441,9 @@ FLUSHO = 0x800000 F_CANCEL = 0x5 F_DUP2FD = 0xa + F_DUP2FD_CLOEXEC = 0x12 F_DUPFD = 0x0 + F_DUPFD_CLOEXEC = 0x11 F_GETFD = 0x1 F_GETFL = 0x3 F_GETLK = 0xb @@ -516,7 +521,6 @@ IFT_BGPPOLICYACCOUNTING = 0xa2 IFT_BRIDGE = 0xd1 IFT_BSC = 0x53 - IFT_CARP = 0xf8 IFT_CCTEMUL = 0x3d IFT_CEPT = 0x13 IFT_CES = 0x85 @@ -787,6 +791,7 @@ IPPROTO_MHRP = 0x30 IPPROTO_MICP = 0x5f IPPROTO_MOBILE = 0x37 + IPPROTO_MPLS = 0x89 IPPROTO_MTP = 0x5c IPPROTO_MUX = 0x12 IPPROTO_ND = 0x4d @@ -1028,6 +1033,7 @@ MS_ASYNC = 0x1 MS_INVALIDATE = 0x2 MS_SYNC = 0x0 + NAME_MAX = 0xff NET_RT_DUMP = 0x1 NET_RT_FLAGS = 0x2 NET_RT_IFLIST = 0x3 @@ -1067,6 +1073,7 @@ O_ACCMODE = 0x3 O_APPEND = 0x8 O_ASYNC = 0x40 + O_CLOEXEC = 0x100000 O_CREAT = 0x200 O_DIRECT = 0x10000 O_DIRECTORY = 0x20000 @@ -1096,6 +1103,39 @@ PROT_NONE = 0x0 PROT_READ = 0x1 PROT_WRITE = 0x2 + PT_ATTACH = 0xa + PT_CLEARSTEP = 0x10 + PT_CONTINUE = 0x7 + PT_DETACH = 0xb + PT_FIRSTMACH = 0x40 + PT_FOLLOW_FORK = 0x17 + PT_GETDBREGS = 0x25 + PT_GETFPREGS = 0x23 + PT_GETLWPLIST = 0xf + PT_GETNUMLWPS = 0xe + PT_GETREGS = 0x21 + PT_GETXSTATE = 0x42 + PT_IO = 0xc + PT_KILL = 0x8 + PT_LWPINFO = 0xd + PT_READ_D = 0x2 + PT_READ_I = 0x1 + PT_RESUME = 0x13 + PT_SETDBREGS = 0x26 + PT_SETFPREGS = 0x24 + PT_SETREGS = 0x22 + PT_SETSTEP = 0x11 + PT_SETXSTATE = 0x43 + PT_STEP = 0x9 + PT_SUSPEND = 0x12 + PT_SYSCALL = 0x16 + PT_TO_SCE = 0x14 + PT_TO_SCX = 0x15 + PT_TRACE_ME = 0x0 + PT_VM_ENTRY = 0x29 + PT_VM_TIMESTAMP = 0x28 + PT_WRITE_D = 0x5 + PT_WRITE_I = 0x4 RLIMIT_AS = 0xa RLIMIT_CORE = 0x4 RLIMIT_CPU = 0x0 @@ -1175,6 +1215,7 @@ RTV_WEIGHT = 0x100 RT_CACHING_CONTEXT = 0x1 RT_DEFAULT_FIB = 0x0 + RT_NORTREF = 0x2 RUSAGE_CHILDREN = -0x1 RUSAGE_SELF = 0x0 RUSAGE_THREAD = 0x1 @@ -1187,7 +1228,7 @@ SHUT_WR = 0x1 SIOCADDMULTI = 0x80206931 SIOCADDRT = 0x8040720a - SIOCAIFADDR = 0x8040691a + SIOCAIFADDR = 0x8044692b SIOCAIFGROUP = 0x80286987 SIOCALIFADDR = 0x8118691b SIOCATMARK = 0x40047307 @@ -1249,7 +1290,7 @@ SIOCSIFMTU = 0x80206934 SIOCSIFNAME = 0x80206928 SIOCSIFNETMASK = 0x80206916 - SIOCSIFPHYADDR = 0x80406946 + SIOCSIFPHYADDR = 0x80446946 SIOCSIFPHYS = 0x80206936 SIOCSIFRVNET = 0xc020695b SIOCSIFVNET = 0xc020695a @@ -1405,10 +1446,12 @@ VWERASE = 0x4 WCONTINUED = 0x4 WCOREFLAG = 0x80 + WEXITED = 0x10 WLINUXCLONE = 0x80000000 WNOHANG = 0x1 WNOWAIT = 0x8 WSTOPPED = 0x2 + WTRAPPED = 0x20 WUNTRACED = 0x2 ) @@ -1529,6 +1572,7 @@ SIGIO = Signal(0x17) SIGIOT = Signal(0x6) SIGKILL = Signal(0x9) + SIGLIBRT = Signal(0x21) SIGLWP = Signal(0x20) SIGPIPE = Signal(0xd) SIGPROF = Signal(0x1b) @@ -1683,4 +1727,5 @@ 30: "user defined signal 1", 31: "user defined signal 2", 32: "unknown signal", + 33: "unknown signal", } diff --git a/src/pkg/syscall/zsyscall_freebsd_amd64.go b/src/pkg/syscall/zsyscall_freebsd_amd64.go --- a/src/pkg/syscall/zsyscall_freebsd_amd64.go +++ b/src/pkg/syscall/zsyscall_freebsd_amd64.go @@ -258,6 +258,16 @@ // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { + _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) + if e1 != 0 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func pipe() (r int, w int, err error) { r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0) r = int(r0) diff --git a/src/pkg/syscall/zsysnum_freebsd_amd64.go b/src/pkg/syscall/zsysnum_freebsd_amd64.go --- a/src/pkg/syscall/zsysnum_freebsd_amd64.go +++ b/src/pkg/syscall/zsysnum_freebsd_amd64.go @@ -34,8 +34,8 @@ SYS_GETPEERNAME = 31 // { int getpeername(int fdes, \ SYS_GETSOCKNAME = 32 // { int getsockname(int fdes, \ SYS_ACCESS = 33 // { int access(char *path, int amode); } - SYS_CHFLAGS = 34 // { int chflags(char *path, int flags); } - SYS_FCHFLAGS = 35 // { int fchflags(int fd, int flags); } + SYS_CHFLAGS = 34 // { int chflags(const char *path, u_long flags); } + SYS_FCHFLAGS = 35 // { int fchflags(int fd, u_long flags); } SYS_SYNC = 36 // { int sync(void); } SYS_KILL = 37 // { int kill(int pid, int signum); } SYS_GETPPID = 39 // { pid_t getppid(void); } @@ -208,14 +208,14 @@ SYS___ACL_ACLCHECK_FILE = 353 // { int __acl_aclcheck_file(const char *path, \ SYS___ACL_ACLCHECK_FD = 354 // { int __acl_aclcheck_fd(int filedes, \ SYS_EXTATTRCTL = 355 // { int extattrctl(const char *path, int cmd, \ - SYS_EXTATTR_SET_FILE = 356 // { int extattr_set_file( \ + SYS_EXTATTR_SET_FILE = 356 // { ssize_t extattr_set_file( \ SYS_EXTATTR_GET_FILE = 357 // { ssize_t extattr_get_file( \ SYS_EXTATTR_DELETE_FILE = 358 // { int extattr_delete_file(const char *path, \ SYS_GETRESUID = 360 // { int getresuid(uid_t *ruid, uid_t *euid, \ SYS_GETRESGID = 361 // { int getresgid(gid_t *rgid, gid_t *egid, \ SYS_KQUEUE = 362 // { int kqueue(void); } SYS_KEVENT = 363 // { int kevent(int fd, \ - SYS_EXTATTR_SET_FD = 371 // { int extattr_set_fd(int fd, \ + SYS_EXTATTR_SET_FD = 371 // { ssize_t extattr_set_fd(int fd, \ SYS_EXTATTR_GET_FD = 372 // { ssize_t extattr_get_fd(int fd, \ SYS_EXTATTR_DELETE_FD = 373 // { int extattr_delete_fd(int fd, \ SYS___SETUGID = 374 // { int __setugid(int flag); } @@ -228,7 +228,7 @@ SYS___MAC_SET_FD = 388 // { int __mac_set_fd(int fd, \ SYS___MAC_SET_FILE = 389 // { int __mac_set_file(const char *path_p, \ SYS_KENV = 390 // { int kenv(int what, const char *name, \ - SYS_LCHFLAGS = 391 // { int lchflags(const char *path, int flags); } + SYS_LCHFLAGS = 391 // { int lchflags(const char *path, \ SYS_UUIDGEN = 392 // { int uuidgen(struct uuid *store, \ SYS_SENDFILE = 393 // { int sendfile(int fd, int s, off_t offset, \ SYS_MAC_SYSCALL = 394 // { int mac_syscall(const char *policy, \ @@ -239,7 +239,7 @@ SYS___MAC_GET_PID = 409 // { int __mac_get_pid(pid_t pid, \ SYS___MAC_GET_LINK = 410 // { int __mac_get_link(const char *path_p, \ SYS___MAC_SET_LINK = 411 // { int __mac_set_link(const char *path_p, \ - SYS_EXTATTR_SET_LINK = 412 // { int extattr_set_link( \ + SYS_EXTATTR_SET_LINK = 412 // { ssize_t extattr_set_link( \ SYS_EXTATTR_GET_LINK = 413 // { ssize_t extattr_get_link( \ SYS_EXTATTR_DELETE_LINK = 414 // { int extattr_delete_link( \ SYS___MAC_EXECVE = 415 // { int __mac_execve(char *fname, char **argv, \ @@ -322,7 +322,7 @@ SYS_CLOSEFROM = 509 // { int closefrom(int lowfd); } SYS_LPATHCONF = 513 // { int lpathconf(char *path, int name); } SYS_CAP_NEW = 514 // { int cap_new(int fd, uint64_t rights); } - SYS_CAP_GETRIGHTS = 515 // { int cap_getrights(int fd, \ + SYS_CAP_RIGHTS_GET = 515 // { int cap_rights_get(int fd, \ SYS_CAP_ENTER = 516 // { int cap_enter(void); } SYS_CAP_GETMODE = 517 // { int cap_getmode(u_int *modep); } SYS_PDFORK = 518 // { int pdfork(int *fdp, int flags); } @@ -338,5 +338,15 @@ SYS_RCTL_REMOVE_RULE = 529 // { int rctl_remove_rule(const void *inbufp, \ SYS_POSIX_FALLOCATE = 530 // { int posix_fallocate(int fd, \ SYS_POSIX_FADVISE = 531 // { int posix_fadvise(int fd, off_t offset, \ - SYS_WAIT6 = 532 // { int wait6(int idtype, int id, \ + SYS_WAIT6 = 532 // { int wait6(int idtype, id_t id, \ + SYS_CAP_RIGHTS_LIMIT = 533 // { int cap_rights_limit(int fd, \ + SYS_CAP_IOCTLS_LIMIT = 534 // { int cap_ioctls_limit(int fd, \ + SYS_CAP_IOCTLS_GET = 535 // { ssize_t cap_ioctls_get(int fd, \ + SYS_CAP_FCNTLS_LIMIT = 536 // { int cap_fcntls_limit(int fd, \ + SYS_CAP_FCNTLS_GET = 537 // { int cap_fcntls_get(int fd, \ + SYS_BINDAT = 538 // { int bindat(int fd, int s, caddr_t name, \ + SYS_CONNECTAT = 539 // { int connectat(int fd, int s, caddr_t name, \ + SYS_CHFLAGSAT = 540 // { int chflagsat(int fd, const char *path, \ + SYS_ACCEPT4 = 541 // { int accept4(int s, \ + SYS_PIPE2 = 542 // { int pipe2(int *fildes, int flags); } ) diff --git a/src/pkg/syscall/ztypes_freebsd_amd64.go b/src/pkg/syscall/ztypes_freebsd_amd64.go --- a/src/pkg/syscall/ztypes_freebsd_amd64.go +++ b/src/pkg/syscall/ztypes_freebsd_amd64.go @@ -55,10 +55,6 @@ type _Gid_t uint32 const ( - O_CLOEXEC = 0 -) - -const ( S_IFMT = 0xf000 S_IFIFO = 0x1000 S_IFCHR = 0x2000 @@ -76,23 +72,23 @@ ) type Stat_t struct { - Dev uint32 - Ino uint32 - Mode uint16 - Nlink uint16 - Uid uint32 - Gid uint32 - Rdev uint32 - Atimespec Timespec - Mtimespec Timespec - Ctimespec Timespec - Size int64 - Blocks int64 - Blksize uint32 - Flags uint32 - Gen uint32 - Lspare int32 - Birthtimespec Timespec + Dev uint32 + Ino uint32 + Mode uint16 + Nlink uint16 + Uid uint32 + Gid uint32 + Rdev uint32 + Atim Timespec + Mtim Timespec + Ctim Timespec + Size int64 + Blocks int64 + Blksize uint32 + Flags uint32 + Gen uint32 + Lspare int32 + Birthtim Timespec } type Statfs_t struct { @@ -264,6 +260,35 @@ SizeofICMPv6Filter = 0x20 ) +type PtraceRegs struct { + R15 int64 + R14 int64 + R13 int64 + R12 int64 + R11 int64 + R10 int64 + R9 int64 + R8 int64 + Rdi int64 + Rsi int64 + Rbp int64 + Rbx int64 + Rdx int64 + Rcx int64 + Rax int64 + Trapno uint32 + Fs uint16 + Gs uint16 + Err uint32 + Es uint16 + Ds uint16 + Rip int64 + Cs int64 + Rflags int64 + Rsp int64 + Ss int64 +} + const ( PTRACE_TRACEME = 0x0 PTRACE_CONT = 0x7 @@ -310,8 +335,8 @@ Addrlen uint8 Hdrlen uint8 Link_state uint8 - Spare_char1 uint8 - Spare_char2 uint8 + Vhid uint8 + Baudrate_pf uint8 Datalen uint8 Mtu uint64 Metric uint64 exporting patch: