Mercurial > paraspace
diff paraspace/dex_deptracker.py @ 132:75a31967ebee
Following the ref in resotre_dependencies()
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Tue, 09 Aug 2011 15:30:45 +0800 |
parents | 52749d91cc22 |
children | ddf8a20ecc4b |
line wrap: on
line diff
--- a/paraspace/dex_deptracker.py Tue Aug 09 11:47:43 2011 +0800 +++ b/paraspace/dex_deptracker.py Tue Aug 09 15:30:45 2011 +0800 @@ -218,6 +218,13 @@ pass +class _travel_rel_node(object): + obj = None + parents = None + name_path = None + origin_path = None + pass + ## \brief Travel the tree of relocatable objects and their attributes. # # \param skip_func is a function that returns true for skip a subtree. @@ -225,13 +232,25 @@ # \ref skip_func is called for every relocatable and their attributes # to determines if visiting the object and subtree. # +# NOTE: +# You never know what information you will use later. Use an object +# instead of tuple to carry information. You can extend states an object +# later. But, it is hard to extend a tuple. That is why _travel_rel_node +# instances are used to replace tuples, here. +# def _travel_dex_relocatable(root_obj, parents=[], skip_func=None): - stk = [(root_obj, parents, root_obj.__class__.__name__)] + root_node = _travel_rel_node() + root_node.obj = root_obj + root_node.parents = parents + root_node.name_path = root_obj.__class__.__name__ + root_node.origin_path = root_obj.__class__.__name__ + stk = [root_node] def make_travel_info(obj, obj_name, child_name, parents): child_parents = parents + [obj] child_obj = _dex_tree_get_child(obj, child_name) child_path = obj_name + '.' + child_name + origin_path = child_path child_clazz, dummy = _resolve_name_path(child_path) if not isinstance(child_clazz, dexfile.depend): @@ -239,13 +258,21 @@ child_path = child_obj.__class__.__name__ pass pass - return (child_obj, child_parents, child_path) + + node = _travel_rel_node() + node.obj = child_obj + node.parents = child_parents + node.name_path = child_path + node.origin_path = origin_path + + return node while stk: - obj, parents, obj_name = stk.pop(0) + node = stk.pop(0) + obj, parents, obj_name = node.obj, node.parents, node.name_path if skip_func and skip_func(obj, parents, obj_name): continue - yield (obj, parents, obj_name) + yield node if isinstance(obj, list): children = [make_travel_info(obj, obj_name, repr(idx), parents) @@ -622,8 +649,10 @@ pass return obj - for obj, parents, name_path in \ - _travel_dex_relocatable(root_obj): + for node in _travel_dex_relocatable(root_obj): + obj = node.obj + parents = node.parents + if isinstance(obj, dexfile._objs_asso): rev_parents = list(parents) rev_parents.reverse() @@ -652,6 +681,11 @@ raise TypeError, 'can not find a prent of %s type' % (repr(clazz)) +## \brief Split a name path into class and attribute parts. +# +# \param name_path is a name path string. +# \return a tuple in pattern (class name, attribute name) +# def _split_name_path_clazz_attr(name_path): idx = name_path.index('.') if idx >= 0: @@ -667,8 +701,10 @@ ## \brief Setup value of refs. # def _build_refs(root_obj): - for obj, parents, name_path in \ - _travel_dex_relocatable(root_obj): + for node in _travel_dex_relocatable(root_obj): + name_path = node.name_path + parents = node.parents + if not parents: continue @@ -710,8 +746,11 @@ # # Collect marked objects # - for obj, parents, name_path in \ - _travel_dex_relocatable(root_obj): + for node in _travel_dex_relocatable(root_obj): + obj = node.obj + parents = node.parents + name_path = node.name_path + if name_path not in markers_info: continue @@ -725,8 +764,10 @@ # # Link depend source to marked target # - for obj, parents, name_path in \ - _travel_dex_relocatable(root_obj): + for node in _travel_dex_relocatable(root_obj): + obj = node.obj + parents = node.parents + name_path = node.name_path if name_path not in all_dep_decls: continue @@ -801,7 +842,8 @@ def dex_sort_sorted_arrays(dex): assert isinstance(dex, dexfile.DEXFile_linked) - for obj, parents, name_path in _travel_dex_relocatable(dex): + for node in _travel_dex_relocatable(dex): + obj = node.obj if isinstance(obj, dexfile.array_sorted): obj.items.sort() pass @@ -973,9 +1015,33 @@ # def restore_dependencies(dexroot, all_dep_decls): update_offset(dexroot, all_dep_decls) + + def set_child(node, value): + vtype, dummy = _resolve_name_path(node.origin_path) + while isinstance(vtype, dexfile.null_relocatable): + vtype = vtype.back_type + pass + + if isinstance(vtype, dexfile.ref): + name_path = vtype.target_path + print 'REF', node.origin_path, name_path, '0x%x' % value + else: + name_path = node.origin_path + pass + + parent_clazzname, attr_name = _split_name_path_clazz_attr(name_path) + parent_clazz, dummy = _resolve_name_path(parent_clazzname) + parent_clazz = _skip_marker_clazz(parent_clazz) + clazz_parent = _find_parent_of_clazz(parent_clazz, node.parents) + + _dex_tree_set_child(clazz_parent, attr_name, value) + pass - for obj, parents, name_path in \ - _travel_dex_relocatable(dexroot): + for node in _travel_dex_relocatable(dexroot): + obj = node.obj + parents = node.parents + name_path = node.name_path + if name_path not in all_dep_decls: continue @@ -989,17 +1055,13 @@ relative_to = _rel_offset_marker.find_depon(dep[2], parents) depon = obj rel_off = depon.data_offset - relative_to.data_offset - - name = name_path.split('.')[-1] - _dex_tree_set_child(imm_parent, name, rel_off) + set_child(node, rel_off) elif dep_type == dexfile.depend_off: depon = obj - name = name_path.split('.')[-1] - _dex_tree_set_child(imm_parent, name, depon.data_offset) + set_child(node, depon.data_offset) elif dep_type == dexfile.depend_idx: depon = obj - name = name_path.split('.')[-1] - _dex_tree_set_child(imm_parent, name, depon.data_idx) + set_child(node, depon.data_idx) else: raise TypeError, 'invalid depend type %s' % (repr(dep_type)) pass