summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarkj <markj@FreeBSD.org>2014-08-04 21:41:00 +0000
committermarkj <markj@FreeBSD.org>2014-08-04 21:41:00 +0000
commita14261c0897b808f7557a5960fb3c6432f216d36 (patch)
tree66bcf79d723c80a39adae837328093ade8296f2d
parent2fd28e23736da641dbe3990391f997fb55353b17 (diff)
downloadFreeBSD-src-a14261c0897b808f7557a5960fb3c6432f216d36.zip
FreeBSD-src-a14261c0897b808f7557a5960fb3c6432f216d36.tar.gz
MFC r256822:
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.
-rw-r--r--sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c15
-rw-r--r--sys/cddl/dev/dtrace/amd64/dtrace_isa.c22
2 files changed, 35 insertions, 2 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c b/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c
index 22dbda4..778a84d 100644
--- a/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c
+++ b/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c
@@ -273,7 +273,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);
diff --git a/sys/cddl/dev/dtrace/amd64/dtrace_isa.c b/sys/cddl/dev/dtrace/amd64/dtrace_isa.c
index 34d6f33..3d3c43c 100644
--- a/sys/cddl/dev/dtrace/amd64/dtrace_isa.c
+++ b/sys/cddl/dev/dtrace/amd64/dtrace_isa.c
@@ -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;
OpenPOWER on IntegriCloud