-/*
- * Critical routines that must not be probed. PR_5221096, PR_5379018.
- * The blacklist must be kept in alphabetic order for purposes of bsearch().
- */
-
-static const char * critical_blacklist[] =
-{
- "bcopy_phys",
- "console_cpu_alloc",
- "console_cpu_free",
- "cpu_IA32e_disable",
- "cpu_IA32e_enable",
- "cpu_NMI_interrupt",
- "cpu_control",
- "cpu_data_alloc",
- "cpu_desc_init",
- "cpu_desc_init64",
- "cpu_desc_load",
- "cpu_desc_load64",
- "cpu_exit_wait",
- "cpu_info",
- "cpu_info_count",
- "cpu_init",
- "cpu_interrupt",
- "cpu_machine_init",
- "cpu_mode_init",
- "cpu_processor_alloc",
- "cpu_processor_free",
- "cpu_signal_handler",
- "cpu_sleep",
- "cpu_start",
- "cpu_subtype",
- "cpu_thread_alloc",
- "cpu_thread_halt",
- "cpu_thread_init",
- "cpu_threadtype",
- "cpu_to_processor",
- "cpu_topology_sort",
- "cpu_topology_start_cpu",
- "cpu_type",
- "cpuid_cpu_display",
- "cpuid_extfeatures",
- "handle_pending_TLB_flushes",
- "hw_compare_and_store",
- "machine_idle_cstate",
- "mca_cpu_alloc",
- "mca_cpu_init",
- "ml_nofault_copy",
- "pmap_cpu_alloc",
- "pmap_cpu_free",
- "pmap_cpu_high_map_vaddr",
- "pmap_cpu_high_shared_remap",
- "pmap_cpu_init",
- "register_cpu_setup_func",
- "unregister_cpu_setup_func",
- "vstart"
-};
-#define CRITICAL_BLACKLIST_COUNT (sizeof(critical_blacklist)/sizeof(critical_blacklist[0]))
-
-/*
- * The transitive closure of entry points that can be reached from probe context.
- * (Apart from routines whose names begin with dtrace_).
- */
-static const char * probe_ctx_closure[] =
-{
- "Debugger",
- "IS_64BIT_PROCESS",
- "OSCompareAndSwap",
- "absolutetime_to_microtime",
- "act_set_astbsd",
- "ast_pending",
- "clock_get_calendar_nanotime_nowait",
- "copyin",
- "copyin_user",
- "copyinstr",
- "copyout",
- "copyoutstr",
- "cpu_number",
- "current_proc",
- "current_processor",
- "current_task",
- "current_thread",
- "debug_enter",
- "find_user_regs",
- "flush_tlb64",
- "get_bsdtask_info",
- "get_bsdthread_info",
- "hw_atomic_and",
- "kauth_cred_get",
- "kauth_getgid",
- "kauth_getuid",
- "kernel_preempt_check",
- "mach_absolute_time",
- "max_valid_stack_address",
- "ml_at_interrupt_context",
- "ml_phys_write_byte_64",
- "ml_phys_write_half_64",
- "ml_phys_write_word_64",
- "ml_set_interrupts_enabled",
- "panic",
- "pmap64_pde",
- "pmap64_pdpt",
- "pmap_find_phys",
- "pmap_get_mapwindow",
- "pmap_pde",
- "pmap_pte",
- "pmap_put_mapwindow",
- "pmap_valid_page",
- "prf",
- "proc_is64bit",
- "proc_selfname",
- "psignal_lock",
- "rtc_nanotime_load",
- "rtc_nanotime_read",
- "sdt_getargdesc",
- "strlcpy",
- "sync_iss_to_iks_unconditionally",
- "systrace_stub",
- "timer_grab"
-};
-#define PROBE_CTX_CLOSURE_COUNT (sizeof(probe_ctx_closure)/sizeof(probe_ctx_closure[0]))
-
-
-static int _cmp(const void *a, const void *b)
-{
- return strncmp((const char *)a, *(const char **)b, strlen((const char *)a) + 1);
-}
-
-static const void * bsearch(
- register const void *key,
- const void *base0,
- size_t nmemb,
- register size_t size,
- register int (*compar)(const void *, const void *)) {
-
- register const char *base = base0;
- register size_t lim;
- register int cmp;
- register const void *p;
-
- for (lim = nmemb; lim != 0; lim >>= 1) {
- p = base + (lim >> 1) * size;
- cmp = (*compar)(key, p);
- if (cmp == 0)
- return p;
- if (cmp > 0) { /* key > p: move right */
- base = (const char *)p + size;
- lim--;
- } /* else move left */
- }
- return (NULL);
-}
-
-/*
- * Module validation
- */
-static int
-is_module_valid(struct modctl* ctl)
-{
- ASSERT(!MOD_FBT_PROBES_PROVIDED(ctl));
- ASSERT(!MOD_FBT_INVALID(ctl));
-
- if (0 == ctl->mod_address || 0 == ctl->mod_size) {
- return FALSE;
- }
-
- if (0 == ctl->mod_loaded) {
- return FALSE;
- }
-
- if (strstr(ctl->mod_modname, "CHUD") != NULL)
- return FALSE;
-
- /*
- * If the user sets this, trust they know what they are doing.
- */
- if (gIgnoreFBTBlacklist) /* per boot-arg set in fbt_init() */
- return TRUE;
-
- /*
- * These drivers control low level functions that when traced
- * 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.
- */
-
- if (strstr(ctl->mod_modname, "AppleACPIEC") != NULL)
- return FALSE;
-
- if (strstr(ctl->mod_modname, "AppleACPIPlatform") != NULL)
- return FALSE;
-
- if (strstr(ctl->mod_modname, "AppleRTC") != NULL)
- return FALSE;
-
- if (strstr(ctl->mod_modname, "IOACPIFamily") != NULL)
- return FALSE;
-
- if (strstr(ctl->mod_modname, "AppleIntelCPUPowerManagement") != NULL)
- return FALSE;
-
- if (strstr(ctl->mod_modname, "AppleProfile") != NULL)
- return FALSE;
-
- if (strstr(ctl->mod_modname, "AppleIntelProfile") != NULL)
- return FALSE;
-
- if (strstr(ctl->mod_modname, "AppleEFI") != NULL)
- return FALSE;
-
- return TRUE;
-}
-
-/*
- * FBT probe name validation
- */
-static int
-is_symbol_valid(const char* name)
-{
- /*
- * If the user set this, trust they know what they are doing.
- */
- if (gIgnoreFBTBlacklist)
- return TRUE;
-
- if (LIT_STRNSTART(name, "dtrace_") && !LIT_STRNSTART(name, "dtrace_safe_")) {
- /*
- * Anything beginning with "dtrace_" may be called
- * from probe context unless it explitly indicates
- * that it won't be called from probe context by
- * using the prefix "dtrace_safe_".
- */
- return FALSE;
- }
-
- if (LIT_STRNSTART(name, "fasttrap_") ||
- LIT_STRNSTART(name, "fuword") ||
- LIT_STRNSTART(name, "suword") ||
- LIT_STRNEQL(name, "sprlock") ||
- LIT_STRNEQL(name, "sprunlock") ||
- LIT_STRNEQL(name, "uread") ||
- LIT_STRNEQL(name, "uwrite")) {
- return FALSE; /* Fasttrap inner-workings. */
- }
-
- if (LIT_STRNSTART(name, "dsmos_"))
- return FALSE; /* Don't Steal Mac OS X! */
-
- if (LIT_STRNSTART(name, "_dtrace"))
- return FALSE; /* Shims in dtrace.c */
-
- if (LIT_STRNSTART(name, "chud"))
- return FALSE; /* Professional courtesy. */
-
- if (LIT_STRNSTART(name, "hibernate_"))
- return FALSE; /* Let sleeping dogs lie. */
-
- if (LIT_STRNEQL(name, "_ZNK6OSData14getBytesNoCopyEv"))
- return FALSE; /* Data::getBytesNoCopy, IOHibernateSystemWake path */
-
- if (LIT_STRNEQL(name, "_ZN9IOService14newTemperatureElPS_") || /* IOService::newTemperature */
- LIT_STRNEQL(name, "_ZN9IOService26temperatureCriticalForZoneEPS_")) { /* IOService::temperatureCriticalForZone */
- return FALSE; /* Per the fire code */
- }
-
- /*
- * Place no probes (illegal instructions) in the exception handling path!
- */
- if (LIT_STRNEQL(name, "t_invop") ||
- LIT_STRNEQL(name, "enter_lohandler") ||
- LIT_STRNEQL(name, "lo_alltraps") ||
- LIT_STRNEQL(name, "kernel_trap") ||
- LIT_STRNEQL(name, "interrupt") ||
- LIT_STRNEQL(name, "i386_astintr")) {
- return FALSE;
- }
-
- if (LIT_STRNEQL(name, "current_thread") ||
- LIT_STRNEQL(name, "ast_pending") ||
- LIT_STRNEQL(name, "fbt_perfCallback") ||
- LIT_STRNEQL(name, "machine_thread_get_kern_state") ||
- LIT_STRNEQL(name, "get_threadtask") ||
- LIT_STRNEQL(name, "ml_set_interrupts_enabled") ||
- LIT_STRNEQL(name, "dtrace_invop") ||
- LIT_STRNEQL(name, "fbt_invop") ||
- LIT_STRNEQL(name, "sdt_invop") ||
- LIT_STRNEQL(name, "max_valid_stack_address")) {
- return FALSE;
- }
-
- /*
- * Voodoo.
- */
- if (LIT_STRNSTART(name, "machine_stack_") ||
- LIT_STRNSTART(name, "mapping_") ||
- LIT_STRNEQL(name, "tmrCvt") ||
-
- LIT_STRNSTART(name, "tsc_") ||
-
- LIT_STRNSTART(name, "pmCPU") ||
- LIT_STRNEQL(name, "pmKextRegister") ||
- LIT_STRNEQL(name, "pmMarkAllCPUsOff") ||
- LIT_STRNEQL(name, "pmSafeMode") ||
- LIT_STRNEQL(name, "pmTimerSave") ||
- LIT_STRNEQL(name, "pmTimerRestore") ||
- LIT_STRNEQL(name, "pmUnRegister") ||
- LIT_STRNSTART(name, "pms") ||
- LIT_STRNEQL(name, "power_management_init") ||
- LIT_STRNSTART(name, "usimple_") ||
- LIT_STRNSTART(name, "lck_spin_lock") ||
- LIT_STRNSTART(name, "lck_spin_unlock") ||
-
- LIT_STRNSTART(name, "rtc_") ||
- LIT_STRNSTART(name, "_rtc_") ||
- LIT_STRNSTART(name, "rtclock_") ||
- LIT_STRNSTART(name, "clock_") ||
- LIT_STRNSTART(name, "absolutetime_to_") ||
- LIT_STRNEQL(name, "setPop") ||
- LIT_STRNEQL(name, "nanoseconds_to_absolutetime") ||
- LIT_STRNEQL(name, "nanotime_to_absolutetime") ||
-
- LIT_STRNSTART(name, "etimer_") ||
-
- LIT_STRNSTART(name, "commpage_") ||
- LIT_STRNSTART(name, "pmap_") ||
- LIT_STRNSTART(name, "ml_") ||
- LIT_STRNSTART(name, "PE_") ||
- LIT_STRNEQL(name, "kprintf") ||
- LIT_STRNSTART(name, "lapic_") ||
- LIT_STRNSTART(name, "act_machine") ||
- LIT_STRNSTART(name, "acpi_") ||
- LIT_STRNSTART(name, "pal_")){
- return FALSE;
- }
-
- /*
- * Avoid machine_ routines. PR_5346750.
- */
- if (LIT_STRNSTART(name, "machine_"))
- return FALSE;
-
- if (LIT_STRNEQL(name, "handle_pending_TLB_flushes"))
- return FALSE;
-
- /*
- * Place no probes on critical routines. PR_5221096
- */
- if (bsearch( name, critical_blacklist, CRITICAL_BLACKLIST_COUNT, sizeof(name), _cmp ) != NULL)
- return FALSE;
-
- /*
- * Place no probes that could be hit in probe context.
- */
- if (bsearch( name, probe_ctx_closure, PROBE_CTX_CLOSURE_COUNT, sizeof(name), _cmp ) != NULL) {
- return FALSE;
- }
-
- /*
- * Place no probes that could be hit on the way to the debugger.
- */
- 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;
- }
-
-
- /*
- * Place no probes that could be hit on the way to a panic.
- */
- if (NULL != strstr(name, "panic_") ||
- LIT_STRNEQL(name, "panic") ||
- LIT_STRNEQL(name, "preemption_underflow_panic")) {
- return FALSE;
- }
-
- return TRUE;
-}
-