Three updates to PowerPC FBT:

* Use a constant to define the number of stack frames in a probe exception.
* Only allow function symbols in powerpc64 ('.' prefixed)
* Set the fbtp_roffset for return probes, so the correct dtrace_probe call is
  made.

MFC after:	1 week
This commit is contained in:
jhibbits 2014-10-24 03:33:01 +00:00
parent 72aeed53f4
commit 251119f0e6

View File

@ -48,6 +48,7 @@
#define FBT_ENTRY "entry" #define FBT_ENTRY "entry"
#define FBT_RETURN "return" #define FBT_RETURN "return"
#define FBT_AFRAMES 7
int int
fbt_invop(uintptr_t addr, uintptr_t *stack, uintptr_t rval) fbt_invop(uintptr_t addr, uintptr_t *stack, uintptr_t rval)
@ -116,9 +117,17 @@ fbt_provide_module_function(linker_file_t lf, int symindx,
int j; int j;
uint32_t *instr, *limit; uint32_t *instr, *limit;
/* PowerPC64 uses '.' prefixes on symbol names, ignore it. */ #ifdef __powerpc64__
/*
* PowerPC64 uses '.' prefixes on symbol names, ignore it, but only
* allow symbols with the '.' prefix, so that we don't get the function
* descriptor instead.
*/
if (name[0] == '.') if (name[0] == '.')
name++; name++;
else
return (0);
#endif
if (strncmp(name, "dtrace_", 7) == 0 && if (strncmp(name, "dtrace_", 7) == 0 &&
strncmp(name, "dtrace_safe_", 12) != 0) { strncmp(name, "dtrace_safe_", 12) != 0) {
@ -147,7 +156,7 @@ fbt_provide_module_function(linker_file_t lf, int symindx,
fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO); fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO);
fbt->fbtp_name = name; fbt->fbtp_name = name;
fbt->fbtp_id = dtrace_probe_create(fbt_id, modname, fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
name, FBT_ENTRY, 7, fbt); name, FBT_ENTRY, FBT_AFRAMES, fbt);
fbt->fbtp_patchpoint = instr; fbt->fbtp_patchpoint = instr;
fbt->fbtp_ctl = lf; fbt->fbtp_ctl = lf;
fbt->fbtp_loadcnt = lf->loadcnt; fbt->fbtp_loadcnt = lf->loadcnt;
@ -210,7 +219,7 @@ fbt_provide_module_function(linker_file_t lf, int symindx,
if (retfbt == NULL) { if (retfbt == NULL) {
fbt->fbtp_id = dtrace_probe_create(fbt_id, modname, fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
name, FBT_RETURN, 7, fbt); name, FBT_RETURN, FBT_AFRAMES, fbt);
} else { } else {
retfbt->fbtp_next = fbt; retfbt->fbtp_next = fbt;
fbt->fbtp_id = retfbt->fbtp_id; fbt->fbtp_id = retfbt->fbtp_id;
@ -229,6 +238,9 @@ fbt_provide_module_function(linker_file_t lf, int symindx,
else else
fbt->fbtp_rval = DTRACE_INVOP_JUMP; fbt->fbtp_rval = DTRACE_INVOP_JUMP;
fbt->fbtp_roffset =
(uintptr_t)((uint8_t *)instr - (uint8_t *)symval->value);
fbt->fbtp_savedval = *instr; fbt->fbtp_savedval = *instr;
fbt->fbtp_patchval = FBT_PATCHVAL; fbt->fbtp_patchval = FBT_PATCHVAL;
fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)]; fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];