X-Git-Url: https://git.saurik.com/apple/objc4.git/blobdiff_plain/7257e56cc9570231fcb1a302702a85f51f9a9790..refs/heads/master:/runtime/objc-gdb.h diff --git a/runtime/objc-gdb.h b/runtime/objc-gdb.h index 55304a2..99cff42 100644 --- a/runtime/objc-gdb.h +++ b/runtime/objc-gdb.h @@ -34,7 +34,9 @@ #ifdef __APPLE_API_PRIVATE -#define _OBJC_PRIVATE_H_ +#ifndef _OBJC_PRIVATE_H_ +# define _OBJC_PRIVATE_H_ +#endif #include #include #include @@ -47,17 +49,30 @@ __BEGIN_DECLS **********************************************************************/ // Return cls if it's a valid class, or crash. -OBJC_EXPORT Class gdb_class_getClass(Class cls) +OBJC_EXPORT Class _Nonnull +gdb_class_getClass(Class _Nonnull cls) #if __OBJC2__ - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1); + OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0, 2.0); #else - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_3_1); + OBJC_AVAILABLE(10.7, 3.1, 9.0, 1.0, 2.0); #endif // Same as gdb_class_getClass(object_getClass(cls)). -OBJC_EXPORT Class gdb_object_getClass(id obj) - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +OBJC_EXPORT Class _Nonnull gdb_object_getClass(id _Nullable obj) + OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0); + +/*********************************************************************** +* Class inspection +**********************************************************************/ + +#if __OBJC2__ + +// Return the raw, mangled name of cls. +OBJC_EXPORT const char * _Nonnull +objc_debug_class_getNameRaw(Class _Nullable cls) +OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0); +#endif /*********************************************************************** * Class lists for heap. @@ -66,14 +81,124 @@ OBJC_EXPORT Class gdb_object_getClass(id obj) #if __OBJC2__ // Maps class name to Class, for in-use classes only. NXStrValueMapPrototype. -OBJC_EXPORT NXMapTable *gdb_objc_realized_classes - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1); +OBJC_EXPORT NXMapTable * _Nullable gdb_objc_realized_classes + OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0, 2.0); + +// A generation count of realized classes. Increments when new classes +// are realized. This is NOT an exact count of the number of classes. +// It's not guaranteed by how much it increases when classes are +// realized, only that it increases by something. When classes are +// removed (unloading bundles or destroying dynamically allocated +// classes) the number will also increase to signal that there has +// been a change. +OBJC_EXPORT uintptr_t objc_debug_realized_class_generation_count; #else // Hashes Classes, for all known classes. Custom prototype. -OBJC_EXPORT NXHashTable *_objc_debug_class_hash - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA); +OBJC_EXPORT NXHashTable * _Nullable _objc_debug_class_hash + __OSX_AVAILABLE(10.2) + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; + +#endif + + +/*********************************************************************** +* Non-pointer isa +**********************************************************************/ + +#if __OBJC2__ + +// Extract isa pointer from an isa field. +// (Class)(isa & mask) == class pointer +OBJC_EXPORT const uintptr_t objc_debug_isa_class_mask + OBJC_AVAILABLE(10.10, 7.0, 9.0, 1.0, 2.0); + +// Extract magic cookie from an isa field. +// (isa & magic_mask) == magic_value +OBJC_EXPORT const uintptr_t objc_debug_isa_magic_mask + OBJC_AVAILABLE(10.10, 7.0, 9.0, 1.0, 2.0); +OBJC_EXPORT const uintptr_t objc_debug_isa_magic_value + OBJC_AVAILABLE(10.10, 7.0, 9.0, 1.0, 2.0); + +// Use indexed ISAs for targets which store index of the class in the ISA. +// This index can be used to index the array of classes. +OBJC_EXPORT const uintptr_t objc_debug_indexed_isa_magic_mask; +OBJC_EXPORT const uintptr_t objc_debug_indexed_isa_magic_value; + +// Then these are used to extract the index from the ISA. +OBJC_EXPORT const uintptr_t objc_debug_indexed_isa_index_mask; +OBJC_EXPORT const uintptr_t objc_debug_indexed_isa_index_shift; + +// And then we can use that index to get the class from this array. Note +// the size is provided so that clients can ensure the index they get is in +// bounds and not read off the end of the array. +OBJC_EXPORT Class _Nullable objc_indexed_classes[]; + +// When we don't have enough bits to store a class*, we can instead store an +// index in to this array. Classes are added here when they are realized. +// Note, an index of 0 is illegal. +OBJC_EXPORT uintptr_t objc_indexed_classes_count; + +// Absolute symbols for some of the above values are in objc-abi.h. + +#endif + + +/*********************************************************************** +* Class structure decoding +**********************************************************************/ +#if __OBJC2__ + +// Mask for the pointer from class struct to class rw data. +// Other bits may be used for flags. +// Use 0x00007ffffffffff8UL or 0xfffffffcUL when this variable is unavailable. +OBJC_EXPORT const uintptr_t objc_debug_class_rw_data_mask + OBJC_AVAILABLE(10.13, 11.0, 11.0, 4.0, 2.0); + +// The ABI version for the internal runtime representations +// lldb, CoreSymbolication and debugging tools need to know +OBJC_EXTERN const uint32_t objc_class_abi_version + OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0); + +// the maximum ABI version in existence for now +#define OBJC_CLASS_ABI_VERSION_MAX 1 + +// Used when objc_class_abi_version is absent or 0 +struct class_rw_v0_t { + uint32_t flags; + uint32_t version; + uintptr_t ro; // class_ro_t + uintptr_t methods; // method_array_t + uintptr_t properties; // property_array_t + uintptr_t protocols; // protocol_array_t + Class _Nullable firstSubclass; + Class _Nullable nextSiblingClass; + char *_Nullable demangledName; + + // uint32_t index; // only when indexed-isa is used +}; + +// Used when objc_class_abi_version is 1 +struct class_rw_v1_t { + uint32_t flags; + uint16_t witness; + uint16_t index; // only when indexed-isa is used + uintptr_t ro_or_rw_ext; // tagged union based on the low bit: + // 0: class_ro_t 1: class_rw_ext_t + Class _Nullable firstSubclass; + Class _Nullable nextSiblingClass; +}; + +struct class_rw_ext_v1_t { + uintptr_t ro; // class_ro_t + uintptr_t methods; // method_array_t + uintptr_t properties; // property_array_t + uintptr_t protocols; // protocol_array_t + char *_Nullable demangledName; + uint32_t version; +}; #endif @@ -83,81 +208,102 @@ OBJC_EXPORT NXHashTable *_objc_debug_class_hash **********************************************************************/ #if __OBJC2__ +// Basic tagged pointers (7 classes, 60-bit payload). + // if (obj & mask) obj is a tagged pointer object OBJC_EXPORT uintptr_t objc_debug_taggedpointer_mask - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA); + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0); + +// tagged pointers are obfuscated by XORing with a random value +// decoded_obj = (obj ^ obfuscator) +OBJC_EXPORT uintptr_t objc_debug_taggedpointer_obfuscator + OBJC_AVAILABLE(10.14, 12.0, 12.0, 5.0, 3.0); + +#if OBJC_SPLIT_TAGGED_POINTERS +OBJC_EXPORT uint8_t objc_debug_tag60_permutations[8]; +#endif + // tag_slot = (obj >> slot_shift) & slot_mask OBJC_EXPORT unsigned int objc_debug_taggedpointer_slot_shift - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA); + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0); OBJC_EXPORT uintptr_t objc_debug_taggedpointer_slot_mask - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA); + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0); // class = classes[tag_slot] -OBJC_EXPORT Class objc_debug_taggedpointer_classes[] - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA); +OBJC_EXPORT Class _Nullable objc_debug_taggedpointer_classes[] + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0); -// payload = (obj << payload_lshift) >> payload_rshift +// payload = (decoded_obj << payload_lshift) >> payload_rshift // Payload signedness is determined by the signedness of the right-shift. OBJC_EXPORT unsigned int objc_debug_taggedpointer_payload_lshift - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA); + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0); OBJC_EXPORT unsigned int objc_debug_taggedpointer_payload_rshift - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA); + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0); -#endif +// Extended tagged pointers (255 classes, 52-bit payload). -/*********************************************************************** -* Breakpoints in objc_msgSend for debugger stepping. -* The array is a {0,0} terminated list of addresses. -* Each address is one of the following: -* OBJC_MESSENGER_START: Address is the start of a messenger function. -* OBJC_MESSENGER_END_FAST: Address is a jump insn that calls an IMP. -* OBJC_MESSENGER_END_SLOW: Address is some insn in the slow lookup path. -* OBJC_MESSENGER_END_NIL: Address is a return insn for messages to nil. -* -* Every path from OBJC_MESSENGER_START should reach some OBJC_MESSENGER_END. -* At all ENDs, the stack and parameter register state is the same as START. -* -* In some cases, the END_FAST case jumps to something other than the -* method's implementation. In those cases the jump's destination will -* be another function that is marked OBJC_MESSENGER_START. -**********************************************************************/ -#if __OBJC2__ +// If you interrogate an extended tagged pointer using the basic +// tagged pointer scheme alone, it will appear to have an isa +// that is either nil or class __NSUnrecognizedTaggedPointer. -#define OBJC_MESSENGER_START 1 -#define OBJC_MESSENGER_END_FAST 2 -#define OBJC_MESSENGER_END_SLOW 3 -#define OBJC_MESSENGER_END_NIL 4 +// if (ext_mask != 0 && (decoded_obj & ext_mask) == ext_mask) +// obj is a ext tagged pointer object +OBJC_EXPORT uintptr_t objc_debug_taggedpointer_ext_mask + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); -struct objc_messenger_breakpoint { - uintptr_t address; - uintptr_t kind; -}; +// ext_tag_slot = (obj >> ext_slot_shift) & ext_slot_mask +OBJC_EXPORT unsigned int objc_debug_taggedpointer_ext_slot_shift + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); +OBJC_EXPORT uintptr_t objc_debug_taggedpointer_ext_slot_mask + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); -OBJC_EXPORT struct objc_messenger_breakpoint -gdb_objc_messenger_breakpoints[] - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); +// class = ext_classes[ext_tag_slot] +OBJC_EXPORT Class _Nullable objc_debug_taggedpointer_ext_classes[] + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); -#endif +// payload = (decoded_obj << ext_payload_lshift) >> ext_payload_rshift +// Payload signedness is determined by the signedness of the right-shift. +OBJC_EXPORT unsigned int objc_debug_taggedpointer_ext_payload_lshift + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); +OBJC_EXPORT unsigned int objc_debug_taggedpointer_ext_payload_rshift + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); +OBJC_EXPORT uintptr_t objc_debug_constant_cfstring_tag_bits + OBJC_AVAILABLE(10.16, 14.0, 14.0, 7.0, 6.0); + +#endif -#ifndef OBJC_NO_GC /*********************************************************************** - * Garbage Collector heap dump +* Swift marker bits **********************************************************************/ +#if __OBJC2__ +OBJC_EXPORT const uintptr_t objc_debug_swift_stable_abi_bit +OBJC_AVAILABLE(10.14.4, 12.2, 12.2, 5.2, 3.2); +#endif -/* Dump GC heap; if supplied the name is returned in filenamebuffer. Returns YES on success. */ -OBJC_EXPORT BOOL objc_dumpHeap(char *filenamebuffer, unsigned long length) - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); -#define OBJC_HEAP_DUMP_FILENAME_FORMAT "/tmp/objc-gc-heap-dump-%d-%d" +/*********************************************************************** +* AutoreleasePoolPage +**********************************************************************/ +OBJC_EXTERN const uint32_t objc_debug_autoreleasepoolpage_magic_offset OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0); +OBJC_EXTERN const uint32_t objc_debug_autoreleasepoolpage_next_offset OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0); +OBJC_EXTERN const uint32_t objc_debug_autoreleasepoolpage_thread_offset OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0); +OBJC_EXTERN const uint32_t objc_debug_autoreleasepoolpage_parent_offset OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0); +OBJC_EXTERN const uint32_t objc_debug_autoreleasepoolpage_child_offset OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0); +OBJC_EXTERN const uint32_t objc_debug_autoreleasepoolpage_depth_offset OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0); +OBJC_EXTERN const uint32_t objc_debug_autoreleasepoolpage_hiwat_offset OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0); +#if __OBJC2__ +OBJC_EXTERN const uintptr_t objc_debug_autoreleasepoolpage_ptr_mask OBJC_AVAILABLE(10.16, 14.0, 14.0, 7.0, 6.0); #endif __END_DECLS +// APPLE_API_PRIVATE #endif +// _OBJC_GDB_H #endif