;;;
;;; ptrace.lisp
;;;
;;; Constants and bindings for ptrace(2).
;;;

(cl:in-package :lh-linuxapi)

;; So, of course, ptrace identifiers are per-architecture.  And the
;; version in the system headers is a subset and doesn't even contain
;; all of the constants mentioned in the manpage, and the manpage
;; doesn't mention a couple of constants defined in the system
;; headers.  But to a certain extent this doesn't matter, as we're
;; working with linux, so the linux kernel headers trump the system
;; headers.

;; These from kernel include/linux/ptrace.h
(defconstant ptrace-traceme 0)
(defconstant ptrace-peektext 1)
(defconstant ptrace-peekdata 2)
(defconstant ptrace-peekuser 3)
(defconstant ptrace-poketext 4)
(defconstant ptrace-pokedata 5)
(defconstant ptrace-pokeuser 6)
(defconstant ptrace-cont 7)
(defconstant ptrace-kill 8)
(defconstant ptrace-singlestep 9)

(defconstant ptrace-attach 16)
(defconstant ptrace-detach 17)

(defconstant ptrace-syscall 24)

(defconstant ptrace-setoptions #x4200)
(defconstant ptrace-geteventmsg #x4201)
(defconstant ptrace-getsiginfo #x4202)
(defconstant ptrace-setsiginfo #x4203)

(defconstant ptrace-o-tracesysgood #x00000001)
(defconstant ptrace-o-tracefork #x00000002)
(defconstant ptrace-o-tracevfork #x00000004)
(defconstant ptrace-o-traceclone #x00000008)
(defconstant ptrace-o-traceexec #x00000010)
(defconstant ptrace-o-tracevforkdone #x00000020)
(defconstant ptrace-o-traceexit #x00000040)
(defconstant ptrace-o-mask #x0000007f)

(defconstant ptrace-event-fork 1)
(defconstant ptrace-event-vfork 2)
(defconstant ptrace-event-clone 3)
(defconstant ptrace-event-exec 4)
(defconstant ptrace-event-vfork-done 5)
(defconstant ptrace-event-exit 6)
;; End from kernel include/linux/ptrace.h

;; These from kernel arch/x86/include/asm/ptrace-abi.h
(defconstant ptrace-getregs 12)
(defconstant ptrace-setregs 13)
(defconstant ptrace-getfpregs 14)
(defconstant ptrace-setfpregs 15)
(defconstant ptrace-getfpxregs 18)
(defconstant ptrace-setfpxregs 19)

(defconstant ptrace-oldsetoptions 21)

(defconstant ptrace-sysemu 31)
(defconstant ptrace-sysemu-singlestep 32)

(defconstant ptrace-singleblock 33)

;; There was also some stuff about "BTS", which has to do with branch
;; tracing.  Not bothering yet.  Also had some register layout stuff?

;; End from kernel arch/x86/include/asm/ptrace-abi.h


;; The prototype for ptrace is (from the man page):
;;
;;     long ptrace(enum __ptrace_request request, pid_t pid,
;;                 void *addr, void *data);

(declaim (inline ptrace))
(defun ptrace (request pid addr data)
  "ptrace(2) system call.  See linux man-page for details.  Returns
two values.  First, the return value from ptrace(2).  Second, the
value of errno, or 0 if the first value is not -1 (not necessarily an
error for three requests).  Note that addr and data are exposed as (*
t) alien values but are sometimes required to hold an integer value,
for these cases, use (sap-alien (int-sap <value>) (* t))."
  ;; FIXME: If we had SET-ERRNO, we could clear up the inconsistency
  ;; with the peek{text,data,user} requests.
  (let ((result (alien-funcall (extern-alien "ptrace"
					     (function long
						       int pid-t (* t) (* t)))
			       request pid addr data)))
    (if (= -1 result)
	(values -1 (get-errno))
	(values result 0))))


;;; EOF
