[Lldb-commits] [lldb] r139372 - /lldb/trunk/examples/synthetic/objc.py

Enrico Granata granata.enrico at gmail.com
Fri Sep 9 09:47:15 PDT 2011


Author: enrico
Date: Fri Sep  9 11:47:15 2011
New Revision: 139372

URL: http://llvm.org/viewvc/llvm-project?rev=139372&view=rev
Log:
Objective-C runtime wrapper

Added:
    lldb/trunk/examples/synthetic/objc.py

Added: lldb/trunk/examples/synthetic/objc.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/synthetic/objc.py?rev=139372&view=auto
==============================================================================
--- lldb/trunk/examples/synthetic/objc.py (added)
+++ lldb/trunk/examples/synthetic/objc.py Fri Sep  9 11:47:15 2011
@@ -0,0 +1,128 @@
+"""
+Objective-C runtime wrapper - Replicates the behavior of AppleObjCRuntimeV2.cpp in Python code
+for the benefit of synthetic children providers and Python summaries
+
+part of The LLVM Compiler Infrastructure
+This file is distributed under the University of Illinois Open Source
+License. See LICENSE.TXT for details.
+"""
+import lldb
+
+class ObjCRuntime:
+
+	def __init__(self,valobj = None):
+		self.valobj = valobj;
+		self.adjust_for_architecture() 
+
+	def adjust_for_architecture(self):
+		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
+		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
+		self.addr_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
+		self.addr_ptr_type = self.addr_type.GetPointerType()
+
+	def is_tagged(self):
+		if valobj is None:
+			return None
+		ptr_value = self.valobj.GetPointerValue()
+		if (ptr_value % 2) == 1:
+			return True
+		else:
+			return False
+
+	def read_ascii(self, pointer):
+		process = self.valobj.GetTarget().GetProcess()
+		error = lldb.SBError()
+		pystr = ''
+		# cannot do the read at once because there is no length byte
+		while True:
+			content = process.ReadMemory(pointer, 1, error)
+			new_bytes = bytearray(content)
+			b0 = new_bytes[0]
+			pointer = pointer + 1
+			if b0 == 0:
+				break
+			pystr = pystr + chr(b0)
+		return pystr
+
+	def read_isa(self):
+		# read ISA pointer
+		isa_pointer = self.valobj.CreateChildAtOffset("cfisa",
+			0,
+			self.addr_ptr_type)
+		if isa_pointer == None or isa_pointer.IsValid() == False:
+			return None;
+		if isa_pointer.GetValue() == None:
+			return None;
+		isa = int(isa_pointer.GetValue(), 0)
+		if isa == 0 or isa == None:
+			return None;
+		return isa
+		
+
+	def get_parent_class(self, isa = None):
+		if isa is None:
+			isa = self.read_isa()
+		# read superclass pointer
+		rw_pointer = isa + self.pointer_size
+		rw_object = self.valobj.CreateValueFromAddress("parent_isa",
+			rw_pointer,
+			self.addr_type)
+		if rw_object == None or rw_object.IsValid() == False:
+			return None;
+		if rw_object.GetValue() == None:
+			return None;
+		rw = int(rw_object.GetValue(), 0)
+		if rw == 0 or rw == None:
+			return None;
+		return rw
+
+	def get_class_name(self, isa = None):
+		if isa is None:
+			isa = self.read_isa()
+		# read rw pointer
+		rw_pointer = isa + 4 * self.pointer_size
+		rw_object = self.valobj.CreateValueFromAddress("rw",
+			rw_pointer,
+			self.addr_type)
+		if rw_object == None or rw_object.IsValid() == False:
+			return None;
+		if rw_object.GetValue() == None:
+			return None;
+		rw = int(rw_object.GetValue(), 0)
+		if rw == 0 or rw == None:
+			return None;
+
+		# read data pointer
+		data_pointer = rw + 8
+		data_object = self.valobj.CreateValueFromAddress("data",
+			data_pointer,
+			self.addr_type)
+		if data_object == None or data_object.IsValid() == False:
+			return None;
+		if data_object.GetValue() == None:
+			return None;
+		data = int(data_object.GetValue(), 0)
+		if data == 0 or data == None:
+			return None;
+
+		# read ro pointer
+		ro_pointer = data + 12 + self.pointer_size
+		if self.lp64:
+			ro_pointer += 4
+		ro_object = self.valobj.CreateValueFromAddress("ro",
+			ro_pointer,
+			self.addr_type)
+		if ro_object == None or ro_object.IsValid() == False:
+			return None;
+		if ro_object.GetValue() == None:
+			return None;
+		name_pointer = int(ro_object.GetValue(), 0)
+		if name_pointer == 0 or name_pointer == None:
+			return None;
+
+		# now read the actual name and compare it to known stuff
+		name_string = self.read_ascii(name_pointer)
+		if (name_string.startswith("NSKVONotify")):
+			return self.get_class_name(self.get_parent_class())
+		return name_string





More information about the lldb-commits mailing list