1f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata""" 2f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico GranataObjective-C runtime wrapper for use by LLDB Python formatters 3f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata 4f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granatapart of The LLVM Compiler Infrastructure 5f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico GranataThis file is distributed under the University of Illinois Open Source 6f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico GranataLicense. See LICENSE.TXT for details. 7f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata""" 8b370df27c76fd875f3312be487868528121a4838Enrico Granataimport lldb 90d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataimport lldb.formatters.cache 100d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataimport lldb.formatters.attrib_fromdict 11f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granataimport functools 120d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataimport lldb.formatters.Logger 13b370df27c76fd875f3312be487868528121a4838Enrico Granata 14b370df27c76fd875f3312be487868528121a4838Enrico Granataclass Utilities: 15b370df27c76fd875f3312be487868528121a4838Enrico Granata @staticmethod 161328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata def read_ascii(process, pointer,max_len=128): 170d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 18b370df27c76fd875f3312be487868528121a4838Enrico Granata error = lldb.SBError() 191328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata content = None 201328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata try: 211328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata content = process.ReadCStringFromMemory(pointer,max_len,error) 221328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata except: 231328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata pass 24d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if content is None or len(content) == 0 or error.fail: 251328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata return None 261328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata return content 27b370df27c76fd875f3312be487868528121a4838Enrico Granata 28b370df27c76fd875f3312be487868528121a4838Enrico Granata @staticmethod 29d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata def is_valid_pointer(pointer, pointer_size, allow_tagged=0, allow_NULL=0): 300d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 31d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if pointer is None: 32d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 0 33b370df27c76fd875f3312be487868528121a4838Enrico Granata if pointer == 0: 341328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata return allow_NULL 351328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata if allow_tagged and (pointer % 2) == 1: 36d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 1 37b370df27c76fd875f3312be487868528121a4838Enrico Granata return ((pointer % pointer_size) == 0) 38b370df27c76fd875f3312be487868528121a4838Enrico Granata 39b370df27c76fd875f3312be487868528121a4838Enrico Granata # Objective-C runtime has a rule that pointers in a class_t will only have bits 0 thru 46 set 40b370df27c76fd875f3312be487868528121a4838Enrico Granata # so if any pointer has bits 47 thru 63 high we know that this is not a valid isa 41b370df27c76fd875f3312be487868528121a4838Enrico Granata @staticmethod 42b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_allowed_pointer(pointer): 430d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 44d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if pointer is None: 45d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 0 461328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata return ((pointer & 0xFFFF800000000000) == 0) 47b370df27c76fd875f3312be487868528121a4838Enrico Granata 48b370df27c76fd875f3312be487868528121a4838Enrico Granata @staticmethod 49b370df27c76fd875f3312be487868528121a4838Enrico Granata def read_child_of(valobj,offset,type): 500d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 51d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if offset == 0 and type.GetByteSize() == valobj.GetByteSize(): 52d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return valobj.GetValueAsUnsigned() 53b370df27c76fd875f3312be487868528121a4838Enrico Granata child = valobj.CreateChildAtOffset("childUNK",offset,type) 54d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if child is None or child.IsValid() == 0: 55b370df27c76fd875f3312be487868528121a4838Enrico Granata return None; 56b370df27c76fd875f3312be487868528121a4838Enrico Granata return child.GetValueAsUnsigned() 57b370df27c76fd875f3312be487868528121a4838Enrico Granata 58b370df27c76fd875f3312be487868528121a4838Enrico Granata @staticmethod 59b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_valid_identifier(name): 600d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 61b370df27c76fd875f3312be487868528121a4838Enrico Granata if name is None: 62b370df27c76fd875f3312be487868528121a4838Enrico Granata return None 63b370df27c76fd875f3312be487868528121a4838Enrico Granata if len(name) == 0: 64b370df27c76fd875f3312be487868528121a4838Enrico Granata return None 651328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata # technically, the ObjC runtime does not enforce any rules about what name a class can have 661328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata # in practice, the commonly used byte values for a class name are the letters, digits and some 671328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata # symbols: $, %, -, _, . 681328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata # WARNING: this means that you cannot use this runtime implementation if you need to deal 691328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata # with class names that use anything but what is allowed here 701328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata ok_values = dict.fromkeys("$%_.-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890") 711328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata return all(c in ok_values for c in name) 721328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata 731328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata @staticmethod 741328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata def check_is_osx_lion(target): 750d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 761328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata # assume the only thing that has a Foundation.framework is a Mac 771328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata # assume anything < Lion does not even exist 783b031d93d53b509c43d592cbcdc17a862f3508b8Enrico Granata try: 793b031d93d53b509c43d592cbcdc17a862f3508b8Enrico Granata mod = target.module['Foundation'] 803b031d93d53b509c43d592cbcdc17a862f3508b8Enrico Granata except: 813b031d93d53b509c43d592cbcdc17a862f3508b8Enrico Granata mod = None 82d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if mod is None or mod.IsValid() == 0: 831328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata return None 841328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata ver = mod.GetVersion() 85d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if ver is None or ver == []: 861328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata return None 871328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata return (ver[0] < 900) 88b370df27c76fd875f3312be487868528121a4838Enrico Granata 89579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata # a utility method that factors out code common to almost all the formatters 90579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata # takes in an SBValue and a metrics object 91579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata # returns a class_data and a wrapper (or None, if the runtime alone can't decide on a wrapper) 92579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata @staticmethod 93579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata def prepare_class_detection(valobj,statistics): 940d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 95579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata class_data = ObjCRuntime(valobj) 96d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if class_data.is_valid() == 0: 97579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata statistics.metric_hit('invalid_pointer',valobj) 98579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata wrapper = InvalidPointer_Description(valobj.GetValueAsUnsigned(0) == 0) 99579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return class_data,wrapper 100579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata class_data = class_data.read_class_data() 101d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if class_data.is_valid() == 0: 102579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata statistics.metric_hit('invalid_isa',valobj) 103579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata wrapper = InvalidISA_Description() 104579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return class_data,wrapper 105579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if class_data.is_kvo(): 106579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata class_data = class_data.get_superclass() 10700f9ebe460fd6e9c226f4ba3f6610fbed7b0ef29Enrico Granata if class_data.class_name() == '_NSZombie_OriginalClass': 10800f9ebe460fd6e9c226f4ba3f6610fbed7b0ef29Enrico Granata wrapper = ThisIsZombie_Description() 109579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return class_data,wrapper 110579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return class_data,None 111579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata 112579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata 113b370df27c76fd875f3312be487868528121a4838Enrico Granataclass RoT_Data: 114b370df27c76fd875f3312be487868528121a4838Enrico Granata def __init__(self,rot_pointer,params): 1150d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 116d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if (Utilities.is_valid_pointer(rot_pointer.GetValueAsUnsigned(),params.pointer_size, allow_tagged=0)): 117b370df27c76fd875f3312be487868528121a4838Enrico Granata self.sys_params = params 118b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = rot_pointer 1191328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata #self.flags = Utilities.read_child_of(self.valobj,0,self.sys_params.uint32_t) 120f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata #self.instanceStart = Utilities.read_child_of(self.valobj,4,self.sys_params.uint32_t) 121f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.instanceSize = None # lazy fetching 1221328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata offset = 24 if self.sys_params.is_64_bit else 16 1231328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata #self.ivarLayoutPtr = Utilities.read_child_of(self.valobj,offset,self.sys_params.addr_ptr_type) 124f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.namePointer = Utilities.read_child_of(self.valobj,offset,self.sys_params.types_cache.addr_ptr_type) 125d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 1 # self.check_valid() 126b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 1278f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Marking as invalid - rot is invalid" 128d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 0 129b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.valid: 130b370df27c76fd875f3312be487868528121a4838Enrico Granata self.name = Utilities.read_ascii(self.valobj.GetTarget().GetProcess(),self.namePointer) 131b370df27c76fd875f3312be487868528121a4838Enrico Granata if not(Utilities.is_valid_identifier(self.name)): 1328f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Marking as invalid - name is invalid" 133d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 0 134b370df27c76fd875f3312be487868528121a4838Enrico Granata 135f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata # perform sanity checks on the contents of this class_ro_t 136b370df27c76fd875f3312be487868528121a4838Enrico Granata def check_valid(self): 137d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 1 138b370df27c76fd875f3312be487868528121a4838Enrico Granata # misaligned pointers seem to be possible for this field 139d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata #if not(Utilities.is_valid_pointer(self.namePointer,self.sys_params.pointer_size,allow_tagged=0)): 140d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata # self.valid = 0 141b370df27c76fd875f3312be487868528121a4838Enrico Granata # pass 142b370df27c76fd875f3312be487868528121a4838Enrico Granata 143b370df27c76fd875f3312be487868528121a4838Enrico Granata def __str__(self): 1440d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 1451328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata return \ 146f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata "instanceSize = " + hex(self.instance_size()) + "\n" + \ 147b370df27c76fd875f3312be487868528121a4838Enrico Granata "namePointer = " + hex(self.namePointer) + " --> " + self.name 148b370df27c76fd875f3312be487868528121a4838Enrico Granata 149b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_valid(self): 150b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.valid 151b370df27c76fd875f3312be487868528121a4838Enrico Granata 152d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata def instance_size(self,align=0): 1530d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 154d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if self.is_valid() == 0: 155f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return None 156d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if self.instanceSize is None: 157f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.instanceSize = Utilities.read_child_of(self.valobj,8,self.sys_params.types_cache.uint32_t) 158f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if align: 159d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata unalign = self.instance_size(0) 160f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if self.sys_params.is_64_bit: 161f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return ((unalign + 7) & ~7) % 0x100000000 162f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata else: 163f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return ((unalign + 3) & ~3) % 0x100000000 164f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata else: 165f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return self.instanceSize 166b370df27c76fd875f3312be487868528121a4838Enrico Granata 167b370df27c76fd875f3312be487868528121a4838Enrico Granataclass RwT_Data: 168b370df27c76fd875f3312be487868528121a4838Enrico Granata def __init__(self,rwt_pointer,params): 1690d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 170d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if (Utilities.is_valid_pointer(rwt_pointer.GetValueAsUnsigned(),params.pointer_size, allow_tagged=0)): 171b370df27c76fd875f3312be487868528121a4838Enrico Granata self.sys_params = params 172b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = rwt_pointer 1731328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata #self.flags = Utilities.read_child_of(self.valobj,0,self.sys_params.uint32_t) 1741328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata #self.version = Utilities.read_child_of(self.valobj,4,self.sys_params.uint32_t) 175f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.roPointer = Utilities.read_child_of(self.valobj,8,self.sys_params.types_cache.addr_ptr_type) 176b370df27c76fd875f3312be487868528121a4838Enrico Granata self.check_valid() 177b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 1788f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Marking as invalid - rwt is invald" 179d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 0 180b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.valid: 1816bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata self.rot = self.valobj.CreateValueFromData("rot",lldb.SBData.CreateDataFromUInt64Array(self.sys_params.endianness, self.sys_params.pointer_size, [self.roPointer]),self.sys_params.types_cache.addr_ptr_type) 1826bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata# self.rot = self.valobj.CreateValueFromAddress("rot",self.roPointer,self.sys_params.types_cache.addr_ptr_type).AddressOf() 183b370df27c76fd875f3312be487868528121a4838Enrico Granata self.data = RoT_Data(self.rot,self.sys_params) 184b370df27c76fd875f3312be487868528121a4838Enrico Granata 185b370df27c76fd875f3312be487868528121a4838Enrico Granata # perform sanity checks on the contents of this class_rw_t 186b370df27c76fd875f3312be487868528121a4838Enrico Granata def check_valid(self): 1870d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 188d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 1 189d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if not(Utilities.is_valid_pointer(self.roPointer,self.sys_params.pointer_size,allow_tagged=0)): 1908f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Marking as invalid - ropointer is invalid" 191d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 0 192b370df27c76fd875f3312be487868528121a4838Enrico Granata 193b370df27c76fd875f3312be487868528121a4838Enrico Granata def __str__(self): 1940d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 1951328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata return \ 196b370df27c76fd875f3312be487868528121a4838Enrico Granata "roPointer = " + hex(self.roPointer) 197b370df27c76fd875f3312be487868528121a4838Enrico Granata 198b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_valid(self): 1990d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 200b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.valid: 201b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.data.is_valid() 202d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 0 203b370df27c76fd875f3312be487868528121a4838Enrico Granata 204b370df27c76fd875f3312be487868528121a4838Enrico Granataclass Class_Data_V2: 205b370df27c76fd875f3312be487868528121a4838Enrico Granata def __init__(self,isa_pointer,params): 2060d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 207d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if (isa_pointer != None) and (Utilities.is_valid_pointer(isa_pointer.GetValueAsUnsigned(),params.pointer_size, allow_tagged=0)): 208b370df27c76fd875f3312be487868528121a4838Enrico Granata self.sys_params = params 209b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = isa_pointer 210b370df27c76fd875f3312be487868528121a4838Enrico Granata self.check_valid() 211b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 2128f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Marking as invalid - isa is invalid or None" 213d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 0 214b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.valid: 2156bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata self.rwt = self.valobj.CreateValueFromData("rwt",lldb.SBData.CreateDataFromUInt64Array(self.sys_params.endianness, self.sys_params.pointer_size, [self.dataPointer]),self.sys_params.types_cache.addr_ptr_type) 2166bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata# self.rwt = self.valobj.CreateValueFromAddress("rwt",self.dataPointer,self.sys_params.types_cache.addr_ptr_type).AddressOf() 217b370df27c76fd875f3312be487868528121a4838Enrico Granata self.data = RwT_Data(self.rwt,self.sys_params) 218b370df27c76fd875f3312be487868528121a4838Enrico Granata 219b370df27c76fd875f3312be487868528121a4838Enrico Granata # perform sanity checks on the contents of this class_t 220f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata # this call tries to minimize the amount of data fetched- as soon as we have "proven" 221f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata # that we have an invalid object, we stop reading 222b370df27c76fd875f3312be487868528121a4838Enrico Granata def check_valid(self): 2230d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 224d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 1 225ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas 226f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.isaPointer = Utilities.read_child_of(self.valobj,0,self.sys_params.types_cache.addr_ptr_type) 227d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if not(Utilities.is_valid_pointer(self.isaPointer,self.sys_params.pointer_size,allow_tagged=0)): 2288f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Marking as invalid - isaPointer is invalid" 229d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 0 230b370df27c76fd875f3312be487868528121a4838Enrico Granata return 231f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if not(Utilities.is_allowed_pointer(self.isaPointer)): 2328f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Marking as invalid - isaPointer is not allowed" 233d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 0 234f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return 235f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata 236f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.cachePointer = Utilities.read_child_of(self.valobj,2*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type) 237d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if not(Utilities.is_valid_pointer(self.cachePointer,self.sys_params.pointer_size,allow_tagged=0)): 2388f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Marking as invalid - cachePointer is invalid" 239d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 0 240b370df27c76fd875f3312be487868528121a4838Enrico Granata return 241f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if not(Utilities.is_allowed_pointer(self.cachePointer)): 2428f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Marking as invalid - cachePointer is not allowed" 243d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 0 244f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return 245f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.dataPointer = Utilities.read_child_of(self.valobj,4*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type) 246d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if not(Utilities.is_valid_pointer(self.dataPointer,self.sys_params.pointer_size,allow_tagged=0)): 2478f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Marking as invalid - dataPointer is invalid" 248d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 0 249b370df27c76fd875f3312be487868528121a4838Enrico Granata return 250f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if not(Utilities.is_allowed_pointer(self.dataPointer)): 2518f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Marking as invalid - dataPointer is not allowed" 252d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 0 253b370df27c76fd875f3312be487868528121a4838Enrico Granata return 254f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata 255f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.superclassIsaPointer = Utilities.read_child_of(self.valobj,1*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type) 256d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if not(Utilities.is_valid_pointer(self.superclassIsaPointer,self.sys_params.pointer_size,allow_tagged=0, allow_NULL=1)): 2578f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Marking as invalid - superclassIsa is invalid" 258d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 0 259b370df27c76fd875f3312be487868528121a4838Enrico Granata return 260f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if not(Utilities.is_allowed_pointer(self.superclassIsaPointer)): 2618f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Marking as invalid - superclassIsa is not allowed" 262d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 0 263b370df27c76fd875f3312be487868528121a4838Enrico Granata return 264b370df27c76fd875f3312be487868528121a4838Enrico Granata 2651328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata # in general, KVO is implemented by transparently subclassing 2661328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata # however, there could be exceptions where a class does something else 2671328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata # internally to implement the feature - this method will have no clue that a class 2681328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata # has been KVO'ed unless the standard implementation technique is used 269b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_kvo(self): 2700d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 271b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.is_valid(): 2721328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata if self.class_name().startswith("NSKVONotifying_"): 273d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 1 274d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 0 275b370df27c76fd875f3312be487868528121a4838Enrico Granata 276f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata # some CF classes have a valid ObjC isa in their CFRuntimeBase 277f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata # but instead of being class-specific this isa points to a match-'em-all class 278f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata # which is __NSCFType (the versions without __ also exists and we are matching to it 279f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata # just to be on the safe side) 280f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def is_cftype(self): 2810d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 282f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if self.is_valid(): 283579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return self.class_name() == '__NSCFType' or self.class_name() == 'NSCFType' 284f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata 285b370df27c76fd875f3312be487868528121a4838Enrico Granata def get_superclass(self): 2860d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 287b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.is_valid(): 288b370df27c76fd875f3312be487868528121a4838Enrico Granata parent_isa_pointer = self.valobj.CreateChildAtOffset("parent_isa", 289b370df27c76fd875f3312be487868528121a4838Enrico Granata self.sys_params.pointer_size, 290b370df27c76fd875f3312be487868528121a4838Enrico Granata self.sys_params.addr_ptr_type) 291b370df27c76fd875f3312be487868528121a4838Enrico Granata return Class_Data_V2(parent_isa_pointer,self.sys_params) 292b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 293b370df27c76fd875f3312be487868528121a4838Enrico Granata return None 294b370df27c76fd875f3312be487868528121a4838Enrico Granata 295b370df27c76fd875f3312be487868528121a4838Enrico Granata def class_name(self): 2960d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 297b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.is_valid(): 298b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.data.data.name 299b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 300b370df27c76fd875f3312be487868528121a4838Enrico Granata return None 301b370df27c76fd875f3312be487868528121a4838Enrico Granata 302b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_valid(self): 3030d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 304b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.valid: 305b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.data.is_valid() 306d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 0 307b370df27c76fd875f3312be487868528121a4838Enrico Granata 308b370df27c76fd875f3312be487868528121a4838Enrico Granata def __str__(self): 3090d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 310b370df27c76fd875f3312be487868528121a4838Enrico Granata return 'isaPointer = ' + hex(self.isaPointer) + "\n" + \ 311b370df27c76fd875f3312be487868528121a4838Enrico Granata "superclassIsaPointer = " + hex(self.superclassIsaPointer) + "\n" + \ 312b370df27c76fd875f3312be487868528121a4838Enrico Granata "cachePointer = " + hex(self.cachePointer) + "\n" + \ 313b370df27c76fd875f3312be487868528121a4838Enrico Granata "data = " + hex(self.dataPointer) 314b370df27c76fd875f3312be487868528121a4838Enrico Granata 315b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_tagged(self): 316d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 0 317b370df27c76fd875f3312be487868528121a4838Enrico Granata 318d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata def instance_size(self,align=0): 3190d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 320d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if self.is_valid() == 0: 321e859697139685b7bbe27d3d420e77c727af2080aEnrico Granata return None 322f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return self.rwt.rot.instance_size(align) 323e859697139685b7bbe27d3d420e77c727af2080aEnrico Granata 324b370df27c76fd875f3312be487868528121a4838Enrico Granata# runtime v1 is much less intricate than v2 and stores relevant information directly in the class_t object 325b370df27c76fd875f3312be487868528121a4838Enrico Granataclass Class_Data_V1: 326b370df27c76fd875f3312be487868528121a4838Enrico Granata def __init__(self,isa_pointer,params): 3270d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 328d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if (isa_pointer != None) and (Utilities.is_valid_pointer(isa_pointer.GetValueAsUnsigned(),params.pointer_size, allow_tagged=0)): 329d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 1 330b370df27c76fd875f3312be487868528121a4838Enrico Granata self.sys_params = params 331b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = isa_pointer 332f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.check_valid() 333b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 3348f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Marking as invalid - isaPointer is invalid or None" 335d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 0 336b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.valid: 337b370df27c76fd875f3312be487868528121a4838Enrico Granata self.name = Utilities.read_ascii(self.valobj.GetTarget().GetProcess(),self.namePointer) 338b370df27c76fd875f3312be487868528121a4838Enrico Granata if not(Utilities.is_valid_identifier(self.name)): 3398f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Marking as invalid - name is not valid" 340d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 0 341b370df27c76fd875f3312be487868528121a4838Enrico Granata 342b370df27c76fd875f3312be487868528121a4838Enrico Granata # perform sanity checks on the contents of this class_t 343b370df27c76fd875f3312be487868528121a4838Enrico Granata def check_valid(self): 3440d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 345d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 1 346f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata 347f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.isaPointer = Utilities.read_child_of(self.valobj,0,self.sys_params.types_cache.addr_ptr_type) 348d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if not(Utilities.is_valid_pointer(self.isaPointer,self.sys_params.pointer_size,allow_tagged=0)): 3498f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Marking as invalid - isaPointer is invalid" 350d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 0 351b370df27c76fd875f3312be487868528121a4838Enrico Granata return 352f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata 353f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.superclassIsaPointer = Utilities.read_child_of(self.valobj,1*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type) 354d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if not(Utilities.is_valid_pointer(self.superclassIsaPointer,self.sys_params.pointer_size,allow_tagged=0,allow_NULL=1)): 3558f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Marking as invalid - superclassIsa is invalid" 356d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 0 3571328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata return 358b370df27c76fd875f3312be487868528121a4838Enrico Granata 359f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.namePointer = Utilities.read_child_of(self.valobj,2*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type) 360d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata #if not(Utilities.is_valid_pointer(self.namePointer,self.sys_params.pointer_size,allow_tagged=0,allow_NULL=0)): 361d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata # self.valid = 0 362f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata # return 363f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata 3641328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata # in general, KVO is implemented by transparently subclassing 3651328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata # however, there could be exceptions where a class does something else 3661328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata # internally to implement the feature - this method will have no clue that a class 3671328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata # has been KVO'ed unless the standard implementation technique is used 368b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_kvo(self): 3690d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 370b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.is_valid(): 3711328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata if self.class_name().startswith("NSKVONotifying_"): 372d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 1 373d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 0 374b370df27c76fd875f3312be487868528121a4838Enrico Granata 375f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata # some CF classes have a valid ObjC isa in their CFRuntimeBase 376f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata # but instead of being class-specific this isa points to a match-'em-all class 377f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata # which is __NSCFType (the versions without __ also exists and we are matching to it 378f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata # just to be on the safe side) 379f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def is_cftype(self): 3800d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 381f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if self.is_valid(): 382579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return self.class_name() == '__NSCFType' or self.class_name() == 'NSCFType' 383f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata 384b370df27c76fd875f3312be487868528121a4838Enrico Granata def get_superclass(self): 3850d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 386b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.is_valid(): 387b370df27c76fd875f3312be487868528121a4838Enrico Granata parent_isa_pointer = self.valobj.CreateChildAtOffset("parent_isa", 388b370df27c76fd875f3312be487868528121a4838Enrico Granata self.sys_params.pointer_size, 389b370df27c76fd875f3312be487868528121a4838Enrico Granata self.sys_params.addr_ptr_type) 390b370df27c76fd875f3312be487868528121a4838Enrico Granata return Class_Data_V1(parent_isa_pointer,self.sys_params) 391b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 392b370df27c76fd875f3312be487868528121a4838Enrico Granata return None 393b370df27c76fd875f3312be487868528121a4838Enrico Granata 394b370df27c76fd875f3312be487868528121a4838Enrico Granata def class_name(self): 3950d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 396b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.is_valid(): 397b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.name 398b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 399b370df27c76fd875f3312be487868528121a4838Enrico Granata return None 400b370df27c76fd875f3312be487868528121a4838Enrico Granata 401b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_valid(self): 402b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.valid 403b370df27c76fd875f3312be487868528121a4838Enrico Granata 404b370df27c76fd875f3312be487868528121a4838Enrico Granata def __str__(self): 4050d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 406b370df27c76fd875f3312be487868528121a4838Enrico Granata return 'isaPointer = ' + hex(self.isaPointer) + "\n" + \ 407b370df27c76fd875f3312be487868528121a4838Enrico Granata "superclassIsaPointer = " + hex(self.superclassIsaPointer) + "\n" + \ 408e859697139685b7bbe27d3d420e77c727af2080aEnrico Granata "namePointer = " + hex(self.namePointer) + " --> " + self.name + \ 409f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata "instanceSize = " + hex(self.instanceSize()) + "\n" 410b370df27c76fd875f3312be487868528121a4838Enrico Granata 411b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_tagged(self): 412d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 0 413b370df27c76fd875f3312be487868528121a4838Enrico Granata 414d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata def instance_size(self,align=0): 4150d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 416d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if self.is_valid() == 0: 417e859697139685b7bbe27d3d420e77c727af2080aEnrico Granata return None 418d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if self.instanceSize is None: 419f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.instanceSize = Utilities.read_child_of(self.valobj,5*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type) 420e859697139685b7bbe27d3d420e77c727af2080aEnrico Granata if align: 421d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata unalign = self.instance_size(0) 4221328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata if self.sys_params.is_64_bit: 423e859697139685b7bbe27d3d420e77c727af2080aEnrico Granata return ((unalign + 7) & ~7) % 0x100000000 424e859697139685b7bbe27d3d420e77c727af2080aEnrico Granata else: 425e859697139685b7bbe27d3d420e77c727af2080aEnrico Granata return ((unalign + 3) & ~3) % 0x100000000 426e859697139685b7bbe27d3d420e77c727af2080aEnrico Granata else: 427e859697139685b7bbe27d3d420e77c727af2080aEnrico Granata return self.instanceSize 428e859697139685b7bbe27d3d420e77c727af2080aEnrico Granata 429a0e904189172b6748935e4d00bc05d21f340caaaEnrico Granata# these are the only tagged pointers values for current versions 4303069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata# of OSX - they might change in future OS releases, and no-one is 431a0e904189172b6748935e4d00bc05d21f340caaaEnrico Granata# advised to rely on these values, or any of the bitmasking formulas 432a0e904189172b6748935e4d00bc05d21f340caaaEnrico Granata# in TaggedClass_Data. doing otherwise is at your own risk 4333069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico GranataTaggedClass_Values_Lion = {1 : 'NSNumber', \ 4343069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata 5: 'NSManagedObject', \ 4353069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata 6: 'NSDate', \ 4363069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata 7: 'NSDateTS' }; 4373069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico GranataTaggedClass_Values_NMOS = {0: 'NSAtom', \ 4383069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata 3 : 'NSNumber', \ 4393069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata 4: 'NSDateTS', \ 4403069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata 5: 'NSManagedObject', \ 4413069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata 6: 'NSDate' }; 4421328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata 443b370df27c76fd875f3312be487868528121a4838Enrico Granataclass TaggedClass_Data: 444b370df27c76fd875f3312be487868528121a4838Enrico Granata def __init__(self,pointer,params): 4450d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 4463069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata global TaggedClass_Values_Lion,TaggedClass_Values_NMOS 447d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 1 448b370df27c76fd875f3312be487868528121a4838Enrico Granata self.name = None 449b370df27c76fd875f3312be487868528121a4838Enrico Granata self.sys_params = params 450b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = pointer 451b370df27c76fd875f3312be487868528121a4838Enrico Granata self.val = (pointer & ~0x0000000000000000FF) >> 8 452b370df27c76fd875f3312be487868528121a4838Enrico Granata self.class_bits = (pointer & 0xE) >> 1 453b370df27c76fd875f3312be487868528121a4838Enrico Granata self.i_bits = (pointer & 0xF0) >> 4 454ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas 4553069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata if self.sys_params.is_lion: 4563069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata if self.class_bits in TaggedClass_Values_Lion: 4573069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata self.name = TaggedClass_Values_Lion[self.class_bits] 4583069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata else: 4598f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Marking as invalid - not a good tagged pointer for Lion" 460d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 0 461b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 4623069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata if self.class_bits in TaggedClass_Values_NMOS: 4633069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata self.name = TaggedClass_Values_NMOS[self.class_bits] 4643069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata else: 4658f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Marking as invalid - not a good tagged pointer for NMOS" 466d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.valid = 0 4671328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata 468b370df27c76fd875f3312be487868528121a4838Enrico Granata 469b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_valid(self): 470b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.valid 471b370df27c76fd875f3312be487868528121a4838Enrico Granata 472b370df27c76fd875f3312be487868528121a4838Enrico Granata def class_name(self): 4730d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 474b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.is_valid(): 475b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.name 476b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 477d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 0 478b370df27c76fd875f3312be487868528121a4838Enrico Granata 479b370df27c76fd875f3312be487868528121a4838Enrico Granata def value(self): 480b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.val if self.is_valid() else None 481b370df27c76fd875f3312be487868528121a4838Enrico Granata 482b370df27c76fd875f3312be487868528121a4838Enrico Granata def info_bits(self): 483b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.i_bits if self.is_valid() else None 484b370df27c76fd875f3312be487868528121a4838Enrico Granata 485b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_kvo(self): 486d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 0 487b370df27c76fd875f3312be487868528121a4838Enrico Granata 488f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def is_cftype(self): 489d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 0 490f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata 491b370df27c76fd875f3312be487868528121a4838Enrico Granata # we would need to go around looking for the superclass or ask the runtime 492b370df27c76fd875f3312be487868528121a4838Enrico Granata # for now, we seem not to require support for this operation so we will merrily 493b370df27c76fd875f3312be487868528121a4838Enrico Granata # pretend to be at a root point in the hierarchy 494b370df27c76fd875f3312be487868528121a4838Enrico Granata def get_superclass(self): 495b370df27c76fd875f3312be487868528121a4838Enrico Granata return None 496b370df27c76fd875f3312be487868528121a4838Enrico Granata 497b370df27c76fd875f3312be487868528121a4838Enrico Granata # anything that is handled here is tagged 498b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_tagged(self): 499d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 1 500b370df27c76fd875f3312be487868528121a4838Enrico Granata 501e859697139685b7bbe27d3d420e77c727af2080aEnrico Granata # it seems reasonable to say that a tagged pointer is the size of a pointer 502d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata def instance_size(self,align=0): 5030d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 504d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if self.is_valid() == 0: 505e859697139685b7bbe27d3d420e77c727af2080aEnrico Granata return None 506f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return self.sys_params.pointer_size 507e859697139685b7bbe27d3d420e77c727af2080aEnrico Granata 508e859697139685b7bbe27d3d420e77c727af2080aEnrico Granata 509b370df27c76fd875f3312be487868528121a4838Enrico Granataclass InvalidClass_Data: 510b370df27c76fd875f3312be487868528121a4838Enrico Granata def __init__(self): 511b370df27c76fd875f3312be487868528121a4838Enrico Granata pass 512b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_valid(self): 513d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 0 514b370df27c76fd875f3312be487868528121a4838Enrico Granata 515ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas 516f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granataclass Version: 517f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __init__(self, major, minor, release, build_string): 518f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self._major = major 519f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self._minor = minor 520f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self._release = release 521f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self._build_string = build_string 522f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata 523f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def get_major(self): 524f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return self._major 525f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def get_minor(self): 526f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return self._minor 527f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def get_release(self): 528f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return self._release 529f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def get_build_string(self): 530f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return self._build_string 531f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata 532f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata major = property(get_major,None) 533f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata minor = property(get_minor,None) 534f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata release = property(get_release,None) 535f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata build_string = property(get_build_string,None) 536f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata 537f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __lt__(self,other): 538f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if (self.major < other.major): 539d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 1 540f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if (self.minor < other.minor): 541d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 1 542f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if (self.release < other.release): 543d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 1 544f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata # build strings are not compared since they are heavily platform-dependent and might not always 545f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata # be available 546d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 0 547f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata 548f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __eq__(self,other): 549f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return (self.major == other.major) and \ 550f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata (self.minor == other.minor) and \ 551f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata (self.release == other.release) and \ 552f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata (self.build_string == other.build_string) 553f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata 554ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas # Python 2.6 doesn't have functools.total_ordering, so we have to implement 555ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas # other comparators 556ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas def __gt__(self, other): 557ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas return other < self 558ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas 559ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas def __le__(self, other): 560ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas return not other < self 561ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas 562ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas def __ge__(self, other): 563ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas return not self < other 564ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas 565ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas 5660d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataruntime_version = lldb.formatters.cache.Cache() 5670d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataos_version = lldb.formatters.cache.Cache() 5680d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granatatypes_caches = lldb.formatters.cache.Cache() 5690d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granataisa_caches = lldb.formatters.cache.Cache() 570b370df27c76fd875f3312be487868528121a4838Enrico Granata 571b370df27c76fd875f3312be487868528121a4838Enrico Granataclass SystemParameters: 572b370df27c76fd875f3312be487868528121a4838Enrico Granata def __init__(self,valobj): 5730d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 574b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture(valobj) 575f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.adjust_for_process(valobj) 576b370df27c76fd875f3312be487868528121a4838Enrico Granata 577f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def adjust_for_process(self, valobj): 5780d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 579b370df27c76fd875f3312be487868528121a4838Enrico Granata global runtime_version 5801328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata global os_version 581f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata global types_caches 582f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata global isa_caches 583ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas 584f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata process = valobj.GetTarget().GetProcess() 585209473a3e32a515f28cde69464ba2e625ae8f55cEnrico Granata self.pid = process.GetUniqueID() # using the unique ID for added guarantees (see svn revision 172628 for further details) 586ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas 587f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if runtime_version.look_for_key(self.pid): 588f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.runtime_version = runtime_version.get_value(self.pid) 589b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 590f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.runtime_version = ObjCRuntime.runtime_version(process) 591f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata runtime_version.add_item(self.pid,self.runtime_version) 592ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas 593f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if os_version.look_for_key(self.pid): 594f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.is_lion = os_version.get_value(self.pid) 5951328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata else: 5961328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata self.is_lion = Utilities.check_is_osx_lion(valobj.GetTarget()) 597f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata os_version.add_item(self.pid,self.is_lion) 598ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas 599f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if types_caches.look_for_key(self.pid): 600f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.types_cache = types_caches.get_value(self.pid) 601f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata else: 602d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.types_cache = lldb.formatters.attrib_fromdict.AttributesDictionary(allow_reset=0) 603f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.types_cache.addr_type = valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) 604f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.types_cache.addr_ptr_type = self.types_cache.addr_type.GetPointerType() 605f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.types_cache.uint32_t = valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt) 606f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata types_caches.add_item(self.pid,self.types_cache) 607ee1747d7ae79fdce19b3807c39f81ee8b63c13a0Filipe Cabecinhas 608f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if isa_caches.look_for_key(self.pid): 609f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.isa_cache = isa_caches.get_value(self.pid) 610f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata else: 6110d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata self.isa_cache = lldb.formatters.cache.Cache() 612f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata isa_caches.add_item(self.pid,self.isa_cache) 613f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata 614f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def adjust_for_architecture(self,valobj): 615f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata process = valobj.GetTarget().GetProcess() 616f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.pointer_size = process.GetAddressByteSize() 617f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.is_64_bit = (self.pointer_size == 8) 6186bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata self.endianness = process.GetByteOrder() 6196bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata self.is_little = (self.endianness == lldb.eByteOrderLittle) 620de3b25b645e4b4d97a87ebf059056a6c696d4e9cEnrico Granata self.cfruntime_size = 16 if self.is_64_bit else 8 621b370df27c76fd875f3312be487868528121a4838Enrico Granata 622f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata # a simple helper function that makes it more explicit that one is calculating 623f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata # an offset that is made up of X pointers and Y bytes of additional data 624f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata # taking into account pointer size - if you know there is going to be some padding 625f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata # you can pass that in and it will be taken into account (since padding may be different between 626f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata # 32 and 64 bit versions, you can pass padding value for both, the right one will be used) 627f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def calculate_offset(self, num_pointers = 0, bytes_count = 0, padding32 = 0, padding64 = 0): 628f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata value = bytes_count + num_pointers*self.pointer_size 629f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return value + padding64 if self.is_64_bit else value + padding32 630b370df27c76fd875f3312be487868528121a4838Enrico Granata 631b370df27c76fd875f3312be487868528121a4838Enrico Granataclass ObjCRuntime: 632b370df27c76fd875f3312be487868528121a4838Enrico Granata 633b370df27c76fd875f3312be487868528121a4838Enrico Granata # the ObjC runtime has no explicit "version" field that we can use 634b370df27c76fd875f3312be487868528121a4838Enrico Granata # instead, we discriminate v1 from v2 by looking for the presence 635b370df27c76fd875f3312be487868528121a4838Enrico Granata # of a well-known section only present in v1 636b370df27c76fd875f3312be487868528121a4838Enrico Granata @staticmethod 637b370df27c76fd875f3312be487868528121a4838Enrico Granata def runtime_version(process): 6380d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 639d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if process.IsValid() == 0: 6408f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "No process - bailing out" 641b370df27c76fd875f3312be487868528121a4838Enrico Granata return None 642b370df27c76fd875f3312be487868528121a4838Enrico Granata target = process.GetTarget() 643b370df27c76fd875f3312be487868528121a4838Enrico Granata num_modules = target.GetNumModules() 644b370df27c76fd875f3312be487868528121a4838Enrico Granata module_objc = None 645b370df27c76fd875f3312be487868528121a4838Enrico Granata for idx in range(num_modules): 646b370df27c76fd875f3312be487868528121a4838Enrico Granata module = target.GetModuleAtIndex(idx) 647b370df27c76fd875f3312be487868528121a4838Enrico Granata if module.GetFileSpec().GetFilename() == 'libobjc.A.dylib': 648b370df27c76fd875f3312be487868528121a4838Enrico Granata module_objc = module 649b370df27c76fd875f3312be487868528121a4838Enrico Granata break 650d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if module_objc is None or module_objc.IsValid() == 0: 6518f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "no libobjc - bailing out" 652b370df27c76fd875f3312be487868528121a4838Enrico Granata return None 653b370df27c76fd875f3312be487868528121a4838Enrico Granata num_sections = module.GetNumSections() 654b370df27c76fd875f3312be487868528121a4838Enrico Granata section_objc = None 655b370df27c76fd875f3312be487868528121a4838Enrico Granata for idx in range(num_sections): 656b370df27c76fd875f3312be487868528121a4838Enrico Granata section = module.GetSectionAtIndex(idx) 657b370df27c76fd875f3312be487868528121a4838Enrico Granata if section.GetName() == '__OBJC': 658b370df27c76fd875f3312be487868528121a4838Enrico Granata section_objc = section 659b370df27c76fd875f3312be487868528121a4838Enrico Granata break 660b370df27c76fd875f3312be487868528121a4838Enrico Granata if section_objc != None and section_objc.IsValid(): 6618f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "found __OBJC: v1" 662b370df27c76fd875f3312be487868528121a4838Enrico Granata return 1 6638f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "no __OBJC: v2" 664b370df27c76fd875f3312be487868528121a4838Enrico Granata return 2 665b370df27c76fd875f3312be487868528121a4838Enrico Granata 66667812172eecc4426c17b25354af072f6a4a9aad9Enrico Granata @staticmethod 66767812172eecc4426c17b25354af072f6a4a9aad9Enrico Granata def runtime_from_isa(isa): 6680d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 66967812172eecc4426c17b25354af072f6a4a9aad9Enrico Granata runtime = ObjCRuntime(isa) 67067812172eecc4426c17b25354af072f6a4a9aad9Enrico Granata runtime.isa = isa 67167812172eecc4426c17b25354af072f6a4a9aad9Enrico Granata return runtime 67267812172eecc4426c17b25354af072f6a4a9aad9Enrico Granata 673b370df27c76fd875f3312be487868528121a4838Enrico Granata def __init__(self,valobj): 6740d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 675b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj 676b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture() 677b370df27c76fd875f3312be487868528121a4838Enrico Granata self.sys_params = SystemParameters(self.valobj) 6781328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata self.unsigned_value = self.valobj.GetValueAsUnsigned() 6791328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata self.isa_value = None 680b370df27c76fd875f3312be487868528121a4838Enrico Granata 681b370df27c76fd875f3312be487868528121a4838Enrico Granata def adjust_for_architecture(self): 682f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 683b370df27c76fd875f3312be487868528121a4838Enrico Granata 684b370df27c76fd875f3312be487868528121a4838Enrico Granata# an ObjC pointer can either be tagged or must be aligned 685b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_tagged(self): 6860d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 687b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.valobj is None: 688d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 0 689d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return (Utilities.is_valid_pointer(self.unsigned_value,self.sys_params.pointer_size, allow_tagged=1) and \ 690d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata not(Utilities.is_valid_pointer(self.unsigned_value,self.sys_params.pointer_size, allow_tagged=0))) 691b370df27c76fd875f3312be487868528121a4838Enrico Granata 692b370df27c76fd875f3312be487868528121a4838Enrico Granata def is_valid(self): 6930d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 694b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.valobj is None: 695d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 0 696d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if self.valobj.IsInScope() == 0: 697d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return 0 698d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return Utilities.is_valid_pointer(self.unsigned_value,self.sys_params.pointer_size, allow_tagged=1) 699b370df27c76fd875f3312be487868528121a4838Enrico Granata 700579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata def is_nil(self): 701579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return self.unsigned_value == 0 702579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata 703b370df27c76fd875f3312be487868528121a4838Enrico Granata def read_isa(self): 7040d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 7051328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata if self.isa_value != None: 7068f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "using cached isa" 7071328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata return self.isa_value 708d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.isa_pointer = self.valobj.CreateChildAtOffset("cfisa", 709b370df27c76fd875f3312be487868528121a4838Enrico Granata 0, 710f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.addr_ptr_type) 711d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if self.isa_pointer is None or self.isa_pointer.IsValid() == 0: 7128f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "invalid isa - bailing out" 713b370df27c76fd875f3312be487868528121a4838Enrico Granata return None; 714d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.isa_value = self.isa_pointer.GetValueAsUnsigned(1) 715d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if self.isa_value == 1: 7168f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "invalid isa value - bailing out" 717b370df27c76fd875f3312be487868528121a4838Enrico Granata return None; 718d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata return Ellipsis 719b370df27c76fd875f3312be487868528121a4838Enrico Granata 720b370df27c76fd875f3312be487868528121a4838Enrico Granata def read_class_data(self): 7210d235d5864e996d95f485df1a0df406126e1ccdeEnrico Granata logger = lldb.formatters.Logger.Logger() 722b370df27c76fd875f3312be487868528121a4838Enrico Granata global isa_cache 723b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.is_tagged(): 724b370df27c76fd875f3312be487868528121a4838Enrico Granata # tagged pointers only exist in ObjC v2 725b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.sys_params.runtime_version == 2: 7268f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "on v2 and tagged - maybe" 727b370df27c76fd875f3312be487868528121a4838Enrico Granata # not every odd-valued pointer is actually tagged. most are just plain wrong 728b370df27c76fd875f3312be487868528121a4838Enrico Granata # we could try and predetect this before even creating a TaggedClass_Data object 729b370df27c76fd875f3312be487868528121a4838Enrico Granata # but unless performance requires it, this seems a cleaner way to tackle the task 7301328b1410eb0f5e03c3b3ee302e9adca3e1b0361Enrico Granata tentative_tagged = TaggedClass_Data(self.unsigned_value,self.sys_params) 7318f18240a09893310c43673901d863892ae7b0611Enrico Granata if tentative_tagged.is_valid(): 7328f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "truly tagged" 7338f18240a09893310c43673901d863892ae7b0611Enrico Granata return tentative_tagged 7348f18240a09893310c43673901d863892ae7b0611Enrico Granata else: 7358f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "not tagged - error" 7368f18240a09893310c43673901d863892ae7b0611Enrico Granata return InvalidClass_Data() 737b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 7388f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "on v1 and tagged - error" 739b370df27c76fd875f3312be487868528121a4838Enrico Granata return InvalidClass_Data() 740d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if self.is_valid() == 0 or self.read_isa() is None: 741b370df27c76fd875f3312be487868528121a4838Enrico Granata return InvalidClass_Data() 742d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata data = self.sys_params.isa_cache.get_value(self.isa_value,default=None) 743b370df27c76fd875f3312be487868528121a4838Enrico Granata if data != None: 744b370df27c76fd875f3312be487868528121a4838Enrico Granata return data 745b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.sys_params.runtime_version == 2: 746d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata data = Class_Data_V2(self.isa_pointer,self.sys_params) 747b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 748d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata data = Class_Data_V1(self.isa_pointer,self.sys_params) 749d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata if data is None: 750b370df27c76fd875f3312be487868528121a4838Enrico Granata return InvalidClass_Data() 751b370df27c76fd875f3312be487868528121a4838Enrico Granata if data.is_valid(): 752d0a098024ae5cd6e98429682590e687cecb6b0feEnrico Granata self.sys_params.isa_cache.add_item(self.isa_value,data,ok_to_replace=1) 753b370df27c76fd875f3312be487868528121a4838Enrico Granata return data 754e859697139685b7bbe27d3d420e77c727af2080aEnrico Granata 755579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata# these classes below can be used by the data formatters to provide a consistent message that describes a given runtime-generated situation 756579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granataclass SpecialSituation_Description: 757579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata def message(self): 758579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return '' 759579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata 760579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granataclass InvalidPointer_Description(SpecialSituation_Description): 761579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata 762579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata def __init__(self,nil): 763579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata self.is_nil = nil 764579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata 765579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata def message(self): 766579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if self.is_nil: 767579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return '@"<nil>"' 768579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata else: 769579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return '<invalid pointer>' 770579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata 771579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granataclass InvalidISA_Description(SpecialSituation_Description): 772579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata 773579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata def __init__(self): 774579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata pass 775579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata 776579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata def message(self): 777579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return '<not an Objective-C object>' 778579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata 77900f9ebe460fd6e9c226f4ba3f6610fbed7b0ef29Enrico Granataclass ThisIsZombie_Description(SpecialSituation_Description): 78000f9ebe460fd6e9c226f4ba3f6610fbed7b0ef29Enrico Granata def message(self): 78100f9ebe460fd6e9c226f4ba3f6610fbed7b0ef29Enrico Granata return '<freed object>'