Mercurial > paraspace
diff paraspace/dex_deptracker.py @ 43:5cea19126a11
Fix issue of _build_refs()
- _build_refs() does not handle dexfile.cond well when traveling.
- fix it
- Move from ref.get_value() to ref.set_value().
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Sun, 19 Jun 2011 19:36:36 +0800 |
parents | 8ca4a6bc6b79 |
children | 94e80f7a61b5 |
line wrap: on
line diff
--- a/paraspace/dex_deptracker.py Sun Jun 19 14:26:09 2011 +0800 +++ b/paraspace/dex_deptracker.py Sun Jun 19 19:36:36 2011 +0800 @@ -175,14 +175,30 @@ def _dex_tree_set_child(obj, child_name, value): + child_parts = child_name.split('.') + for child_part in child_parts[:-1]: + if isinstance(obj, list): + idx = int(child_part) + obj = obj[idx] + continue + + if isinstance(obj, dexfile.switch): + assert obj.map[eval(child_part)] == obj.child_type + obj = obj.value + continue + + obj = getattr(obj, child_part) + pass + + last_part = child_parts[-1] if isinstance(obj, list): - idx = int(child_name) + idx = int(last_part) obj[idx] = value elif isinstance(obj, dexfile.switch): - assert obj.map[eval(child_name)] == obj.child_type + assert obj.map[eval(last_part)] == obj.child_type obj.value = value else: - setattr(obj, child_name, value) + setattr(obj, last_part, value) pass pass @@ -530,12 +546,58 @@ pass +## \brief Find a parent that is an instance of given clazz from a list. +# +def _find_parent_of_clazz(clazz, parents): + rev_parents = list(parents) + rev_parents.reverse() + for parent in rev_parents: + if isinstance(parent, clazz): + return parent + pass + raise TypeError, 'can not find a prent of %s type' % (repr(clazz)) + + +def _split_name_path_clazz_attr(name_path): + idx = name_path.index('.') + if idx >= 0: + clazz = name_path[:idx] + attr = name_path[idx + 1:] + else: + clazz = name_path + attr = None + pass + return clazz, attr + + +## \brief Setup value of refs. +# def _build_refs(root_obj): for obj, parents, name_path in \ _travel_dex_relocatable(root_obj): - if not isinstance(obj, dexfile.value_ref): + if not parents: + continue + + imm_parent = parents[-1] + if isinstance(imm_parent, dexfile.cond) and not imm_parent.is_true: continue - obj.set_value(parents) + + clazz, pclazz = _resolve_name_path(name_path) + while isinstance(clazz, dexfile.depend): + clazz = clazz.child_type + pass + + if isinstance(clazz, dexfile.ref): + pclazz_name, attr_name = _split_name_path_clazz_attr(name_path) + if not attr_name: + raise ValueError, \ + 'not attribute name in name path (%s)' % (name_path) + + parent = _find_parent_of_clazz(dexfile.composite, parents) + + value = clazz.get_value(parents) + _dex_tree_set_child(parent, attr_name, value) + pass pass pass @@ -570,7 +632,8 @@ if name_path not in all_dep_decls: continue - if obj is None and isinstance(parents[-1], dexfile.cond): + imm_parent = parents[-1] + if isinstance(imm_parent, dexfile.cond) and not imm_parent.is_true: continue dep = all_dep_decls[name_path] @@ -579,21 +642,18 @@ depon1 = _rel_offset_marker.find_depon(dep[1], parents) depon2 = _rel_offset_marker.find_depon(dep[2], parents) - parent = parents[-1] name = name_path.split('.')[-1] - _dex_tree_set_child(parent, name, (depon1, depon2)) + _dex_tree_set_child(imm_parent, name, (depon1, depon2)) elif dep_type == dexfile.depend_off: depon_name_path = dep[1] depon = markers_info[depon_name_path][obj] - parent = parents[-1] name = name_path.split('.')[-1] - _dex_tree_set_child(parent, name, depon) + _dex_tree_set_child(imm_parent, name, depon) elif dep_type == dexfile.depend_idx: depon_name_path = dep[1] depon = markers_info[depon_name_path][obj] - parent = parents[-1] name = name_path.split('.')[-1] - _dex_tree_set_child(parent, name, depon) + _dex_tree_set_child(imm_parent, name, depon) else: raise TypeError, 'invalid depend type %s' % (repr(dep_type)) pass