Skip to content

Instantly share code, notes, and snippets.

@darkfall
Last active January 24, 2021 10:03

Revisions

  1. darkfall renamed this gist Jan 29, 2015. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion gistfile1.txt → gistfile1.c
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,3 @@

    #include <objc/objc-runtime.h>

    // from objc_runtime_new.h with some simplifications
  2. darkfall revised this gist Jan 29, 2015. 1 changed file with 11 additions and 17 deletions.
    28 changes: 11 additions & 17 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,8 @@

    #include <objc/objc-runtime.h>

    // from objc_runtime_new.h with some simplifications

    #if __LP64__
    typedef uint32_t mask_t;
    #define FAST_DATA_MASK 0x00007ffffffffff8UL
    @@ -9,24 +11,13 @@ typedef uint64_t mask_t;
    #define FAST_DATA_MASK 0xfffffffcUL
    #endif

    struct cache_t {
    void* buckets;

    mask_t mask;
    mask_t occupied;
    } ;

    struct class_rw_t {
    uint32_t flags;
    uint32_t version;

    void* ro;
    void* methods;
    void* properties;
    void* protocols;

    // flag, version, ro, methods, properties, protocols
    uint8_t __placeholder[sizeof(uint32_t) * 2 + sizeof(void*) * 4];

    Class firstSubClass;
    Class nextSiblingClass;

    const char* demangleName;
    };

    @@ -41,7 +32,10 @@ struct class_data_bits_t {
    struct objc_class_t {
    Class isa;
    Class superclass;
    cache_t cache;

    // buckets, masks = cache_t
    uint8_t __placeholder[sizeof(void*) + sizeof(mask_t) * 2];

    class_data_bits_t dataBits;

    Class getFirstSubClass() {
    @@ -77,4 +71,4 @@ int main(int argc, const char * argv[]) {

    print_subclass_tree(cls, 0);
    return 0;
    }
    }
  3. darkfall created this gist Jan 29, 2015.
    80 changes: 80 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,80 @@

    #include <objc/objc-runtime.h>

    #if __LP64__
    typedef uint32_t mask_t;
    #define FAST_DATA_MASK 0x00007ffffffffff8UL
    #else
    typedef uint64_t mask_t;
    #define FAST_DATA_MASK 0xfffffffcUL
    #endif

    struct cache_t {
    void* buckets;

    mask_t mask;
    mask_t occupied;
    } ;

    struct class_rw_t {
    uint32_t flags;
    uint32_t version;

    void* ro;
    void* methods;
    void* properties;
    void* protocols;

    Class firstSubClass;
    Class nextSiblingClass;
    const char* demangleName;
    };

    struct class_data_bits_t {
    uintptr_t bits;

    class_rw_t* data() {
    return (class_rw_t*)(bits & FAST_DATA_MASK);
    }
    };

    struct objc_class_t {
    Class isa;
    Class superclass;
    cache_t cache;
    class_data_bits_t dataBits;

    Class getFirstSubClass() {
    return dataBits.data()->firstSubClass;
    }

    Class getNextSiblingClass() {
    return dataBits.data()->nextSiblingClass;
    }
    };

    void print_subclass_tree(Class cls, int level)
    {
    objc_class_t* rt_cls = (__bridge objc_class_t*)cls;

    Class subClass = rt_cls->getFirstSubClass();
    while(subClass)
    {
    for(int i=0; i<level; ++i)
    printf(" ");

    printf("%s\n", class_getName(subClass));

    print_subclass_tree(subClass, level + 1);

    subClass = ((__bridge objc_class_t*)subClass)->getNextSiblingClass();
    }
    }

    int main(int argc, const char * argv[]) {

    Class cls = objc_getClass("NSObject");

    print_subclass_tree(cls, 0);
    return 0;
    }