Mercurial > illumos > illumos-gate
changeset 6988:6e7ccf1f1466
6721057 tst.sdtargs.d fails on 7th sdt arg on amd64
author | brendan |
---|---|
date | Tue, 01 Jul 2008 11:12:03 -0700 |
parents | 877c018eb06c |
children | 7385b7b2ab40 |
files | usr/src/uts/intel/dtrace/sdt.c |
diffstat | 1 files changed, 32 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/intel/dtrace/sdt.c Tue Jul 01 10:31:58 2008 -0700 +++ b/usr/src/uts/intel/dtrace/sdt.c Tue Jul 01 11:12:03 2008 -0700 @@ -319,9 +319,7 @@ * If we pass through the invalid op handler, we will * use the pointer that it passed to the stack as the * second argument to dtrace_invop() as the pointer to - * the stack. When using this stack, we must step - * beyond the EIP/RIP that was pushed when the trap was - * taken -- hence the "+ 1" below. + * the stack. */ stack = ((uintptr_t **)&fp[1])[1]; #else @@ -329,17 +327,15 @@ * In the case of amd64, we will use the pointer to the * regs structure that was pushed when we took the * trap. To get this structure, we must increment - * beyond the frame structure, and then again beyond - * the calling RIP stored in dtrace_invop(). If the - * argument that we're seeking is passed on the stack, - * we'll pull the true stack pointer out of the saved - * registers and decrement our argument by the number - * of arguments passed in registers; if the argument + * beyond the frame structure. If the argument that + * we're seeking is passed on the stack, we'll pull + * the true stack pointer out of the saved registers + * and decrement our argument by the number of + * arguments passed in registers; if the argument * we're seeking is passed in regsiters, we can just * load it directly. */ - struct regs *rp = (struct regs *)((uintptr_t)&fp[1] + - sizeof (uintptr_t)); + struct regs *rp = (struct regs *)&fp[1]; if (argno <= inreg) { stack = (uintptr_t *)&rp->r_rdi; @@ -352,6 +348,31 @@ } } + /* + * We know that we did not come through a trap to get into + * dtrace_probe() -- the provider simply called dtrace_probe() + * directly. As this is the case, we need to shift the argument + * that we're looking for: the probe ID is the first argument to + * dtrace_probe(), so the argument n will actually be found where + * one would expect to find argument (n + 1). + */ + argno++; + +#if defined(__amd64) + if (argno <= inreg) { + /* + * This shouldn't happen. If the argument is passed in a + * register then it should have been, well, passed in a + * register... + */ + DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); + return (0); + } + + argno -= (inreg + 1); +#endif + stack = (uintptr_t *)&fp[1]; + load: DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); val = stack[argno];