def _readClassRO(machO, cls, protoRefsMap, absfileoff): """Peek a ``class_ro_t`` at *absfileoff*. If *cls* is ``None``, read the class as normal class. Otherwise, read as meta class and insert the class methods. """ # typedef struct class_ro_t { # uint32_t flags; # uint32_t instanceStart; # uint32_t instanceSize; # #ifdef __LP64__ # uint32_t reserved; # #endif # # const uint8_t * ivarLayout; # # const char * name; # const method_list_t * baseMethods; # const protocol_list_t * baseProtocols; # const ivar_list_t * ivars; # # const uint8_t * weakIvarLayout; # const struct objc_property_list *baseProperties; # } class_ro_t; (flags, _, _, _, namePtr, methodsPtr, protosPtr, ivarsPtr, _, propsPtr) = peekStruct(machO.file, machO.makeStruct('3L~7^'), position=absfileoff) methods = readMethodListAt(machO, methodsPtr, optional=False) if cls is None: # not meta class. name = machO.derefString(namePtr) cls = Class(name, flags) cls.addMethods(methods) cls.addIvars(readIvarListAt(machO, ivarsPtr)) cls.addProperties(readPropertyListAt(machO, propsPtr)) protocolRefs = _readProtocolRefListAt(machO, protosPtr) connectProtocol(cls, protocolRefs, protoRefsMap) else: # is meta-class: prepend the class methods. cls.addClassMethods(methods) return cls
def analyzeClass(machO, classTuple, protoRefsMap): """Analyze an ``old_class`` structure. Returns the :class:`~objc.class_.Class` and the pointer to the super class. """ # struct old_class { # struct old_class *isa; # struct old_class *super_class; # const char *name; # long version; # long info; # long instance_size; # struct old_ivar_list *ivars; # struct old_method_list **methodLists; # Cache cache; # struct old_protocol_list *protocols; # // CLS_EXT only # const char *ivar_layout; # struct old_class_ext *ext; # }; (metaClsPtr, superClsPtr, namePtr, _, _, _, ivarListPtr, methodListsPtr, _, protoListPtr, _, classExtPtr) = classTuple ms = machO.makeStruct deref = machO.deref name = machO.derefString(namePtr) cls = Class(name) cls.addIvars(readIvarList(machO, ivarListPtr)) cls.addMethods(readLists(machO, methodListsPtr, readMethodList)) if protoListPtr: protoAddrs = list(_readProtocolRefListsAt(machO, [protoListPtr])) connectProtocol(cls, protoAddrs, protoRefsMap) if classExtPtr: # struct old_class_ext { # uint32_t size; # const char *weak_ivar_layout; # struct objc_property_list **propertyLists; # }; propListsPtr = deref(classExtPtr, ms('L~2^'))[2] cls.addProperties(readPropertyList(machO, propListsPtr)) metaClsTuple = deref(metaClsPtr, ms('12^')) cls.addClassMethods(readLists(machO, metaClsTuple[7], readMethodList)) return (cls, superClsPtr)