When fetching function arguments out of a frame on amd64, explicitly select
the register based on the argument index rather than relying on the fields in struct reg to be in the right order. This assumption is incorrect on FreeBSD and generally led to bogus argument values for the sixth argument of PID and USDT probes; the first five are passed directly to dtrace_probe() via the fasttrap trap handler and so were correctly handled. MFC after: 2 weeks
This commit is contained in:
parent
72c775da6c
commit
7e75d58610
@ -272,7 +272,20 @@ fasttrap_anarg(struct reg *rp, int function_entry, int argno)
|
||||
* registers.
|
||||
*/
|
||||
if (argno < 6)
|
||||
return ((&rp->r_rdi)[argno]);
|
||||
switch (argno) {
|
||||
case 0:
|
||||
return (rp->r_rdi);
|
||||
case 1:
|
||||
return (rp->r_rsi);
|
||||
case 2:
|
||||
return (rp->r_rdx);
|
||||
case 3:
|
||||
return (rp->r_rcx);
|
||||
case 4:
|
||||
return (rp->r_r8);
|
||||
case 5:
|
||||
return (rp->r_r9);
|
||||
}
|
||||
|
||||
stack = (uintptr_t *)rp->r_rsp;
|
||||
DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
|
||||
|
@ -367,7 +367,27 @@ dtrace_getarg(int arg, int aframes)
|
||||
sizeof (uintptr_t));
|
||||
|
||||
if (arg <= inreg) {
|
||||
stack = (uintptr_t *)&rp->r_rdi;
|
||||
switch (arg) {
|
||||
case 0:
|
||||
stack = (uintptr_t *)&rp->r_rdi;
|
||||
break;
|
||||
case 1:
|
||||
stack = (uintptr_t *)&rp->r_rsi;
|
||||
break;
|
||||
case 2:
|
||||
stack = (uintptr_t *)&rp->r_rdx;
|
||||
break;
|
||||
case 3:
|
||||
stack = (uintptr_t *)&rp->r_rcx;
|
||||
break;
|
||||
case 4:
|
||||
stack = (uintptr_t *)&rp->r_r8;
|
||||
break;
|
||||
case 5:
|
||||
stack = (uintptr_t *)&rp->r_r9;
|
||||
break;
|
||||
}
|
||||
arg = 0;
|
||||
} else {
|
||||
stack = (uintptr_t *)(rp->r_rsp);
|
||||
arg -= inreg;
|
||||
|
Loading…
x
Reference in New Issue
Block a user