here is a little review of mine... just little suggestions.

Index: i386/i386/trap.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/trap.c,v
retrieving revision 1.307
diff -u -r1.307 trap.c
--- i386/i386/trap.c    26 Jul 2007 15:32:55 -0000      1.307
+++ i386/i386/trap.c    22 Aug 2007 08:53:19 -0000
@@ -1004,6 +1004,32 @@
 
                PTRACESTOP_SC(p, td, S_PT_SCE);
 
+               if (__predict_false(p->p_sysent->sv_name[0]=='L')) {

please use __predict_true(p->p_sysent != &elf_linux_sysvec)

+                       if (code != frame->tf_eax) {
+                       printf("linux sysctl patched: code %d return eax %d\n", 
code, frame->tf_eax);
+                               /* retry */
+                               code = frame->tf_eax;
+                       
+                               if (p->p_sysent->sv_prepsyscall)
+                                       /*
+                                        * The prep code is MP aware.
+                                        */
+                                       (*p->p_sysent->sv_prepsyscall)(frame, 
args, &code, &params);
+                               /* else should always be null */
+
+                               if (p->p_sysent->sv_mask)
+                                       code &= p->p_sysent->sv_mask;

the sv_mask should be removed.. dont use it in your code. its entirely 
pointless when dealing
with Linux binaries

+                               if (code >= p->p_sysent->sv_size)
+                                       callp = &p->p_sysent->sv_table[0];
+                               else
+                                       callp = &p->p_sysent->sv_table[code];
+
+                               narg = callp->sy_narg;
+                               /* retry ends */
+                       }
+               }
+
                AUDIT_SYSCALL_ENTER(code, td);
                error = (*callp->sy_call)(td, args);
                AUDIT_SYSCALL_EXIT(error, td);
Index: i386/linux/linux_ptrace.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/linux/linux_ptrace.c,v
retrieving revision 1.17
diff -u -r1.17 linux_ptrace.c
--- i386/linux/linux_ptrace.c   22 Feb 2006 18:57:49 -0000      1.17
+++ i386/linux/linux_ptrace.c   22 Aug 2007 09:27:01 -0000
@@ -78,6 +78,7 @@
 #define PTRACE_SETFPXREGS      19
 
 #define PTRACE_SETOPTIONS      21
+#define PTRACE_O_TRACESYSGOOD  0x00000001
 
 /*
  * Linux keeps debug registers at the following
@@ -95,6 +96,10 @@
        return ((signum == SIGSTOP)? 0 : signum);
 }
 
+struct linux_pt_lreg {
+       l_long reg[19];
+};
+
 struct linux_pt_reg {
        l_long  ebx;
        l_long  ecx;
@@ -103,17 +108,17 @@
        l_long  edi;
        l_long  ebp;
        l_long  eax;
-       l_int   xds;
-       l_int   xes;
-       l_int   xfs;
-       l_int   xgs;
+       l_long  xds;
+       l_long  xes;
+       l_long  xfs;
+       l_long  xgs;
        l_long  orig_eax;
        l_long  eip;
-       l_int   xcs;
+       l_long  xcs;
        l_long  eflags;
        l_long  esp;
-       l_int   xss;
-};
+       l_long  xss;
+} __packed;

why is this necessary? how does it affect amd64 linux32 emulator?
 
 /*
  *   Translate i386 ptrace registers between Linux and FreeBSD formats.
@@ -247,6 +252,7 @@
                struct linux_pt_reg     reg;
                struct linux_pt_fpreg   fpreg;
                struct linux_pt_fpxreg  fpxreg;
+               struct linux_pt_lreg    lreg;
        } r;
        union {
                struct reg              bsd_reg;
@@ -429,20 +435,21 @@
                 * as necessary.
                 */
                if (uap->addr < sizeof(struct linux_pt_reg)) {
+                       if (uap->addr == (11 << 2)) /* orig_eax */
+                               uap->addr = (6 << 2); /* eax */
+                       
                        error = kern_ptrace(td, PT_GETREGS, pid, &u.bsd_reg, 0);
                        if (error != 0)
                                break;
 
                        map_regs_to_linux(&u.bsd_reg, &r.reg);
                        if (req == PTRACE_PEEKUSR) {
-                               error = copyout((char *)&r.reg + uap->addr,
-                                   (void *)uap->data, sizeof(l_int));
+                               error = 
copyout((l_long*)(&r.lreg.reg[uap->addr>>2]),
+                                   (void *)uap->data, sizeof(l_long));
                                break;
                        }
 
-                       *(l_int *)((char *)&r.reg + uap->addr) =
-                           (l_int)uap->data;
-
+                       r.lreg.reg[uap->addr>>2] = (l_long)uap->data;
                        map_regs_from_linux(&u.bsd_reg, &r.reg);
                        error = kern_ptrace(td, PT_SETREGS, pid, &u.bsd_reg, 0);
                }
@@ -470,11 +477,34 @@
                        error = kern_ptrace(td, PT_SETDBREGS, pid,
                            &u.bsd_dbreg, 0);
                }
