X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/6d2010ae8f7a6078e10b361c6962983bab233e0f..813fb2f63a553c957e917ede5f119b021d6ce391:/bsd/dev/i386/fbt_x86.c?ds=sidebyside diff --git a/bsd/dev/i386/fbt_x86.c b/bsd/dev/i386/fbt_x86.c index baec24f83..54f00f290 100644 --- a/bsd/dev/i386/fbt_x86.c +++ b/bsd/dev/i386/fbt_x86.c @@ -174,8 +174,11 @@ static const char * probe_ctx_closure[] = "Debugger", "IS_64BIT_PROCESS", "OSCompareAndSwap", + "_disable_preemption", + "_enable_preemption", "absolutetime_to_microtime", "act_set_astbsd", + "ast_dtrace_on", "ast_pending", "clock_get_calendar_nanotime_nowait", "copyin", @@ -217,8 +220,6 @@ static const char * probe_ctx_closure[] = "prf", "proc_is64bit", "proc_selfname", - "proc_selfpid", - "proc_selfppid", "psignal_lock", "rtc_nanotime_load", "rtc_nanotime_read", @@ -237,16 +238,16 @@ static int _cmp(const void *a, const void *b) } static const void * bsearch( - register const void *key, + const void *key, const void *base0, size_t nmemb, - register size_t size, - register int (*compar)(const void *, const void *)) { + size_t size, + int (*compar)(const void *, const void *)) { - register const char *base = base0; - register size_t lim; - register int cmp; - register const void *p; + const char *base = base0; + size_t lim; + int cmp; + const void *p; for (lim = nmemb; lim != 0; lim >>= 1) { p = base + (lim >> 1) * size; @@ -289,7 +290,8 @@ is_module_valid(struct modctl* ctl) /* * These drivers control low level functions that when traced - * cause problems, especially in the sleep/wake paths. + * cause problems often in the sleep/wake paths as well as + * critical debug and panic paths. * If somebody really wants to drill in on one of these kexts, then * they can override blacklisting using the boot-arg above. */ @@ -313,9 +315,10 @@ is_module_valid(struct modctl* ctl) return FALSE; if (strstr(ctl->mod_modname, "AppleIntelProfile") != NULL) - return FALSE; - - + return FALSE; + + if (strstr(ctl->mod_modname, "AppleEFI") != NULL) + return FALSE; return TRUE; } @@ -469,13 +472,13 @@ is_symbol_valid(const char* name) */ if (LIT_STRNSTART(name, "kdp_") || LIT_STRNSTART(name, "kdb_") || - LIT_STRNSTART(name, "kdbg_") || - LIT_STRNSTART(name, "kdebug_") || - LIT_STRNSTART(name, "kernel_debug") || + LIT_STRNSTART(name, "debug_") || LIT_STRNEQL(name, "Debugger") || LIT_STRNEQL(name, "Call_DebuggerC") || LIT_STRNEQL(name, "lock_debugger") || LIT_STRNEQL(name, "unlock_debugger") || + LIT_STRNEQL(name, "packA") || + LIT_STRNEQL(name, "unpackA") || LIT_STRNEQL(name, "SysChoked")) { return FALSE; } @@ -493,547 +496,6 @@ is_symbol_valid(const char* name) return TRUE; } -#if defined(__i386__) -int -fbt_invop(uintptr_t addr, uintptr_t *stack, uintptr_t rval) -{ - uintptr_t stack0 = 0, stack1 = 0, stack2 = 0, stack3 = 0, stack4 = 0; - fbt_probe_t *fbt = fbt_probetab[FBT_ADDR2NDX(addr)]; - - for (; fbt != NULL; fbt = fbt->fbtp_hashnext) { - if ((uintptr_t)fbt->fbtp_patchpoint == addr) { - - if (fbt->fbtp_roffset == 0) { - uintptr_t *stacktop; - if (CPU_ON_INTR(CPU)) - stacktop = (uintptr_t *)dtrace_get_cpu_int_stack_top(); - else - stacktop = (uintptr_t *)(dtrace_get_kernel_stack(current_thread()) + kernel_stack_size); - - stack += 1; /* skip over the target's pushl'd %ebp */ - - if (stack <= stacktop) - CPU->cpu_dtrace_caller = *stack++; - if (stack <= stacktop) - stack0 = *stack++; - if (stack <= stacktop) - stack1 = *stack++; - if (stack <= stacktop) - stack2 = *stack++; - if (stack <= stacktop) - stack3 = *stack++; - if (stack <= stacktop) - stack4 = *stack++; - - /* 32-bit ABI, arguments passed on stack. */ - dtrace_probe(fbt->fbtp_id, stack0, stack1, stack2, stack3, stack4); - CPU->cpu_dtrace_caller = 0; - } else { - dtrace_probe(fbt->fbtp_id, fbt->fbtp_roffset, rval, 0, 0, 0); - CPU->cpu_dtrace_caller = 0; - } - - return (fbt->fbtp_rval); - } - } - - return (0); -} - -#define IS_USER_TRAP(regs) (regs && (((regs)->cs & 3) != 0)) -#define T_INVALID_OPCODE 6 -#define FBT_EXCEPTION_CODE T_INVALID_OPCODE -#define T_PREEMPT 255 - -kern_return_t -fbt_perfCallback( - int trapno, - x86_saved_state_t *tagged_regs, - uintptr_t *lo_spp, - __unused int unused ) -{ - kern_return_t retval = KERN_FAILURE; - x86_saved_state32_t *saved_state = saved_state32(tagged_regs); - struct x86_saved_state32_from_kernel *regs = (struct x86_saved_state32_from_kernel *)saved_state; - - if (FBT_EXCEPTION_CODE == trapno && !IS_USER_TRAP(saved_state)) { - boolean_t oldlevel, cpu_64bit; - uint32_t esp_probe, fp, *pDst, delta = 0; - uintptr_t old_sp; - int emul; - - cpu_64bit = ml_is64bit(); - oldlevel = ml_set_interrupts_enabled(FALSE); - - /* Calculate where the stack pointer was when the probe instruction "fired." */ - if (cpu_64bit) { - esp_probe = saved_state->uesp; /* Easy, x86_64 establishes this value in idt64.s */ - } else { - esp_probe = (uint32_t)&(regs[1]); /* Nasty, infer the location above the save area */ - } - - __asm__ volatile( - "Ldtrace_invop_callsite_pre_label:\n" - ".data\n" - ".private_extern _dtrace_invop_callsite_pre\n" - "_dtrace_invop_callsite_pre:\n" - " .long Ldtrace_invop_callsite_pre_label\n" - ".text\n" - ); - - emul = dtrace_invop( saved_state->eip, (uintptr_t *)esp_probe, saved_state->eax ); - - __asm__ volatile( - "Ldtrace_invop_callsite_post_label:\n" - ".data\n" - ".private_extern _dtrace_invop_callsite_post\n" - "_dtrace_invop_callsite_post:\n" - " .long Ldtrace_invop_callsite_post_label\n" - ".text\n" - ); - - switch (emul) { - case DTRACE_INVOP_NOP: - saved_state->eip += DTRACE_INVOP_NOP_SKIP; /* Skip over the patched NOP (planted by sdt.) */ - retval = KERN_SUCCESS; - break; - - case DTRACE_INVOP_MOVL_ESP_EBP: - saved_state->ebp = esp_probe; /* Emulate patched movl %esp,%ebp */ - saved_state->eip += DTRACE_INVOP_MOVL_ESP_EBP_SKIP; /* Skip over the bytes of the patched movl %esp,%ebp */ - retval = KERN_SUCCESS; - break; - - case DTRACE_INVOP_POPL_EBP: - case DTRACE_INVOP_LEAVE: -/* - * Emulate first micro-op of patched leave: movl %ebp,%esp - * fp points just below the return address slot for target's ret - * and at the slot holding the frame pointer saved by the target's prologue. - */ - fp = saved_state->ebp; -/* Emulate second micro-op of patched leave: patched popl %ebp - * savearea ebp is set for the frame of the caller to target - * The *live* %esp will be adjusted below for pop increment(s) - */ - saved_state->ebp = *(uint32_t *)fp; -/* Skip over the patched leave */ - saved_state->eip += DTRACE_INVOP_LEAVE_SKIP; -/* - * Lift the stack to account for the emulated leave - * Account for words local in this frame - * (in "case DTRACE_INVOP_POPL_EBP:" this is zero.) - */ - delta = ((uint32_t *)fp) - ((uint32_t *)esp_probe); -/* Account for popping off the ebp (just accomplished by the emulation - * above...) - */ - delta += 1; - - if (cpu_64bit) - saved_state->uesp += (delta << 2); -/* Obtain the stack pointer recorded by the trampolines */ - old_sp = *lo_spp; -/* Shift contents of stack */ - for (pDst = (uint32_t *)fp; - pDst > (((uint32_t *)old_sp)); - pDst--) - *pDst = pDst[-delta]; - -/* Track the stack lift in "saved_state". */ - saved_state = (x86_saved_state32_t *) (((uintptr_t)saved_state) + (delta << 2)); -/* Adjust the stack pointer utilized by the trampolines */ - *lo_spp = old_sp + (delta << 2); - - retval = KERN_SUCCESS; - break; - - default: - retval = KERN_FAILURE; - break; - } - saved_state->trapno = T_PREEMPT; /* Avoid call to i386_astintr()! */ - - ml_set_interrupts_enabled(oldlevel); - } - - return retval; -} - -/*ARGSUSED*/ -static void -__provide_probe_32(struct modctl *ctl, uintptr_t instrLow, uintptr_t instrHigh, char *modname, char* symbolName, machine_inst_t* symbolStart) -{ - unsigned int j; - unsigned int doenable = 0; - dtrace_id_t thisid; - - fbt_probe_t *newfbt, *retfbt, *entryfbt; - machine_inst_t *instr, *limit, theInstr, i1, i2; - int size; - - for (j = 0, instr = symbolStart, theInstr = 0; - (j < 4) && ((uintptr_t)instr >= instrLow) && (instrHigh > (uintptr_t)(instr + 2)); - j++) { - theInstr = instr[0]; - if (theInstr == FBT_PUSHL_EBP || theInstr == FBT_RET || theInstr == FBT_RET_IMM16) - break; - - if ((size = dtrace_instr_size(instr)) <= 0) - break; - - instr += size; - } - - if (theInstr != FBT_PUSHL_EBP) - return; - - i1 = instr[1]; - i2 = instr[2]; - - limit = (machine_inst_t *)instrHigh; - - if ((i1 == FBT_MOVL_ESP_EBP0_V0 && i2 == FBT_MOVL_ESP_EBP1_V0) || - (i1 == FBT_MOVL_ESP_EBP0_V1 && i2 == FBT_MOVL_ESP_EBP1_V1)) { - instr += 1; /* Advance to the movl %esp,%ebp */ - theInstr = i1; - } else { - /* - * Sometimes, the compiler will schedule an intervening instruction - * in the function prologue. Example: - * - * _mach_vm_read: - * 000006d8 pushl %ebp - * 000006d9 movl $0x00000004,%edx - * 000006de movl %esp,%ebp - * - * Try the next instruction, to see if it is a movl %esp,%ebp - */ - - instr += 1; /* Advance past the pushl %ebp */ - if ((size = dtrace_instr_size(instr)) <= 0) - return; - - instr += size; - - if ((instr + 1) >= limit) - return; - - i1 = instr[0]; - i2 = instr[1]; - - if (!(i1 == FBT_MOVL_ESP_EBP0_V0 && i2 == FBT_MOVL_ESP_EBP1_V0) && - !(i1 == FBT_MOVL_ESP_EBP0_V1 && i2 == FBT_MOVL_ESP_EBP1_V1)) - return; - - /* instr already points at the movl %esp,%ebp */ - theInstr = i1; - } - - thisid = dtrace_probe_lookup(fbt_id, modname, symbolName, FBT_ENTRY); - newfbt = kmem_zalloc(sizeof (fbt_probe_t), KM_SLEEP); - strlcpy( (char *)&(newfbt->fbtp_name), symbolName, MAX_FBTP_NAME_CHARS ); - - if (thisid != 0) { - /* - * The dtrace_probe previously existed, so we have to hook - * the newfbt entry onto the end of the existing fbt's chain. - * If we find an fbt entry that was previously patched to - * fire, (as indicated by the current patched value), then - * we want to enable this newfbt on the spot. - */ - entryfbt = dtrace_probe_arg (fbt_id, thisid); - ASSERT (entryfbt != NULL); - for(; entryfbt != NULL; entryfbt = entryfbt->fbtp_next) { - if (entryfbt->fbtp_currentval == entryfbt->fbtp_patchval) - doenable++; - - if (entryfbt->fbtp_next == NULL) { - entryfbt->fbtp_next = newfbt; - newfbt->fbtp_id = entryfbt->fbtp_id; - break; - } - } - } - else { - /* - * The dtrace_probe did not previously exist, so we - * create it and hook in the newfbt. Since the probe is - * new, we obviously do not need to enable it on the spot. - */ - newfbt->fbtp_id = dtrace_probe_create(fbt_id, modname, symbolName, FBT_ENTRY, FBT_AFRAMES_ENTRY, newfbt); - doenable = 0; - } - - - newfbt->fbtp_patchpoint = instr; - newfbt->fbtp_ctl = ctl; - newfbt->fbtp_loadcnt = ctl->mod_loadcnt; - newfbt->fbtp_rval = DTRACE_INVOP_MOVL_ESP_EBP; - newfbt->fbtp_savedval = theInstr; - newfbt->fbtp_patchval = FBT_PATCHVAL; - newfbt->fbtp_currentval = 0; - newfbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)]; - fbt_probetab[FBT_ADDR2NDX(instr)] = newfbt; - - if (doenable) - fbt_enable(NULL, newfbt->fbtp_id, newfbt); - - /* - * The fbt entry chain is in place, one entry point per symbol. - * The fbt return chain can have multiple return points per symbol. - * Here we find the end of the fbt return chain. - */ - - doenable=0; - - thisid = dtrace_probe_lookup(fbt_id, modname, symbolName, FBT_RETURN); - if (thisid != 0) { - /* The dtrace_probe previously existed, so we have to - * find the end of the existing fbt chain. If we find - * an fbt return that was previously patched to fire, - * (as indicated by the currrent patched value), then - * we want to enable any new fbts on the spot. - */ - retfbt = dtrace_probe_arg (fbt_id, thisid); - ASSERT(retfbt != NULL); - for (; retfbt != NULL; retfbt = retfbt->fbtp_next) { - if (retfbt->fbtp_currentval == retfbt->fbtp_patchval) - doenable++; - if(retfbt->fbtp_next == NULL) - break; - } - } - else { - doenable = 0; - retfbt = NULL; - } - -again: - if (instr >= limit) - return; - - /* - * If this disassembly fails, then we've likely walked off into - * a jump table or some other unsuitable area. Bail out of the - * disassembly now. - */ - if ((size = dtrace_instr_size(instr)) <= 0) - return; - - /* - * We (desperately) want to avoid erroneously instrumenting a - * jump table, especially given that our markers are pretty - * short: two bytes on x86, and just one byte on amd64. To - * determine if we're looking at a true instruction sequence - * or an inline jump table that happens to contain the same - * byte sequences, we resort to some heuristic sleeze: we - * treat this instruction as being contained within a pointer, - * and see if that pointer points to within the body of the - * function. If it does, we refuse to instrument it. - */ - for (j = 0; j < sizeof (uintptr_t); j++) { - uintptr_t check = (uintptr_t)instr - j; - uint8_t *ptr; - - if (check < (uintptr_t)symbolStart) - break; - - if (check + sizeof (uintptr_t) > (uintptr_t)limit) - continue; - - ptr = *(uint8_t **)check; - - if (ptr >= (uint8_t *)symbolStart && ptr < limit) { - instr += size; - goto again; - } - } - - /* - * OK, it's an instruction. - */ - theInstr = instr[0]; - - /* Walked onto the start of the next routine? If so, bail out of this function. */ - if (theInstr == FBT_PUSHL_EBP) - return; - - if (!(size == 1 && (theInstr == FBT_POPL_EBP || theInstr == FBT_LEAVE))) { - instr += size; - goto again; - } - - /* - * Found the popl %ebp; or leave. - */ - machine_inst_t *patch_instr = instr; - - /* - * Scan forward for a "ret", or "jmp". - */ - instr += size; - if (instr >= limit) - return; - - size = dtrace_instr_size(instr); - if (size <= 0) /* Failed instruction decode? */ - return; - - theInstr = instr[0]; - - if (!(size == FBT_RET_LEN && (theInstr == FBT_RET)) && - !(size == FBT_RET_IMM16_LEN && (theInstr == FBT_RET_IMM16)) && - !(size == FBT_JMP_SHORT_REL_LEN && (theInstr == FBT_JMP_SHORT_REL)) && - !(size == FBT_JMP_NEAR_REL_LEN && (theInstr == FBT_JMP_NEAR_REL)) && - !(size == FBT_JMP_FAR_ABS_LEN && (theInstr == FBT_JMP_FAR_ABS))) - return; - - /* - * popl %ebp; ret; or leave; ret; or leave; jmp tailCalledFun; -- We have a winner! - */ - newfbt = kmem_zalloc(sizeof (fbt_probe_t), KM_SLEEP); - strlcpy( (char *)&(newfbt->fbtp_name), symbolName, MAX_FBTP_NAME_CHARS ); - - if (retfbt == NULL) { - newfbt->fbtp_id = dtrace_probe_create(fbt_id, modname, - symbolName, FBT_RETURN, FBT_AFRAMES_RETURN, newfbt); - } else { - retfbt->fbtp_next = newfbt; - newfbt->fbtp_id = retfbt->fbtp_id; - } - - retfbt = newfbt; - newfbt->fbtp_patchpoint = patch_instr; - newfbt->fbtp_ctl = ctl; - newfbt->fbtp_loadcnt = ctl->mod_loadcnt; - - if (*patch_instr == FBT_POPL_EBP) { - newfbt->fbtp_rval = DTRACE_INVOP_POPL_EBP; - } else { - ASSERT(*patch_instr == FBT_LEAVE); - newfbt->fbtp_rval = DTRACE_INVOP_LEAVE; - } - newfbt->fbtp_roffset = - (uintptr_t)(patch_instr - (uint8_t *)symbolStart); - - newfbt->fbtp_savedval = *patch_instr; - newfbt->fbtp_patchval = FBT_PATCHVAL; - newfbt->fbtp_currentval = 0; - newfbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(patch_instr)]; - fbt_probetab[FBT_ADDR2NDX(patch_instr)] = newfbt; - - if (doenable) - fbt_enable(NULL, newfbt->fbtp_id, newfbt); - - instr += size; - goto again; -} - -static void -__kernel_syms_provide_module(void *arg, struct modctl *ctl) -{ -#pragma unused(arg) - kernel_mach_header_t *mh; - struct load_command *cmd; - kernel_segment_command_t *orig_ts = NULL, *orig_le = NULL; - struct symtab_command *orig_st = NULL; - struct nlist *sym = NULL; - char *strings; - uintptr_t instrLow, instrHigh; - char *modname; - unsigned int i; - - mh = (kernel_mach_header_t *)(ctl->mod_address); - modname = ctl->mod_modname; - - if (mh->magic != MH_MAGIC) - return; - - cmd = (struct load_command *) &mh[1]; - for (i = 0; i < mh->ncmds; i++) { - if (cmd->cmd == LC_SEGMENT_KERNEL) { - kernel_segment_command_t *orig_sg = (kernel_segment_command_t *) cmd; - - if (LIT_STRNEQL(orig_sg->segname, SEG_TEXT)) - orig_ts = orig_sg; - else if (LIT_STRNEQL(orig_sg->segname, SEG_LINKEDIT)) - orig_le = orig_sg; - else if (LIT_STRNEQL(orig_sg->segname, "")) - orig_ts = orig_sg; /* kexts have a single unnamed segment */ - } - else if (cmd->cmd == LC_SYMTAB) - orig_st = (struct symtab_command *) cmd; - - cmd = (struct load_command *) ((caddr_t) cmd + cmd->cmdsize); - } - - if ((orig_ts == NULL) || (orig_st == NULL) || (orig_le == NULL)) - return; - - sym = (struct nlist *)(orig_le->vmaddr + orig_st->symoff - orig_le->fileoff); - strings = (char *)(orig_le->vmaddr + orig_st->stroff - orig_le->fileoff); - - /* Find extent of the TEXT section */ - instrLow = (uintptr_t)orig_ts->vmaddr; - instrHigh = (uintptr_t)(orig_ts->vmaddr + orig_ts->vmsize); - - for (i = 0; i < orig_st->nsyms; i++) { - uint8_t n_type = sym[i].n_type & (N_TYPE | N_EXT); - char *name = strings + sym[i].n_un.n_strx; - - /* Check that the symbol is a global and that it has a name. */ - if (((N_SECT | N_EXT) != n_type && (N_ABS | N_EXT) != n_type)) - continue; - - if (0 == sym[i].n_un.n_strx) /* iff a null, "", name. */ - continue; - - /* Lop off omnipresent leading underscore. */ - if (*name == '_') - name += 1; - - /* - * We're only blacklisting functions in the kernel for now. - */ - if (MOD_IS_MACH_KERNEL(ctl) && !is_symbol_valid(name)) - continue; - - __provide_probe_32(ctl, instrLow, instrHigh, modname, name, (machine_inst_t*)sym[i].n_value); - } -} - -static void -__user_syms_provide_module(void *arg, struct modctl *ctl) -{ -#pragma unused(arg) - char *modname; - unsigned int i; - - modname = ctl->mod_modname; - - dtrace_module_symbols_t* module_symbols = ctl->mod_user_symbols; - if (module_symbols) { - for (i=0; idtmodsyms_count; i++) { - dtrace_symbol_t* symbol = &module_symbols->dtmodsyms_symbols[i]; - char* name = symbol->dtsym_name; - - /* Lop off omnipresent leading underscore. */ - if (*name == '_') - name += 1; - - /* - * We're only blacklisting functions in the kernel for now. - */ - if (MOD_IS_MACH_KERNEL(ctl) && !is_symbol_valid(name)) - continue; - - __provide_probe_32(ctl, (uintptr_t)symbol->dtsym_addr, (uintptr_t)(symbol->dtsym_addr + symbol->dtsym_size), modname, name, (machine_inst_t*)(uintptr_t)symbol->dtsym_addr); - } - } -} - -#elif defined(__x86_64__) int fbt_invop(uintptr_t addr, uintptr_t *state, uintptr_t rval) { @@ -1188,6 +650,14 @@ __provide_probe_64(struct modctl *ctl, uintptr_t instrLow, uintptr_t instrHigh, machine_inst_t *instr, *limit, theInstr, i1, i2, i3; int size; + /* + * Guard against null symbols + */ + if (!symbolStart || !instrLow || !instrHigh) { + kprintf("dtrace: %s has an invalid address\n", symbolName); + return; + } + for (j = 0, instr = symbolStart, theInstr = 0; (j < 4) && ((uintptr_t)instr >= instrLow) && (instrHigh > (uintptr_t)(instr + 2)); j++) { @@ -1456,7 +926,7 @@ __kernel_syms_provide_module(void *arg, struct modctl *ctl) struct load_command *cmd; kernel_segment_command_t *orig_ts = NULL, *orig_le = NULL; struct symtab_command *orig_st = NULL; - struct nlist_64 *sym = NULL; + kernel_nlist_t *sym = NULL; char *strings; uintptr_t instrLow, instrHigh; char *modname; @@ -1465,7 +935,7 @@ __kernel_syms_provide_module(void *arg, struct modctl *ctl) mh = (kernel_mach_header_t *)(ctl->mod_address); modname = ctl->mod_modname; - if (mh->magic != MH_MAGIC_64) + if (mh->magic != MH_MAGIC_KERNEL) return; cmd = (struct load_command *) &mh[1]; @@ -1489,7 +959,7 @@ __kernel_syms_provide_module(void *arg, struct modctl *ctl) if ((orig_ts == NULL) || (orig_st == NULL) || (orig_le == NULL)) return; - sym = (struct nlist_64 *)(orig_le->vmaddr + orig_st->symoff - orig_le->fileoff); + sym = (kernel_nlist_t *)(orig_le->vmaddr + orig_st->symoff - orig_le->fileoff); strings = (char *)(orig_le->vmaddr + orig_st->stroff - orig_le->fileoff); /* Find extent of the TEXT section */ @@ -1533,7 +1003,13 @@ __user_syms_provide_module(void *arg, struct modctl *ctl) dtrace_module_symbols_t* module_symbols = ctl->mod_user_symbols; if (module_symbols) { for (i=0; idtmodsyms_count; i++) { + + /* + * symbol->dtsym_addr (the symbol address) passed in from + * user space, is already slid for both kexts and kernel. + */ dtrace_symbol_t* symbol = &module_symbols->dtmodsyms_symbols[i]; + char* name = symbol->dtsym_name; /* Lop off omnipresent leading underscore. */ @@ -1543,16 +1019,13 @@ __user_syms_provide_module(void *arg, struct modctl *ctl) /* * We're only blacklisting functions in the kernel for now. */ - if (MOD_IS_MACH_KERNEL(ctl) && !is_symbol_valid(name)) - continue; + if (MOD_IS_MACH_KERNEL(ctl) && !is_symbol_valid(name)) + continue; __provide_probe_64(ctl, (uintptr_t)symbol->dtsym_addr, (uintptr_t)(symbol->dtsym_addr + symbol->dtsym_size), modname, name, (machine_inst_t*)(uintptr_t)symbol->dtsym_addr); } } } -#else -#error Unknown arch -#endif extern int dtrace_kernel_symbol_mode; @@ -1581,6 +1054,8 @@ fbt_provide_module(void *arg, struct modctl *ctl) if (MOD_HAS_USERSPACE_SYMBOLS(ctl)) { __user_syms_provide_module(arg, ctl); ctl->mod_flags |= MODCTL_FBT_PROBES_PROVIDED; + if (MOD_FBT_PROVIDE_PRIVATE_PROBES(ctl)) + ctl->mod_flags |= MODCTL_FBT_PRIVATE_PROBES_PROVIDED; return; } }