#include <kern/lock.h>
#include <kern/locks.h>
#include <kern/thread_call.h>
+#include <kern/thread.h>
#include <machine/machine_routines.h>
#include <sys/syslog.h>
#include <sys/ucred.h>
#include <mach/kmod.h>
#include <libkern/OSAtomic.h>
-#ifdef QUIET_PLEASE
- #ifndef NULL
- #define NULL ((void *)0) /* quiets many warnings */
- #endif
+#if defined(__i386__) || defined(__x86_64__)
+#include <i386/mp.h>
#endif
/*
* pid/proc
*/
-typedef struct proc SUN_PROC_T; /* Solaris proc_t is the struct. Darwin's proc_t is a pointer to it. */
-#define proc_t SUN_PROC_T /* replace all the original uses of (Solaris) proc_t */
+/* Solaris proc_t is the struct. Darwin's proc_t is a pointer to it. */
+#define proc_t struct proc /* Steer clear of the Darwin typedef for proc_t */
#define curproc ((struct proc *)current_proc()) /* Called from probe context, must blacklist */
proc_t* sprlock(pid_t pid);
/*
* Per-CPU data.
*/
-typedef struct cpu {
+typedef struct dtrace_cpu {
processorid_t cpu_id; /* CPU number */
- struct cpu *cpu_next; /* next existing CPU */
+ struct dtrace_cpu *cpu_next; /* next existing CPU */
lck_rw_t cpu_ft_lock; /* DTrace: fasttrap lock */
uintptr_t cpu_dtrace_caller; /* DTrace: caller, if any */
hrtime_t cpu_dtrace_chillmark; /* DTrace: chill mark time */
hrtime_t cpu_dtrace_chilled; /* DTrace: total chill time */
boolean_t cpu_dtrace_invop_underway; /* DTrace gaurds against invalid op re-entrancy */
-} cpu_t;
+} dtrace_cpu_t;
-extern cpu_t *cpu_list;
+extern dtrace_cpu_t *cpu_list;
/*
* The cpu_core structure consists of per-CPU state available in any context.
* the structure is sized to avoid false sharing.
*/
#define CPU_CACHE_COHERENCE_SIZE 64
-#define CPUC_SIZE (sizeof (uint16_t))
-#define CPUC_PADSIZE CPU_CACHE_COHERENCE_SIZE - CPUC_SIZE
typedef struct cpu_core {
- uint16_t cpuc_dtrace_flags; /* DTrace flags */
- uint8_t cpuc_pad[CPUC_PADSIZE]; /* padding */
uint64_t cpuc_dtrace_illval; /* DTrace illegal value */
lck_mtx_t cpuc_pid_lock; /* DTrace pid provider lock */
+ uint16_t cpuc_dtrace_flags; /* DTrace flags */
+ uint64_t cpuc_missing_tos; /* Addr. of top most stack frame if missing */
+ uint8_t cpuc_pad[CPU_CACHE_COHERENCE_SIZE - sizeof(uint64_t) - sizeof(lck_mtx_t) - sizeof(uint16_t) - sizeof(uint64_t) ]; /* padding */
} cpu_core_t;
-extern cpu_core_t *cpu_core; /* XXX TLB lockdown? */
-extern unsigned int real_ncpus;
-extern int cpu_number(void); /* XXX #include <kern/cpu_number.h>. Called from probe context, must blacklist. */
+extern cpu_core_t *cpu_core;
+
+
+extern int cpu_number(void); /* From #include <kern/cpu_number.h>. Called from probe context, must blacklist. */
#define CPU (&(cpu_list[cpu_number()])) /* Pointer to current CPU */
#define CPU_ON_INTR(cpup) ml_at_interrupt_context() /* always invoked on current cpu */
#endif
#define CPU_DTRACE_USTACK_FP 0x0400 /* pid provider hint to ustack() */
#define CPU_DTRACE_ENTRY 0x0800 /* pid provider hint to ustack() */
+#define CPU_DTRACE_BADSTACK 0x1000 /* DTrace fault: bad stack */
#define CPU_DTRACE_FAULT (CPU_DTRACE_BADADDR | CPU_DTRACE_BADALIGN | \
CPU_DTRACE_DIVZERO | CPU_DTRACE_ILLOP | \
CPU_DTRACE_NOSCRATCH | CPU_DTRACE_KPRIV | \
- CPU_DTRACE_UPRIV | CPU_DTRACE_TUPOFLOW)
+ CPU_DTRACE_UPRIV | CPU_DTRACE_TUPOFLOW | \
+ CPU_DTRACE_BADSTACK)
#define CPU_DTRACE_ERROR (CPU_DTRACE_FAULT | CPU_DTRACE_DROP)
+/*
+ * Loadable Modules
+ */
+
+/* Keep the compiler happy */
+struct dtrace_module_symbols;
+
+/* Solaris' modctl structure, greatly simplified, shadowing parts of xnu kmod structure. */
+typedef struct modctl {
+ struct modctl *mod_next;
+ struct modctl *mod_stale; // stale module chain
+ uint32_t mod_id; // the kext unique identifier
+ char mod_modname[KMOD_MAX_NAME];
+ int mod_loadcnt;
+ char mod_loaded;
+ char mod_flags; // See flags below
+ int mod_nenabled; // # of enabled DTrace probes in module
+ vm_address_t mod_address; // starting address (of Mach-o header blob)
+ vm_size_t mod_size; // total size (of blob)
+ UUID mod_uuid;
+ struct dtrace_module_symbols* mod_user_symbols;
+} modctl_t;
+
+/* Definitions for mod_flags */
+#define MODCTL_IS_MACH_KERNEL 0x01 // This module represents /mach_kernel
+#define MODCTL_HAS_KERNEL_SYMBOLS 0x02 // Kernel symbols (nlist) are available
+#define MODCTL_FBT_PROBES_PROVIDED 0x04 // fbt probes have been provided
+#define MODCTL_FBT_INVALID 0x08 // Module is invalid for fbt probes
+#define MODCTL_SDT_PROBES_PROVIDED 0x10 // sdt probes have been provided
+#define MODCTL_SDT_INVALID 0x20 // Module is invalid for sdt probes
+#define MODCTL_HAS_UUID 0x40 // Module has UUID
+
+/* Simple/singular mod_flags accessors */
+#define MOD_IS_MACH_KERNEL(mod) (mod->mod_flags & MODCTL_IS_MACH_KERNEL)
+#define MOD_HAS_KERNEL_SYMBOLS(mod) (mod->mod_flags & MODCTL_HAS_KERNEL_SYMBOLS)
+#define MOD_HAS_USERSPACE_SYMBOLS(mod) (mod->mod_user_symbols) /* No point in duplicating state in the flags bits */
+#define MOD_FBT_PROBES_PROVIDED(mod) (mod->mod_flags & MODCTL_FBT_PROBES_PROVIDED)
+#define MOD_FBT_INVALID(mod) (mod->mod_flags & MODCTL_FBT_INVALID)
+#define MOD_SDT_PROBES_PROVIDED(mod) (mod->mod_flags & MODCTL_SDT_PROBES_PROVIDED)
+#define MOD_SDT_INVALID(mod) (mod->mod_flags & MODCTL_SDT_INVALID)
+#define MOD_HAS_UUID(mod) (mod->mod_flags & MODCTL_HAS_UUID)
+
+/* Compound accessors */
+#define MOD_FBT_DONE(mod) (MOD_FBT_PROBES_PROVIDED(mod) || MOD_FBT_INVALID(mod))
+#define MOD_SDT_DONE(mod) (MOD_SDT_PROBES_PROVIDED(mod) || MOD_SDT_INVALID(mod))
+#define MOD_SYMBOLS_DONE(mod) (MOD_FBT_DONE(mod) && MOD_SDT_DONE(mod))
+
+extern modctl_t *dtrace_modctl_list;
+
/*
* cred_t
*/
} cyc_handler_t;
typedef struct cyc_omni_handler {
- void (*cyo_online)(void *, cpu_t *, cyc_handler_t *, cyc_time_t *);
- void (*cyo_offline)(void *, cpu_t *, void *);
+ void (*cyo_online)(void *, dtrace_cpu_t *, cyc_handler_t *, cyc_time_t *);
+ void (*cyo_offline)(void *, dtrace_cpu_t *, void *);
void *cyo_arg;
} cyc_omni_handler_t;
int ddi_getprop(dev_t dev, dev_info_t *dip, int flags, const char *name, int defvalue);
extern int ddi_prop_free(void *);
-extern int ddi_prop_lookup_int_array(dev_t, dev_info_t *, uint_t, char *, int **, uint_t *);
+extern int ddi_prop_lookup_int_array(dev_t, dev_info_t *, uint_t, const char *, int **, uint_t *);
extern int ddi_driver_major(dev_info_t *);
extern major_t getemajor(dev_t);
extern minor_t getminor(dev_t);
-extern int _dtrace_dev;
extern dev_t makedevice(major_t, minor_t);
/*
extern void dt_kmem_free_aligned(void*, size_t);
extern kmem_cache_t *
-kmem_cache_create(char *, size_t, size_t, int (*)(void *, void *, int),
+kmem_cache_create(const char *, size_t, size_t, int (*)(void *, void *, int),
void (*)(void *, void *), void (*)(void *), void *, vmem_t *, int);
extern void *kmem_cache_alloc(kmem_cache_t *, int);
extern void kmem_cache_free(kmem_cache_t *, void *);
typedef struct _kthread kthread_t; /* For dtrace_vtime_switch(), dtrace_panicked and dtrace_errthread */
-/*
- * Loadable Modules
- */
-
-decl_simple_lock_data(extern,kmod_lock)
-
-/* Want to use Darwin's kmod_info in place of the Solaris modctl.
- Can't typedef since the (many) usages in the code are "struct modctl *" */
-extern kmod_info_t *kmod;
-#define modctl kmod_info
-
-#define mod_modname name
-#define mod_loadcnt id
-#define mod_next next
-#define mod_loaded info_version /* XXX Is always > 0, hence TRUE */
-#define modules kmod
-
/*
* proc
*/
static inline void atomic_add_32( uint32_t *theValue, int32_t theAmount )
{
- (void)OSAddAtomic( theAmount, (SInt32 *)theValue );
+ (void)OSAddAtomic( theAmount, theValue );
}
+#if defined(__i386__) || defined(__x86_64__)
+static inline void atomic_add_64( uint64_t *theValue, int64_t theAmount )
+{
+ (void)OSAddAtomic64( theAmount, (SInt64 *)theValue );
+}
+#endif
+
/*
* Miscellaneous
*/
extern struct regs *find_user_regs( thread_t thread);
extern vm_offset_t dtrace_get_cpu_int_stack_top(void);
extern vm_offset_t max_valid_stack_address(void); /* kern/thread.h */
-extern ppnum_t pmap_find_phys(pmap_t pmap, addr64_t va); /* machine/pmap.h */
extern volatile int panicwait; /* kern/debug.c */
#define panic_quiesce (panicwait)
extern int vuprintf(const char *, va_list);
-extern boolean_t dtxnu_is_RAM_page(ppnum_t);
-
extern hrtime_t dtrace_abs_to_nano(uint64_t);
-__private_extern__ char * strstr(const char *, const char *);
+__private_extern__ const char * strstr(const char *, const char *);
#undef proc_t
+/*
+ * Safe counted string compare against a literal string. The sizeof() intentionally
+ * counts the trailing NUL, and so ensures that all the characters in the literal
+ * can participate in the comparison.
+ */
+#define LIT_STRNEQL(s1, lit_s2) (0 == strncmp( (s1), (lit_s2), sizeof((lit_s2)) ))
+
+/*
+ * Safe counted string compare of a literal against the beginning of a string. Here
+ * the sizeof() is reduced by 1 so that the trailing null of the literal does not
+ * participate in the comparison.
+ */
+#define LIT_STRNSTART(s1, lit_s2) (0 == strncmp( (s1), (lit_s2), sizeof((lit_s2)) - 1 ))
+
+#define KERNELBASE VM_MIN_KERNEL_ADDRESS
#endif /* KERNEL_BUILD */
#endif /* _DTRACE_GLUE_H */