Search code examples
ckernelc-preprocessorapple-m1kernel-extension

How do these pre-processor defined kernel functions work?


I am trying to execute some kernel functions on the Apple M1, and have come across this code which appears to use C macros to define some kernel functions at compile time. These are kernel functions that exist in Apple's kern/kpc library, but the header files for this library are not included anywhere, and I believe the API may be private.

I was wondering if anyone could explain how this works, how are the function definitions (ie, the code that would usually be in the function body) revealed to the program? I am unfamiliar with the ##proc notation.

#define KPERF_LIST                               \
    /*  ret, name, params */                     \
    F(int, kpc_get_counting, void)               \
    F(int, kpc_force_all_ctrs_set, int)          \
    F(int, kpc_set_counting, uint32_t)           \
    F(int, kpc_set_thread_counting, uint32_t)    \
    F(int, kpc_set_config, uint32_t, void *)     \
    F(int, kpc_get_config, uint32_t, void *)     \
    F(int, kpc_set_period, uint32_t, void *)     \
    F(int, kpc_get_period, uint32_t, void *)     \
    F(uint32_t, kpc_get_counter_count, uint32_t) \
    F(uint32_t, kpc_get_config_count, uint32_t)  \
    F(int, kperf_sample_get, int *)              \
    F(int, kpc_get_thread_counters, int, unsigned int, void *)

#define F(ret, name, ...)                \
    typedef ret name##proc(__VA_ARGS__); \
    static name##proc *name;
KPERF_LIST
#undef F

Solution

  • I have contacted the author of the original code to figure this out.

    The functions defined by the macro are linked to the kernel library functions later in the code using dlsym(). So, the functions are not actually defined in this code; rather, functions of the same/similar name are declared and then linked to the kernel library dynamically.