-
+       }
+               break;
+       case PTRACE_SETOPTIONS: {
+               struct proc *p;
+               if (uap->data == PTRACE_O_TRACESYSGOOD) {
+                       p = td->td_proc;
+                       PROC_LOCK(p);
+                       p->p_stops |= S_PT_SYSGOOD;
+                       PROC_UNLOCK(p);
+                       break;
+               }
+               printf("linux: ptrace(21,...,%u) not implemented\n",
+                   (unsigned int)uap->data);
+               error = EINVAL;
+               }
                break;

braces around case "case" ? please remove (the blocking there is implicit) and 
introduce
procedure-wide "p"

+       case PTRACE_SYSCALL: {
+               struct proc *p;
+
+               p = td->td_proc;
+               PROC_LOCK(p);
+               p->p_stops |= S_PT_LINUX;
+               PROC_UNLOCK(p);
+
+               if (addr == NULL) addr = (void *)1;
+               error = kern_ptrace(td, PT_SYSCALL, pid, addr, uap->data);
        }
-       case PTRACE_SYSCALL:
-               /* fall through */
+               break;

ditto.

        default:
                printf("linux: ptrace(%u, ...) not implemented\n",
                    (unsigned int)uap->req);
Index: sys/cdefs.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/cdefs.h,v
retrieving revision 1.93
diff -u -r1.93 cdefs.h
--- sys/cdefs.h 21 Sep 2006 01:38:58 -0000      1.93
+++ sys/cdefs.h 10 Aug 2007 18:01:34 -0000
@@ -338,6 +338,10 @@
 #endif
 
 /* Compiler-dependent macros that rely on FreeBSD-specific extensions. */
+#ifndef __FreeBSD_cc_version
+#define __FreeBSD_cc_version 0
+#endif
+
 #if __FreeBSD_cc_version >= 300001 && defined(__GNUC__) && 
!defined(__INTEL_COMPILER)
 #define        __printf0like(fmtarg, firstvararg) \
            __attribute__((__format__ (__printf0__, fmtarg, firstvararg)))
Index: sys/ptrace.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/ptrace.h,v
retrieving revision 1.28
diff -u -r1.28 ptrace.h
--- sys/ptrace.h        6 Feb 2006 09:41:56 -0000       1.28
+++ sys/ptrace.h        22 Aug 2007 08:53:45 -0000
@@ -103,7 +103,12 @@
 #define        PTRACESTOP_SC(p, td, flag)                              \
        if ((p)->p_flag & P_TRACED && (p)->p_stops & (flag)) {  \
                PROC_LOCK(p);                                   \
-               ptracestop((td), SIGTRAP);                      \
+               if (__predict_false(p->p_sysent->sv_name[0]=='L')) { \

please use p->p_sysent instead like stated above

+                       (p)->p_stops &= ~(S_PT_SCE | S_PT_SCX); \
+                       ptracestop((td), SIGTRAP | 0x80);       \
+                       }                                       \
+               else                                            \
+                       ptracestop((td), SIGTRAP);              \
                PROC_UNLOCK(p);                                 \
        }
 /*
@@ -112,6 +117,16 @@
  */
 #define        S_PT_SCE        0x000010000
 #define        S_PT_SCX        0x000020000
+/* 
+ * Linux ptrace conventions: clear S_PT_SCE and S_PT_SCX before raising
+ * signals
+ */
+#define S_PT_LINUX     0x000040000
+/* 
+ * Linux ptrace option PTRACE_O_TRACESYSGOOD, when enabled, changes signal
+ * number to ( SIGTRAP | 0x80 )
+ */
+#define S_PT_SYSGOOD   0x000080000
 
 int    ptrace_set_pc(struct thread *_td, unsigned long _addr);
 int    ptrace_single_step(struct thread *_td);
Index: compat/linux/linux_misc.c
===================================================================
RCS file: /home/ncvs/src/sys/compat/linux/linux_misc.c,v
retrieving revision 1.213
diff -u -r1.213 linux_misc.c
--- compat/linux/linux_misc.c   12 Jun 2007 00:11:57 -0000      1.213
+++ compat/linux/linux_misc.c   22 Aug 2007 09:07:34 -0000
@@ -63,6 +63,7 @@
 #include <sys/vmmeter.h>
 #include <sys/vnode.h>
 #include <sys/wait.h>
+#include <sys/ptrace.h>
 
 #include <security/mac/mac_framework.h>
 
@@ -852,6 +853,8 @@
 
        if (args->status) {
                tmpstat &= 0xffff;
+               if (!(td->td_proc->p_stops & S_PT_SYSGOOD))
+                       tmpstat &= 0x7fff;
                if (WIFSIGNALED(tmpstat))
                        tmpstat = (tmpstat & 0xffffff80) |
                            BSD_TO_LINUX_SIGNAL(WTERMSIG(tmpstat));
@@ -898,6 +901,8 @@
 
        if (args->status) {
                tmpstat &= 0xffff;
+               if (!(td->td_proc->p_stops & S_PT_SYSGOOD))
+                       tmpstat &= 0x7fff;
                if (WIFSIGNALED(tmpstat))
                        tmpstat = (tmpstat & 0xffffff80) |
                            BSD_TO_LINUX_SIGNAL(WTERMSIG(tmpstat));


thnx for the patch!

roman                       
_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to