From 39466fdf6c3ee5c8aaa378ae29a05caa61ae8154 Mon Sep 17 00:00:00 2001 From: Kris Van Hees Date: Tue, 17 Jan 2012 15:03:17 -0500 Subject: [PATCH] Fix signed division and modulo operations in DIF. Ensure that SDT probe points are patched with a NOP sequence at boot time. Remove debugging output during SDT registration. Signed-off-by: Kris Van Hees --- dtrace/dtrace_dif.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/dtrace/dtrace_dif.c b/dtrace/dtrace_dif.c index 3a59d16f8dd5..a7cdb9f2ad95 100644 --- a/dtrace/dtrace_dif.c +++ b/dtrace/dtrace_dif.c @@ -3729,6 +3729,8 @@ uint64_t dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, regs[rd] = 0; *flags |= CPU_DTRACE_DIVZERO; } else { + int neg = 0; + /* * We cannot simply do a 64-bit division, since * gcc translates it into a call to a function @@ -3737,8 +3739,19 @@ uint64_t dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, * regs[rd] = (int64_t)regs[r1] / * (int64_t)regs[r2]; */ - regs[rd] = (int64_t)regs[r1]; - do_div(regs[rd], (int64_t)regs[r2]); + if ((int64_t)regs[r1] < 0) { + neg = !neg; + regs[r1] = -(int64_t)regs[r1]; + } + if ((int64_t)regs[r2] < 0) { + neg = !neg; + regs[r2] = -(int64_t)regs[r2]; + } + regs[rd] = regs[r1]; + do_div(regs[rd], regs[r2]); + + if (neg) + regs[rd] = -(int64_t)regs[rd]; } break; @@ -3764,6 +3777,8 @@ uint64_t dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, regs[rd] = 0; *flags |= CPU_DTRACE_DIVZERO; } else { + int neg = 0; + /* * We cannot simply do a 64-bit division, since * gcc translates it into a call to a function @@ -3772,8 +3787,19 @@ uint64_t dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, * regs[rd] = (int64_t)regs[r1] % * (int64_t)regs[r2]; */ - regs[rd] = (int64_t)regs[r1]; - regs[rd] = do_div(regs[rd], (int64_t)regs[r2]); + if ((int64_t)regs[r1] < 0) { + neg = !neg; + regs[r1] = -(int64_t)regs[r1]; + } + if ((int64_t)regs[r2] < 0) { + neg = !neg; + regs[r2] = -(int64_t)regs[r2]; + } + regs[rd] = regs[r1]; + regs[rd] = do_div(regs[rd], regs[r2]); + + if (neg) + regs[rd] = -(int64_t)regs[rd]; } break; -- 2.50.1