def test_new_far(): p = ptr.new_far(0, 725, 1) assert ptr.kind(p) == ptr.FAR assert ptr.far_landing_pad(p) == 0 assert ptr.far_offset(p) == 725 assert ptr.far_target(p) == 1 assert p == 0x00000001000016aa
def test_FarPtr(): # 00000001 target # 000016aa offset # a landing # a kind p = 0x00000001000016aa assert ptr.kind(p) == ptr.FAR assert ptr.far_landing_pad(p) == 0 assert ptr.far_offset(p) == 725 assert ptr.far_target(p) == 1
def read_far_ptr(self, offset): """ Read and return the ptr referenced by this far pointer """ p = self.read_ptr(offset) assert ptr.far_landing_pad(p) == 0 segment_start = self.segment_offsets[ptr.far_target(p)] # in bytes offset = segment_start + ptr.far_offset(p) * 8 p = self.read_ptr(offset) return offset, p
def read_far_ptr(self, offset): """ Read and return the ptr referenced by this far pointer """ p = self.read_ptr(offset) segment_start = self.segment_offsets[ptr.far_target(p)] # in bytes offset = segment_start + ptr.far_offset(p) * 8 if ptr.far_landing_pad(p) == 0: # simple case: the landing pad is a normal pointer, just read it p = self.read_ptr(offset) return offset, p else: # complex case. From capnproto specs: # If B == 1, then the "landing pad" is itself another far # pointer that is interpreted differently: This far pointer # (which always has B = 0) points to the start of the object's # content, located in some other segment. The landing pad is # itself immediately followed by a tag word. The tag word # looks exactly like an intra-segment pointer to the target # object would look, except that the offset is always zero. # # read the 2nd far pointer and the tag word p = self.read_ptr(offset) ptag = self.read_ptr(offset + 8) assert ptr.kind(p) == ptr.FAR assert ptr.far_landing_pad(p) == 0 assert ptr.offset(ptag) == 0 # compute the absolute offset which the object is located at segment_start = self.segment_offsets[ptr.far_target(p)] # in bytes offset = segment_start + ptr.far_offset(p) * 8 # # ptag is a pointer which perfectly describes the object we want # to read. Remember that normally when ptr_offset==0, capnproto # expects the object to start at offset+8. So here we return # offset-8, so that the object will be read at the expected place return offset - 8, ptag
def ptr(self, offset, s): p = struct.unpack('q', s)[0] if ptr.kind(p) not in (ptr.STRUCT, ptr.LIST, ptr.FAR): return ' ' * 25 # # try to display only "reasonable" ptrs; if the fields are too big, it # probably means that the current word is not a pointer def if_in_range(x, min, max): if min <= x < max: return str(x) else: return '?' # if p == 0: return 'NULL'.ljust(25) if ptr.kind(p) == ptr.STRUCT: descr = 'struct {:>4} {:>3}'.format( if_in_range(ptr.struct_data_size(p), 0, 100), if_in_range(ptr.struct_ptrs_size(p), 0, 100)) elif ptr.kind(p) == ptr.LIST: tag = '<%s>' % self._list_tag(ptr.list_size_tag(p)) descr = 'list{:<5} {:>5}'.format( tag, if_in_range(ptr.list_item_count(p), 0, 65536)) elif ptr.kind(p) == ptr.FAR: descr = 'far {:>7} {:>3}'.format( ptr.far_landing_pad(p), if_in_range(ptr.far_target(p), 0, 100)) else: descr = 'unknown ptr ' # if -1000 < ptr.offset(p) < 1000: dest = ptr.deref(p, offset) dest = self.addr(dest) dest = dest.ljust(16) else: dest = '? ' line = '{0} to {1}'.format(descr, dest) if '?' in line: return Color.set(Color.lightgray, line) else: return line
def unpack(p): assert ptr.kind(p) == ptr.FAR return ptr.far_landing_pad(p), ptr.far_offset(p), ptr.far_target(p)