Changeset View
Changeset View
Standalone View
Standalone View
sys/cddl/dev/fbt/aarch64/fbt_isa.c
Show First 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | |||||
fbt_provide_module_function(linker_file_t lf, int symindx, | fbt_provide_module_function(linker_file_t lf, int symindx, | ||||
linker_symval_t *symval, void *opaque) | linker_symval_t *symval, void *opaque) | ||||
{ | { | ||||
fbt_probe_t *fbt, *retfbt; | fbt_probe_t *fbt, *retfbt; | ||||
uint32_t *target, *start; | uint32_t *target, *start; | ||||
uint32_t *instr, *limit; | uint32_t *instr, *limit; | ||||
const char *name; | const char *name; | ||||
char *modname; | char *modname; | ||||
bool found; | |||||
int offs; | int offs; | ||||
modname = opaque; | modname = opaque; | ||||
name = symval->name; | name = symval->name; | ||||
/* Check if function is excluded from instrumentation */ | /* Check if function is excluded from instrumentation */ | ||||
if (fbt_excluded(name)) | if (fbt_excluded(name)) | ||||
return (0); | return (0); | ||||
/* | /* | ||||
* Instrumenting certain exception handling functions can lead to FBT | * Instrumenting certain exception handling functions can lead to FBT | ||||
* recursion, so exclude from instrumentation. | * recursion, so exclude from instrumentation. | ||||
*/ | */ | ||||
if (strcmp(name, "handle_el1h_sync") == 0 || | if (strcmp(name, "handle_el1h_sync") == 0 || | ||||
strcmp(name, "do_el1h_sync") == 0) | strcmp(name, "do_el1h_sync") == 0) | ||||
return (1); | return (1); | ||||
instr = (uint32_t *)(symval->value); | instr = (uint32_t *)(symval->value); | ||||
limit = (uint32_t *)(symval->value + symval->size); | limit = (uint32_t *)(symval->value + symval->size); | ||||
/* Look for stp (pre-indexed) operation */ | /* Look for stp (pre-indexed) operation */ | ||||
found = false; | |||||
for (; instr < limit; instr++) { | for (; instr < limit; instr++) { | ||||
if ((*instr & LDP_STP_MASK) == STP_64) | /* Some functions start with "stp xt1, xt2, [xn, <const>]!" */ | ||||
if ((*instr & LDP_STP_MASK) == STP_64) { | |||||
/* | |||||
* Assume any other store of this type means we | |||||
* are past the function prolog. | |||||
*/ | |||||
if (((*instr >> ADDR_SHIFT) & ADDR_MASK) == 31) | |||||
found = true; | |||||
break; | break; | ||||
} | } | ||||
if (instr >= limit) | /* | ||||
* Some functions start with a "sub sp, sp, <const>" | |||||
* Sometimes the compiler will have a sub instruction that | |||||
* is not of the above type so don't stop if we see one. | |||||
*/ | |||||
if ((*instr & SUB_MASK) == SUB_INSTR && | |||||
((*instr >> SUB_RD_SHIFT) & SUB_R_MASK) == 31 && | |||||
((*instr >> SUB_RN_SHIFT) & SUB_R_MASK) == 31) { | |||||
found = true; | |||||
break; | |||||
} | |||||
} | |||||
if (!found) | |||||
return (0); | return (0); | ||||
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, 3, fbt); | name, FBT_ENTRY, 3, 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; | ||||
fbt->fbtp_savedval = *instr; | fbt->fbtp_savedval = *instr; | ||||
fbt->fbtp_patchval = FBT_PATCHVAL; | fbt->fbtp_patchval = FBT_PATCHVAL; | ||||
fbt->fbtp_rval = DTRACE_INVOP_PUSHM; | if ((*instr & SUB_MASK) == SUB_INSTR) | ||||
fbt->fbtp_rval = DTRACE_INVOP_SUB; | |||||
else | |||||
fbt->fbtp_rval = DTRACE_INVOP_STP; | |||||
fbt->fbtp_symindx = symindx; | fbt->fbtp_symindx = symindx; | ||||
fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)]; | fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)]; | ||||
fbt_probetab[FBT_ADDR2NDX(instr)] = fbt; | fbt_probetab[FBT_ADDR2NDX(instr)] = fbt; | ||||
lf->fbt_nentries++; | lf->fbt_nentries++; | ||||
retfbt = NULL; | retfbt = NULL; | ||||
▲ Show 20 Lines • Show All 49 Lines • Show Last 20 Lines |