isa_t
union isa_t {
uintptr_t bits;
private:
Class cls;
public:
struct {
ISA_BITFIELD;
};
}
objc_object
struct objc_object {
isa_t isa;
}
objc_class
struct objc_class : objc_object {
Class superclass;
cache_t cache;
class_data_bits_t bits;
class_rw_t *data() const {
return bits.data();
}
}
swift_class_t
struct swift_class_t : objc_class {
uint32_t flags;
uint32_t instanceAddressOffset;
uint32_t instanceSize;
uint16_t instanceAlignMask;
uint16_t reserved;
uint32_t classSize;
uint32_t classAddressOffset;
void *description;
void *baseAddress() {
return (void *)((uint8_t *)this - classAddressOffset);
}
};
class_data_bits_t
struct class_data_bits_t {
friend objc_class;
uintptr_t bits;
public:
class_rw_t* data() const {
return (class_rw_t *)(bits & FAST_DATA_MASK);
}
const class_ro_t *safe_ro() const {
class_rw_t *maybe_rw = data();
if (maybe_rw->flags & RW_REALIZED) {
return maybe_rw->ro();
} else {
return (class_ro_t *)maybe_rw;
}
}
};
class_rw_t
struct class_rw_t {
uint32_t flags;
uint16_t witness;
#if SUPPORT_INDEXED_ISA
uint16_t index;
#endif
explicit_atomic<uintptr_t> ro_or_rw_ext;
Class firstSubclass;
Class nextSiblingClass;
private:
using ro_or_rw_ext_t = objc::PointerUnion<const class_ro_t, class_rw_ext_t, PTRAUTH_STR("class_ro_t"), PTRAUTH_STR("class_rw_ext_t")>;
const ro_or_rw_ext_t get_ro_or_rwe() const {
return ro_or_rw_ext_t{ro_or_rw_ext};
}
class_rw_ext_t *extAlloc(const class_ro_t *ro, bool deep = false);
public:
class_rw_ext_t *ext() const {
return get_ro_or_rwe().dyn_cast<class_rw_ext_t *>(&ro_or_rw_ext);
}
const class_ro_t *ro() const {
auto v = get_ro_or_rwe();
if (slowpath(v.is<class_rw_ext_t *>())) {
return v.get<class_rw_ext_t *>(&ro_or_rw_ext)->ro;
}
return v.get<const class_ro_t *>(&ro_or_rw_ext);
}
const method_array_t methods() const {
auto v = get_ro_or_rwe();
if (v.is<class_rw_ext_t *>()) {
return v.get<class_rw_ext_t *>(&ro_or_rw_ext)->methods;
} else {
return method_array_t{v.get<const class_ro_t *>(&ro_or_rw_ext)->baseMethods};
}
}
const property_array_t properties() const {
auto v = get_ro_or_rwe();
if (v.is<class_rw_ext_t *>()) {
return v.get<class_rw_ext_t *>(&ro_or_rw_ext)->properties;
} else {
return property_array_t{v.get<const class_ro_t *>(&ro_or_rw_ext)->baseProperties};
}
}
const protocol_array_t protocols() const {
auto v = get_ro_or_rwe();
if (v.is<class_rw_ext_t *>()) {
return v.get<class_rw_ext_t *>(&ro_or_rw_ext)->protocols;
} else {
return protocol_array_t{v.get<const class_ro_t *>(&ro_or_rw_ext)->baseProtocols};
}
}
}
class_ro_t
struct class_ro_t {
uint32_t flags;
uint32_t instanceStart;
uint32_t instanceSize;
uint32_t reserved;
union {
const uint8_t * ivarLayout;
Class nonMetaclass;
};
explicit_atomic<const char *> name;
WrappedPtr<method_list_t, method_list_t::Ptrauth> baseMethods;
protocol_list_t * baseProtocols;
const ivar_list_t * ivars;
const uint8_t * weakIvarLayout;
property_list_t *baseProperties;
_objc_swiftMetadataInitializer __ptrauth_objc_method_list_imp _swiftMetadataInitializer_NEVER_USE[0];
}
class_rw_ext_t
struct class_rw_ext_t {
DECLARE_AUTHED_PTR_TEMPLATE(class_ro_t)
class_ro_t_authed_ptr<const class_ro_t> ro;
method_array_t methods;
property_array_t properties;
protocol_array_t protocols;
char *demangledName;
uint32_t version;
};
method_array_t、property_array_t、protocol_array_t
class method_array_t :
public list_array_tt<method_t, method_list_t, method_list_t_authed_ptr>
{
typedef list_array_tt<method_t, method_list_t, method_list_t_authed_ptr> Super;
public:
method_array_t() : Super() { }
method_array_t(method_list_t *l) : Super(l) { }
const method_list_t_authed_ptr<method_list_t> *beginCategoryMethodLists() const {
return beginLists();
}
const method_list_t_authed_ptr<method_list_t> *endCategoryMethodLists(Class cls) const;
};
class property_array_t :
public list_array_tt<property_t, property_list_t, RawPtr>;
class protocol_array_t :
public list_array_tt<protocol_ref_t, protocol_list_t, RawPtr>
method_list_t、property_list_t、protocol_list_t、ivar_list_t
struct method_list_t : entsize_list_tt<method_t, method_list_t, 0xffff0003, method_t::pointer_modifier> {
bool isUniqued() const;
bool isFixedUp() const;
void setFixedUp();
uint32_t indexOfMethod(const method_t *meth) const {
uint32_t i =
(uint32_t)(((uintptr_t)meth - (uintptr_t)this) / entsize());
ASSERT(i < count);
return i;
}
bool isSmallList() const {
return flags() & method_t::smallMethodListFlag;
}
bool isExpectedSize() const {
if (isSmallList())
return entsize() == method_t::smallSize;
else
return entsize() == method_t::bigSize;
}
};
struct property_list_t : entsize_list_tt<property_t, property_list_t, 0> {
};
struct protocol_list_t {
uintptr_t count;
protocol_ref_t list[0];
}
struct ivar_list_t : entsize_list_tt<ivar_t, ivar_list_t, 0> {
bool containsIvar(Ivar ivar) const {
return (ivar >= (Ivar)&*begin() && ivar < (Ivar)&*end());
}
};
method_t
struct method_t {
static const uint32_t smallMethodListFlag = 0x80000000;
struct big {
SEL name;
const char *types;
MethodListIMP imp;
};
private:
bool isSmall() const {
return ((uintptr_t)this & 1) == 1;
}
struct small {
RelativePointer<const void *> name;
RelativePointer<const char *> types;
RelativePointer<IMP, false> imp;
bool inSharedCache() const {
return (CONFIG_SHARED_CACHE_RELATIVE_DIRECT_SELECTORS &&
objc::inSharedCache((uintptr_t)this));
}
};
small &small() const {
ASSERT(isSmall());
return *(struct small *)((uintptr_t)this & ~(uintptr_t)1);
}
public:
static uintptr_t sharedCacheRelativeMethodBase() {
return (uintptr_t)@selector(🤯);
}
struct SortBySELAddress :
public std::binary_function<const struct method_t::big&,
const struct method_t::big&, bool>
{
bool operator() (const struct method_t::big& lhs,
const struct method_t::big& rhs)
{ return lhs.name < rhs.name; }
};
method_t &operator=(const method_t &other) {
ASSERT(!isSmall());
big().imp = other.imp(false);
big().name = other.name();
big().types = other.types();
return *this;
}
};
property_t
struct property_t {
const char *name;
const char *attributes;
};
protocol_t
struct protocol_t : objc_object {
const char *mangledName;
struct protocol_list_t *protocols;
method_list_t *instanceMethods;
method_list_t *classMethods;
method_list_t *optionalInstanceMethods;
method_list_t *optionalClassMethods;
property_list_t *instanceProperties;
uint32_t size;
uint32_t flags;
const char **_extendedMethodTypes;
const char *_demangledName;
property_list_t *_classProperties;
};
ivar_t
struct ivar_t {
int32_t *offset;
const char *name;
const char *type;
uint32_t alignment_raw;
uint32_t size;
uint32_t alignment() const {
if (alignment_raw == ~(uint32_t)0) return 1U << WORD_SHIFT;
return 1 << alignment_raw;
}
};
category_t
struct category_t {
const char *name;
classref_t cls;
WrappedPtr<method_list_t, method_list_t::Ptrauth> instanceMethods;
WrappedPtr<method_list_t, method_list_t::Ptrauth> classMethods;
struct protocol_list_t *protocols;
struct property_list_t *instanceProperties;
struct property_list_t *_classProperties;
}
SyncCache
typedef struct alignas(CacheLineSize) SyncData {
struct SyncData* nextData;
DisguisedPtr<objc_object> object;
int32_t threadCount;
recursive_mutex_t mutex;
} SyncData;
typedef struct {
SyncData *data;
unsigned int lockCount;
} SyncCacheItem;
typedef struct SyncCache {
unsigned int allocated;
unsigned int used;
SyncCacheItem list[0];
} SyncCache;
typedefs
struct Block_callbacks_RR {
size_t size;
void (*retain)(const void *);
void (*release)(const void *);
void (*destructInstance)(const void *);
};
typedef struct Block_callbacks_RR Block_callbacks_RR;
typedef struct objc_class *Class;
typedef struct objc_object *id;
typedef struct objc_selector *SEL;
typedef struct objc_method *Method;
typedef struct objc_ivar *Ivar;
typedef struct objc_category *Category;
typedef struct objc_property *objc_property_t;
typedef struct objc_object Protocol;
typedef struct objc_imp_cache_entry {
SEL _Nonnull sel;
IMP _Nonnull imp;
} objc_imp_cache_entry;
typedef struct classref * classref_t;
macho
struct mach_header_64 {
uint32_t magic;
cpu_type_t cputype;
cpu_subtype_t cpusubtype;
uint32_t filetype;
uint32_t ncmds;
uint32_t sizeofcmds;
uint32_t flags;
uint32_t reserved;
};
struct segment_command_64 {
uint32_t cmd;
uint32_t cmdsize;
char segname[16];
uint64_t vmaddr;
uint64_t vmsize;
uint64_t fileoff;
uint64_t filesize;
vm_prot_t maxprot;
vm_prot_t initprot;
uint32_t nsects;
uint32_t flags;
};
struct section_64 {
char sectname[16];
char segname[16];
uint64_t addr;
uint64_t size;
uint32_t offset;
uint32_t align;
uint32_t reloff;
uint32_t nreloc;
uint32_t flags;
uint32_t reserved1;
uint32_t reserved2;
uint32_t reserved3;
};
typedef struct mach_header_64 headerType;
typedef struct segment_command_64 segmentType;
typedef struct section_64 sectionType;
有趣:__BRIDGEOS_
由__APPLE_BLEACH_SDK__
控制是否展示给我们
# if !defined(OBJC_AVAILABLE)
# define OBJC_AVAILABLE(x, i, t, w, b) \
__OSX_AVAILABLE(x) __IOS_AVAILABLE(i) __TVOS_AVAILABLE(t) \
__WATCHOS_AVAILABLE(w)
# endif
#ifndef __APPLE_BLEACH_SDK__
# if !defined(OBJC_AVAILABLE)
# define OBJC_AVAILABLE(x, i, t, w, b) \
__OSX_AVAILABLE(x) __IOS_AVAILABLE(i) __TVOS_AVAILABLE(t) \
__WATCHOS_AVAILABLE(w) __BRIDGEOS_AVAILABLE(b)
# endif
#else
# if !defined(OBJC_AVAILABLE)
# define OBJC_AVAILABLE(x, i, t, w, b) \
__OSX_AVAILABLE(x) __IOS_AVAILABLE(i) __TVOS_AVAILABLE(t) \
__WATCHOS_AVAILABLE(w)
# endif
#endif
关于__OBJC2__
在哪定义的
__OBJC2__ 是由编译器定义的
可以通过以下方式验证
创建一个空的.m文件 empty.m,然后运行下面的编译命令
cc -dM -E empty.m | grep OBJ
和.c文件相比较
cc -dM -E empty.c | grep OBJ