# HG changeset patch # User Thinker K.F. Li # Date 1309095292 -28800 # Node ID c2a4921ec83be705858bb2f53e003e2664afd290 # Parent fa8fe7d714b9342c3a0421dee9ca2cbffa7692f6 Fix issue misbehavior for dependency when update_offset() - If value of a depenend object is linked to its depend-on, it's size should be computed with value from depend-on. But, it was not. - It is fixed by awaring linking of depend objects in dex_deptracker.update_offset() and depend classes. diff -r fa8fe7d714b9 -r c2a4921ec83b paraspace/dex_deptracker.py --- a/paraspace/dex_deptracker.py Sat Jun 25 08:16:16 2011 +0800 +++ b/paraspace/dex_deptracker.py Sun Jun 26 21:34:52 2011 +0800 @@ -6,13 +6,18 @@ dexfile.switch) +def _skip_marker_clazz(marker): + while isinstance(marker, _marker): + marker = marker.back_type + pass + return marker + + def _resolve_name_path(name_path): obj = dexfile parent = None for name in name_path.split('.'): - while isinstance(obj, _marker): - obj = obj.back_type - pass + obj = _skip_marker_clazz(obj) if isinstance(parent, dexfile.array) and obj == list: # array.items. @@ -53,12 +58,7 @@ return False return True - # - # pass throught markers - # - while isinstance(clazz, _marker): - clazz = clazz.back_type - pass + clazz = _skip_marker_clazz(clazz) travel_queue = [(getattr(clazz, attr_name), name_path + '.' + attr_name) for attr_name in dir(clazz) @@ -270,9 +270,7 @@ def _all_dex_type_to_names(): def check_marker(value, name): - while isinstance(value, _marker): - value = value.back_type - pass + value = _skip_marker_clazz(value) return value, name dex_types = dict([check_marker(value, name) @@ -454,6 +452,7 @@ pass for idx, item in enumerate(obj.items): id_item_map[idx] = item + item.data_idx = idx pass pass @@ -720,7 +719,7 @@ depon1 = markers_info[dep[1]][offset] name = name_path.split('.')[-1] - _dex_tree_set_child(imm_parent, name, (depon1, depon2)) + _dex_tree_set_child(imm_parent, name, depon1) elif dep_type == dexfile.depend_off: depon_name_path = dep[1] depon = markers_info[depon_name_path][obj] @@ -771,21 +770,25 @@ depon_dep_map = _build_depon_dep_map(all_dep_decls) dex_type_names = _all_dex_type_to_names() - def make_path(obj, path_parts, obj_name): + def make_path(obj, parent_path, obj_name): + name_path = parent_path + '.' + obj_name + if isinstance(obj, dexfile.composite): - type_name = dex_type_names[obj.__class__] - return [type_name] - return path_parts + [obj_name] + if name_path not in all_dep_decls: + type_name = dex_type_names[obj.__class__] + return type_name + pass + return name_path moff = man_off(0) - queue = [(dexroot, ['DEXFile'])] + queue = [(dexroot, 'DEXFile')] while queue: - obj, path_parts = queue.pop() - name_path = '.'.join(path_parts) + obj, name_path = queue.pop() - obj_clazz = _resolve_name_path(name_path) + obj_clazz, parent_clazz = _resolve_name_path(name_path) if isinstance(obj_clazz, dexfile.depend): + moff(obj_clazz.sizeof(obj)) continue if name_path in depon_dep_map: @@ -802,7 +805,7 @@ pass if isinstance(obj, (tuple, list)): - attrs = [(elt, make_path(elt, path_parts, str(idx))) + attrs = [(elt, make_path(elt, name_path, str(idx))) for idx, elt in enumerate(obj)] attrs.reverse() queue = queue + attrs @@ -816,12 +819,10 @@ moff(clazz.sizeof(obj)) continue - moff(obj.sizeof(obj)) - children = obj.children() attr_n_names = [(_dex_tree_get_child(obj, child_name), child_name) for child_name in children] - attrs = [(attr, make_path(attr, path_parts, attr_name)) + attrs = [(attr, make_path(attr, name_path, attr_name)) for attr, attr_name in attr_n_names] attrs.reverse() queue = queue + attrs diff -r fa8fe7d714b9 -r c2a4921ec83b paraspace/dexfile.py --- a/paraspace/dexfile.py Sat Jun 25 08:16:16 2011 +0800 +++ b/paraspace/dexfile.py Sun Jun 26 21:34:52 2011 +0800 @@ -755,6 +755,18 @@ return v def sizeof(self, v): + from paraspace.dex_deptracker import _resolve_name_path + from paraspace.dex_deptracker import _skip_marker_clazz + + depon_clazz, dummy = _resolve_name_path(self.depend_on) + depon_clazz = _skip_marker_clazz(depon_clazz) + if type(depon_clazz) == type and \ + isinstance(v, depon_clazz): + v = v.data_offset + elif type(depon_clazz) != type and \ + isinstance(v, depon_clazz.__class__): + v = v.data_offset + pass v = self.back_type.sizeof(v) return v @@ -793,6 +805,24 @@ class depend_idx(depend): + def sizeof(self, v): + from paraspace.dex_deptracker import _resolve_name_path + from paraspace.dex_deptracker import _skip_marker_clazz + + depon_clazz, dummy = _resolve_name_path(self.depend_on) + depon_clazz = _skip_marker_clazz(depon_clazz) + do_child_clazz = depon_clazz.child_type # depon_clazz must be an array + + if type(do_child_clazz) == type and \ + isinstance(v, do_child_clazz): + v = v.data_idx + elif type(do_child_clazz) != type and \ + isinstance(v, do_child_clazz.__class__): + v = v.data_idx + pass + v = self.back_type.sizeof(v) + return v + pass pass diff -r fa8fe7d714b9 -r c2a4921ec83b paraspace/tests/dexfile_test.py --- a/paraspace/tests/dexfile_test.py Sat Jun 25 08:16:16 2011 +0800 +++ b/paraspace/tests/dexfile_test.py Sun Jun 26 21:34:52 2011 +0800 @@ -59,6 +59,10 @@ obj, parent = _resolve_name_path('_DEX_AnnotationMember_noname.value.' + repr(key)) assert isinstance(obj, dexfile.abs_value) + + obj, parent = _resolve_name_path('_DEX_AnnotationSetItem.annotationOffs.' + 'items.0') + assert isinstance(obj, dexfile.depend_off) pass @@ -223,6 +227,9 @@ code_item = dex.codeItems.items[0] assert code_item.debugInfoOff.__class__.__name__ == '_DEX_DebugInfoItem' + + stringid = dex.stringIds.items[0] + assert isinstance(stringid.stringDataOff, dexfile._DEX_StringDataItem) pass @@ -288,9 +295,10 @@ offset1 = dex.typeLists.items[1].value.data_offset dex.typeLists.items[1].value.data_offset = 0 + print 'update_offset()' update_offset(dex, all_dep_decls) - print dex.typeLists.items[0].value.data_offset + print dex.typeLists.items[0].value.data_offset, offset0 assert dex.typeLists.items[0].value.data_offset == offset0 assert dex.typeLists.items[1].value.data_offset == offset1 pass