Mercurial > paraspace
changeset 141:90690a001172
Fixing back to back association and encoding issue.
- Fix problem of _deoptimize_classdata() and _optimize_classdata()
- They don't deoptimize or optimize field indices for _DEX_ClassData.
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Sun, 14 Aug 2011 21:18:48 +0800 |
parents | d4e794249b0f |
children | 50d09eba5166 |
files | paraspace/dex_deptracker.py paraspace/dexfile.py paraspace/tests/dex_deptracker_test.py paraspace/tests/injection_test.py |
diffstat | 4 files changed, 322 insertions(+), 160 deletions(-) [+] |
line wrap: on
line diff
--- a/paraspace/dex_deptracker.py Thu Aug 11 09:20:46 2011 +0800 +++ b/paraspace/dex_deptracker.py Sun Aug 14 21:18:48 2011 +0800 @@ -162,6 +162,11 @@ elif isinstance(value_type, dexfile.depend_idx): depend_name = value_type.depend_on dep_decls[from_name] = (dexfile.depend_idx, depend_name) + elif isinstance(value_type, dexfile.depend_idx_rel): + depend_name = value_type.depend_on + relative_to = value_type.relative_to + dep_decls[from_name] = (dexfile.depend_idx_rel, depend_name, + relative_to) pass pass pass @@ -364,12 +369,12 @@ return value - def sizeof(self, value): - sz = self.back_type.sizeof(value) + def sizeof(self, value, parents): + sz = self.back_type.sizeof(value, parents) return sz - def compute_size(self, back_obj): - self.back_type.compute_size(back_obj) + def compute_size(self, back_obj, parents): + self.back_type.compute_size(back_obj, parents) pass def to_str(self, back_obj): @@ -588,6 +593,13 @@ _install_idx_marker(name_path) pass pass + elif dep_type == dexfile.depend_idx_rel: + name_path = dep[1] + if name_path not in all_markers: + all_markers.add(name_path) + _install_idx_marker(name_path) + pass + pass else: raise TypeError, 'Invalid type of depend %s' % (repr(dep_type)) pass @@ -643,31 +655,11 @@ def _build_associations(root_obj): - def get_elts(parent, path): - parts = path.split('.') - obj = parent - for part in parts: - obj = _dex_tree_get_child(obj, part) - if isinstance(obj, dexfile.cond) and not obj.is_true: - return () - pass - return 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() - for parent in rev_parents: - if isinstance(parent, dexfile.composite): - break - pass - - left_elts = get_elts(parent, obj.left) - right_elts = get_elts(parent, obj.right) - obj.build_associations(left_elts, right_elts) + parent = _find_parent_of_clazz(dexfile.composite, node.parents) + obj.build_associations(parent) pass pass pass @@ -721,7 +713,7 @@ clazz = clazz.back_type pass - if isinstance(clazz, dexfile.ref): + if isinstance(clazz, dexfile.value_ref): pclazz_name, attr_name = _split_name_path_clazz_attr(name_path) if not attr_name: raise ValueError, \ @@ -791,10 +783,20 @@ _dex_tree_set_child(imm_parent, name, depon1) elif dep_type == dexfile.depend_off: depon_name_path = dep[1] + try: + depon = markers_info[depon_name_path][obj] + except: + print depon_name_path + raise + name = name_path.split('.')[-1] + _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] name = name_path.split('.')[-1] _dex_tree_set_child(imm_parent, name, depon) - elif dep_type == dexfile.depend_idx: + elif dep_type == dexfile.depend_idx_rel: + # Value after _build_associations() depon_name_path = dep[1] depon = markers_info[depon_name_path][obj] name = name_path.split('.')[-1] @@ -815,6 +817,26 @@ # def _deoptimize_classdata(dexroot): for classdata in dexroot.classDatas.items: + fields = classdata.staticFields.items + if len(fields) > 1: + firstfield = fields[0] + lastidx = firstfield.fieldIdx + for field in fields[1:]: + field.fieldIdx = field.fieldIdx + lastidx + lastidx = field.fieldIdx + pass + pass + + fields = classdata.instanceFields.items + if len(fields) > 1: + firstfield = fields[0] + lastidx = firstfield.fieldIdx + for field in fields[1:]: + field.fieldIdx = field.fieldIdx + lastidx + lastidx = field.fieldIdx + pass + pass + methods = classdata.directMethods.items if len(methods) > 1: firstmethod = methods[0] @@ -844,6 +866,28 @@ # def _optimize_classdata(dexroot): for classdata in dexroot.classDatas.items: + fields = classdata.staticFields.items + if len(fields) > 1: + firstfield = fields[0] + lastidx = firstfield.fieldIdx + for field in fields[1:]: + save_idx = field.fieldIdx + field.fieldIdx = field.fieldIdx - lastidx + lastidx = save_idx + pass + pass + + fields = classdata.instanceFields.items + if len(fields) > 1: + firstfield = fields[0] + lastidx = firstfield.fieldIdx + for field in fields[1:]: + save_idx = field.fieldIdx + field.fieldIdx = field.fieldIdx - lastidx + lastidx = save_idx + pass + pass + methods = classdata.directMethods.items if len(methods) > 1: firstmethod = methods[0] @@ -871,9 +915,9 @@ def build_dependencies(dexroot, all_dep_decls): _deoptimize_classdata(dexroot) - _build_associations(dexroot) _build_refs(dexroot) _link_dependencies(dexroot, all_dep_decls) + _build_associations(dexroot) pass @@ -930,6 +974,8 @@ def update_offset(dexroot, all_dep_decls): from paraspace.dexfile import man_off + _build_associations(dexroot) + depon_dep_map = _build_depon_dep_map(all_dep_decls) dex_type_names = _all_dex_type_to_names() @@ -951,13 +997,13 @@ obj_clazz, parent_clazz = _resolve_name_path(name_path) if isinstance(obj_clazz, dexfile.depend): - obj_clazz.compute_size(obj) - moff(obj_clazz.sizeof(obj)) + obj_clazz.compute_size(obj, [grand, parent]) + moff(obj_clazz.sizeof(obj, [grand, parent])) continue if name_path in depon_dep_map: marker, dummy = _resolve_name_path(name_path) - while isinstance(marker, dexfile.ref): + while isinstance(marker, dexfile.value_ref): marker, dummy = _resolve_name_path(marker.target_path) try: obj = obj[0] @@ -984,8 +1030,8 @@ name = name_path.split('.')[-1] _dex_tree_set_child(parent, name, obj) pass - obj_clazz.compute_size(obj) - moff(obj_clazz.sizeof(obj)) + obj_clazz.compute_size(obj, [grand, parent]) + moff(obj_clazz.sizeof(obj, [grand, parent])) continue children = obj.children() @@ -1038,7 +1084,7 @@ pass pass - classdef_raw_size = dexfile.array.sizeof(dex.classDefs) + classdef_raw_size = dexfile.array.sizeof(dex.classDefs, [dex]) header.dataOff = header.classDefsOff + classdef_raw_size header.dataSize = header.fileSize - header.dataOff pass @@ -1052,10 +1098,12 @@ attr_name = dexfile.DEXFile.block_defs[map_item.type] obj = getattr(dex, attr_name) - data_sz = obj.sizeof(obj) + data_sz = obj.sizeof(obj, [dex, dex.maps, dex.maps.items, + dex.maps.items.items]) map_item.offset = moff(data_sz) if attr_name == 'maps': - padding_sz = dexfile.auto_align.sizeof(dex.maps.padding) + padding_sz = dexfile.auto_align.sizeof(dex.maps.padding, + [dex, dex.maps]) map_item.offset = map_item.offset + padding_sz pass @@ -1070,7 +1118,7 @@ def _sync_DEXFile_fields(dex): dex.compute_size() - dex.header.fileSize = dex.sizeof(dex) + dex.header.fileSize = dex.sizeof() _sync_dex_maps(dex) _sync_dex_header(dex) @@ -1130,6 +1178,10 @@ elif dep_type == dexfile.depend_idx: depon = obj set_child(node, depon.data_idx) + elif dep_type == dexfile.depend_idx_rel: + dep, dummy = _resolve_name_path(node.origin_path) + idx = dep.get_value(obj, parents) + set_child(node, idx) else: raise TypeError, 'invalid depend type %s' % (repr(dep_type)) pass
--- a/paraspace/dexfile.py Thu Aug 11 09:20:46 2011 +0800 +++ b/paraspace/dexfile.py Sun Aug 14 21:18:48 2011 +0800 @@ -79,7 +79,15 @@ def _uleb128_sz(v): - return len(_to_uleb128(v)) + if v & ~0x3fff: + if v & 0xf0000000: + return 5 + elif v & 0xfe00000: + return 4 + return 3 + if v & 0x3f80: + return 2 + return 1 def _leb128(data): @@ -107,11 +115,11 @@ return len(_to_leb128(v)) -def _compute_sz(o, _type): +def _compute_sz(o, _type, parents): if hasattr(o, 'compute_size'): - _type.compute_size(o) + _type.compute_size(o, parents) pass - return _type.sizeof(o) + return _type.sizeof(o, parents) class _dex_type(object): @@ -148,11 +156,11 @@ obj.data = data[off:off + obj.data_size] return obj - def compute_size(self, v): + def compute_size(self, v, parents): v.data_size = len(v.data) pass - def sizeof(self, v): + def sizeof(self, v, parents): return v.data_size def to_str(self, v): @@ -180,7 +188,7 @@ return tap() @staticmethod - def sizeof(v): + def sizeof(v, parents): return 0 @staticmethod @@ -196,11 +204,11 @@ return v @staticmethod - def compute_size(v): + def compute_size(v, parents): pass @staticmethod - def sizeof(v): + def sizeof(v, parents): return 4 @staticmethod @@ -217,11 +225,11 @@ return v @staticmethod - def compute_size(v): + def compute_size(v, parents): pass @staticmethod - def sizeof(v): + def sizeof(v, parents): return 2 @staticmethod @@ -237,11 +245,11 @@ return v @staticmethod - def compute_size(v): + def compute_size(v, parents): pass @staticmethod - def sizeof(v): + def sizeof(v, parents): return 1 @staticmethod @@ -257,11 +265,11 @@ return v @staticmethod - def compute_size(v): + def compute_size(v, parents): pass @staticmethod - def sizeof(v): + def sizeof(v, parents): return 4 @staticmethod @@ -278,11 +286,11 @@ return v @staticmethod - def compute_size(v): + def compute_size(v, parents): pass @staticmethod - def sizeof(v): + def sizeof(v, parents): return 2 @staticmethod @@ -298,11 +306,11 @@ return v @staticmethod - def compute_size(v): + def compute_size(v, parents): pass @staticmethod - def sizeof(v): + def sizeof(v, parents): return _uleb128_sz(v) @staticmethod @@ -318,11 +326,11 @@ return v @staticmethod - def compute_size(v): + def compute_size(v, parents): pass @staticmethod - def sizeof(v): + def sizeof(v, parents): return _leb128_sz(v) @staticmethod @@ -347,11 +355,11 @@ return self.recompute_align(off) @staticmethod - def compute_size(v): + def compute_size(v, parents): pass @staticmethod - def sizeof(v): + def sizeof(v, parents): return v @staticmethod @@ -360,12 +368,6 @@ pass -def _get_sz(o): - if isinstance(o, relocatable): - return o.data_size - return o.__class__.sizeof(o) - - ## \biref Associate objects from two set of objects. # class _objs_asso(_dex_type): @@ -380,21 +382,29 @@ # elements. # def _update_refs(self, left_elt, right_elt): - lref = getattr(left_elt, self.left_ref) - if not isinstance(right_elt, lref.target_path): - raise TypeError, 'invalid target_path in left %s' % (repr(le)) + from paraspace.dex_deptracker import _resolve_name_path + from paraspace.dex_deptracker import _dex_tree_set_child + from paraspace.dex_deptracker import _split_name_path_clazz_attr - rref = getattr(right_elt, self.right_ref) - if not isinstance(left_elt, rref.target_path): - raise TypeError, 'invalid target_path in right %s' % (repr(re)) + lref, dummy = _resolve_name_path(self.left_ref) + if not isinstance(lref, ref): + raise TypeError, '%s must be a ref' % (self.left_ref) + rref, dummy = _resolve_name_path(self.right_ref) + if not isinstance(rref, ref): + raise TypeError, '%s must be a ref' % (self.right_ref) - new_lref = ref(lref.target_path) - new_lref.target = right_elt - setattr(left_elt, self.left_ref, new_lref) + clazzname, lattr = _split_name_path_clazz_attr(self.left_ref) + clazzname, rattr = _split_name_path_clazz_attr(self.right_ref) + + if left_elt is not None: + new_lref = lref.build_value_instance(right_elt) + _dex_tree_set_child(left_elt, lattr, new_lref) + pass - new_rref = ref(rref.target_path) - new_rref.target = left_elt - setattr(right_elt, self.right_ref, new_rref) + if right_elt is not None: + new_rref = lref.build_value_instance(left_elt) + _dex_tree_set_child(right_elt, rattr, new_rref) + pass pass ## \brief Assocate elements from left list to a respective right element. @@ -407,14 +417,15 @@ def parse(self, parent, data, off): return self - def sizeof(self, obj): + def sizeof(self, obj, parents): return 0 + @staticmethod def to_str(self): return '' @staticmethod - def compute_size(self): + def compute_size(self, parents): pass def children(self): @@ -439,7 +450,6 @@ # def build_associations(self, parent): from paraspace.dex_deptracker import _dex_tree_get_child - from paraspace.dex_deptracker import _dex_tree_set_child from paraspace.dex_deptracker import _split_name_path_clazz_attr left_attr = _split_name_path_clazz_attr(self.left) @@ -463,8 +473,6 @@ # class back2back(_objs_asso): def __init__(self, left, left_ref, right_ref): - if not isinstance(left, array): - raise TypeError, 'back_type must be an array' self.left = left self.right = left self.left_ref = left_ref @@ -473,7 +481,6 @@ def build_associations(self, parent): from paraspace.dex_deptracker import _dex_tree_get_child - from paraspace.dex_deptracker import _dex_tree_set_child from paraspace.dex_deptracker import _split_name_path_clazz_attr dummy, attr = _split_name_path_clazz_attr(self.left) @@ -481,11 +488,13 @@ if not isinstance(target_array, array): raise TypeError, 'left of %x must be an array' % (repr(self)) - left_ref_attr = _split_name_path_clazz_attr(self.left_ref) - right_ref_attr = _split_name_path_clazz_attr(self.right_ref) - for left, right in map(None, target_array[:-1], target_array[1:]): - _dex_tree_set_child(left, left_ref_attr, right) - _dex_tree_set_child(right, right_ref_attr, left) + items = target_array.items + if len(items) > 0: + self._update_refs(None, items[0]) + self._update_refs(items[-1], None) + for left, right in map(None, items[:-1], items[1:]): + self._update_refs(left, right) + pass pass pass pass @@ -499,13 +508,13 @@ pass @staticmethod - def sizeof(v): + def sizeof(v, parents): return v.data_size def to_str(self): pass - def compute_size(self): + def compute_size(self, parents): pass def children(self): @@ -535,11 +544,11 @@ pass @staticmethod - def sizeof(v): + def sizeof(v, parents): return 0 @staticmethod - def compute_size(self): + def compute_size(self, parents): pass @staticmethod @@ -551,6 +560,12 @@ def children(self): return [] + + ## \brief Build a new instance with target value. + def build_value_instance(self, value): + vref = self.__class__(self.target_path) + vref.target = value + return vref pass @@ -629,19 +644,20 @@ def parse(): item = obj.child_type.parse(parent, data, moff()) - item_sz = obj.child_type.sizeof(item) + item_sz = obj.child_type.sizeof(item, [parent, self, items]) moff(item_sz) return item - items = [parse() for i in range(nitem)] + items = [] + items.extend([parse() for i in range(nitem)]) obj.items = items obj.data_size = moff() - off return obj @staticmethod - def compute_size(self): - sizes = [_compute_sz(item, self.child_type) + def compute_size(self, parents): + sizes = [_compute_sz(item, self.child_type, parents) for item in self.items] size = sum(sizes) self.data_size = size @@ -663,6 +679,13 @@ class array_relative(array): + def parse(self, parent, data, off): + nitem = parent + for name in self.count_name.split('.'): + nitem = getattr(nitem, name) + pass + obj = self.parse_nitem(parent, data, off, nitem) + return obj pass @@ -690,18 +713,19 @@ obj.parse_child(child_name, data, moff()) child = getattr(obj, child_name) child_clazz = getattr(obj.__class__, child_name) - child_sz = child_clazz.sizeof(child) + child_sz = child_clazz.sizeof(child, [parent]) moff(child_sz) pass obj.data_size = moff() - off return obj - def compute_size(self): + def compute_size(self, parents): + child_parents = parents + [self] children = [(getattr(self, child_name), getattr(self.__class__, child_name)) for child_name in self.children()] - child_sizes = [_compute_sz(child, child_type) + child_sizes = [_compute_sz(child, child_type, child_parents) for child, child_type in children] self.data_size = sum(child_sizes) pass @@ -743,20 +767,20 @@ obj = cond(self.condition, self.child_type) obj.value = value - obj.data_size = self.sizeof(obj) + obj.data_size = self.sizeof(obj, [parent]) obj.is_true = is_true return obj - def sizeof(self, v): + def sizeof(self, v, parents): if v.value is None: return 0 - return self.child_type.sizeof(v.value) + return self.child_type.sizeof(v.value, parents) @staticmethod - def compute_size(self): + def compute_size(self, parents): if self.is_true: - self.data_size = _compute_sz(self.value, self.child_type) + self.data_size = _compute_sz(self.value, self.child_type, parents) else: self.data_size = 0 pass @@ -811,17 +835,17 @@ obj = switch(self.selector, self.map) obj.value = value obj.child_type = child_type - obj.data_size = self.sizeof(obj) + obj.data_size = self.sizeof(obj, [parent]) obj._parent = parent return obj @staticmethod - def sizeof(v): - return v.child_type.sizeof(v.value) + def sizeof(v, parents): + return v.child_type.sizeof(v.value, parents) @staticmethod - def compute_size(self): - self.data_size = _compute_sz(self.value, self.child_type) + def compute_size(self, parents): + self.data_size = _compute_sz(self.value, self.child_type, parents) pass @staticmethod @@ -846,10 +870,10 @@ return self.value @staticmethod - def compute_size(v): + def compute_size(v, parents): pass - def sizeof(self, v): + def sizeof(self, v, parents): return 0 @staticmethod @@ -883,7 +907,7 @@ v = self.back_type.parse(parent, data, off) return v - def sizeof(self, v): + def sizeof(self, v, parents): from paraspace.dex_deptracker import _resolve_name_path from paraspace.dex_deptracker import _skip_marker_clazz @@ -896,11 +920,11 @@ isinstance(v, depon_clazz.__class__): v = v.data_offset pass - v = self.back_type.sizeof(v) + v = self.back_type.sizeof(v, parents) return v - def compute_size(self, child): - _compute_sz(child, self.back_type) + def compute_size(self, child, parents): + _compute_sz(child, self.back_type, parents) pass def to_str(self, child): @@ -918,13 +942,13 @@ class depend_off(depend): - def compute_size(self, child): + def compute_size(self, child, parents): pass - def sizeof(self, child): + def sizeof(self, child, parents): if isinstance(child, composite): - return self.back_type.sizeof(child.data_offset) - return self.back_type.sizeof(child) + return self.back_type.sizeof(child.data_offset, parents) + return self.back_type.sizeof(child, parents) pass @@ -941,46 +965,72 @@ v = super(depend_off_rel, self).parse(parent, data, off) return v - def compute_size(self, child): + def compute_size(self, child, parents): pass - def sizeof(self, child): + def sizeof(self, child, parents): if isinstance(child, composite): pivot = self._depon2_log[child] # depon2 off_diff = child.data_offset - pivot.data_offset - return self.back_type.sizeof(off_diff) - return self.back_type.sizeof(child) + return self.back_type.sizeof(off_diff, parents) + return self.back_type.sizeof(child, parents) pass class depend_idx(depend): - def compute_size(self, child): + def compute_size(self, child, parents): pass - def sizeof(self, child): + def sizeof(self, child, parents): if isinstance(child, composite): - return self.back_type.sizeof(child.data_idx) - return self.back_type.sizeof(child) + return self.back_type.sizeof(child.data_idx, parents) + return self.back_type.sizeof(child, parents) pass class depend_idx_rel(depend): + relative_to = None + def __init__(self, relative_to, depend_on): super(depend_idx_rel, self).__init__(depend_on) self.relative_to = relative_to pass - - def compute_size(self, child): + + def compute_size(self, child, parents): pass - def sizeof(self, child): - from paraspace.dex_deptracker import _dex_tree_set_child - - relative = _dex_tree_get_child([child], self.relative_to) + def sizeof(self, child, parents): + value = self.get_value(child, parents) + return self.back_type.sizeof(value, parents) + + def get_value(self, child, parents): + from paraspace.dex_deptracker import _dex_tree_get_child + from paraspace.dex_deptracker import _split_name_path_clazz_attr + from paraspace.dex_deptracker import _find_parent_of_clazz if isinstance(child, composite): - return self.back_type.sizeof(child.data_idx - relative.data_idx) - return self.back_type.sizeof(child - relative) + clazz, attr = _split_name_path_clazz_attr(self.relative_to) + parent = parents[-1] + try: + relative = _dex_tree_get_child(parent, attr) + except: + relative = None + pass + # Following is a workaround for restore_dependencies(). + # It is unncessary if restore_dependencies() construct a + # new tree. + if isinstance(relative, composite): + rel_idx = relative.data_idx + else: + rel_idx = relative + pass + + value = child.data_idx + if relative is not None: + value = value - rel_idx + pass + return value + return child pass @@ -1220,35 +1270,51 @@ class _DEX_Field(composite): - fieldIdx = depend_idx('DEXFile.fieldIds')(uleb128) + fieldIdx = depend_idx_rel('_DEX_Field.prev.target.fieldIdx', + 'DEXFile.fieldIds')(uleb128) accessFlags = uleb128 + prev = ref('_DEX_Field') + next = ref('_DEX_Field') - child_names = 'fieldIdx accessFlags'.split() + child_names = 'fieldIdx accessFlags prev next'.split() pass class _DEX_Method(composite): - methodIdx = depend_idx('DEXFile.methodIds')(uleb128) + methodIdx = depend_idx_rel('_DEX_Method.prev.target.methodIdx', + 'DEXFile.methodIds')(uleb128) accessFlags = uleb128 codeOff = uleb128 codeOffRef = cond((lambda parent, data, off: parent.codeOff), depend_off('_DEX_Code') (value_ref('_DEX_Method.codeOff'))) + prev = ref('_DEX_Method') + next = ref('_DEX_Method') - child_names = 'methodIdx accessFlags codeOff codeOffRef'.split() + child_names = 'methodIdx accessFlags codeOff codeOffRef prev next'.split() pass class _DEX_ClassData(composite): header = _DEX_ClassDataHeader + staticFields_b2b = back2back('_DEX_ClassData.staticFields', + '_DEX_Field.next', '_DEX_Field.prev') staticFields = array_relative('header.staticFieldsSize', _DEX_Field) + instanceFields_b2b = back2back('_DEX_ClassData.instanceFields', + '_DEX_Field.next', '_DEX_Field.prev') instanceFields = array_relative('header.instanceFieldsSize', _DEX_Field) + directMethods_b2b = back2back('_DEX_ClassData.directMethods', + '_DEX_Method.next', '_DEX_Method.prev') directMethods = array_relative('header.directMethodsSize', _DEX_Method) + virtualMethods_b2b = back2back('_DEX_ClassData.virtualMethods', + '_DEX_Method.next', '_DEX_Method.prev') virtualMethods = array_relative('header.virtualMethodsSize', _DEX_Method) child_names = \ 'header ' \ - 'staticFields instanceFields directMethods virtualMethods'.split() + 'staticFields staticFields_b2b instanceFields instanceFields_b2b ' \ + 'directMethods directMethods_b2b ' \ + 'virtualMethods virtualMethods_b2b'.split() pass @@ -1667,7 +1733,7 @@ return self - def compute_size(self): + def compute_size(self, parents): import itertools def compute_opcode_size(code): @@ -1709,7 +1775,7 @@ pass @staticmethod - def sizeof(obj): + def sizeof(obj, parents): return obj.data_size @staticmethod @@ -1803,7 +1869,7 @@ self.data_size = sh + size + 1 return self - def compute_size(self): + def compute_size(self, parents): size = len(self.data) self.size = size size_sz = _uleb128_sz(size) @@ -1936,9 +2002,10 @@ raw = self.to_str() sz = self.header.fileSize - nosum = _DEX_header.magic.sizeof(self.header.magic) + \ - _DEX_header.checksum.sizeof(self.header.checksum) + \ - _DEX_header.signature.sizeof(self.header.signature) + parents = [self] + nosum = _DEX_header.magic.sizeof(self.header.magic, parents) + \ + _DEX_header.checksum.sizeof(self.header.checksum, parents) + \ + _DEX_header.signature.sizeof(self.header.signature, parents) sha = sha1() sha.update(raw[nosum:]) signature = sha.digest() @@ -1950,11 +2017,19 @@ raw = self.to_str() sz = self.header.fileSize - nosum = _DEX_header.magic.sizeof(self.header.magic) + \ - _DEX_header.checksum.sizeof(self.header.checksum) + parents = [self] + nosum = _DEX_header.magic.sizeof(self.header.magic, parents) + \ + _DEX_header.checksum.sizeof(self.header.checksum, parents) checksum = adler32(adler32_init_value, raw, nosum, sz - nosum) self.header.checksum = checksum pass + + def compute_size(self): + super(DEXFile, self).compute_size([None]) + pass + + def sizeof(self): + return super(DEXFile, self).sizeof(self, [None]) pass @@ -2148,6 +2223,11 @@ rtypename2 = DEXFile_linked.get_typeid_name(proto2.returnTypeIdx) if rtypename1 != rtypename2: return False + + if not (proto1.parametersOffRef.is_true or + proto2.parametersOffRef.is_true): + return True + typelist1 = proto1.parametersOffRef.value typelist2 = proto2.parametersOffRef.value if len(typelist1.typeItems.items) != len(typelist2.typeItems.items):
--- a/paraspace/tests/dex_deptracker_test.py Thu Aug 11 09:20:46 2011 +0800 +++ b/paraspace/tests/dex_deptracker_test.py Sun Aug 14 21:18:48 2011 +0800 @@ -51,10 +51,26 @@ offset1 = dex.typeLists.items[1].value.data_offset dex.typeLists.items[1].value.data_offset = 0 + classdata1 = dex.classDatas.items[1] + fields_methods_szs1 = [c.sizeof(c, [None]) + for c in classdata1.staticFields.items + + classdata1.instanceFields.items + + classdata1.directMethods.items + + classdata1.virtualMethods.items] cdoffset0 = dex.classDatas.items[0].data_offset dex.classDatas.items[0].data_offset = 0 cdoffset1 = dex.classDatas.items[1].data_offset dex.classDatas.items[1].data_offset = 0 + cdoffset2 = dex.classDatas.items[2].data_offset + dex.classDatas.items[2].data_offset = 0 + cdoffset4 = dex.classDatas.items[4].data_offset + dex.classDatas.items[4].data_offset = 0 + cdoffset8 = dex.classDatas.items[8].data_offset + dex.classDatas.items[8].data_offset = 0 + cdoffset15 = dex.classDatas.items[15].data_offset + dex.classDatas.items[15].data_offset = 0 + cdoffset30 = dex.classDatas.items[30].data_offset + dex.classDatas.items[30].data_offset = 0 cdoffsetlast = dex.classDatas.items[-1].data_offset dex.classDatas.items[-1].data_offset = 0 @@ -62,10 +78,23 @@ update_offset(dex, all_dep_decls) + classdata1 = dex.classDatas.items[1] + for c1, c2 in map(None, classdata1.staticFields.items + \ + classdata1.instanceFields.items + \ + classdata1.directMethods.items + \ + classdata1.virtualMethods.items, \ + fields_methods_szs1): + assert c1.sizeof(c1, [None]) == c2 + pass assert dex.typeLists.items[0].value.data_offset == offset0 assert dex.typeLists.items[1].value.data_offset == offset1 assert dex.classDatas.items[0].data_offset == cdoffset0 assert dex.classDatas.items[1].data_offset == cdoffset1 + assert dex.classDatas.items[2].data_offset == cdoffset2 + assert dex.classDatas.items[4].data_offset == cdoffset4 + assert dex.classDatas.items[8].data_offset == cdoffset8 + assert dex.classDatas.items[15].data_offset == cdoffset15 + assert dex.classDatas.items[30].data_offset == cdoffset30 assert dex.classDatas.items[-1].data_offset == cdoffsetlast assert dex.typeIds.items[12].data_idx == 12 pass @@ -105,7 +134,7 @@ pass -def sizoef_after_build_dep_test(): +def sizeof_after_build_dep_test(): from paraspace.dex_deptracker import update_offset _install_dexfile_4_deptracker() @@ -120,7 +149,7 @@ hello_dex = dexfile.DEXFile.open(helloworld_path) update_offset(hello_dex, decls) - get_sz = lambda x: x.sizeof(x) + get_sz = lambda x: x.sizeof(x, [hello_dex]) assert get_sz(hello_dex.header) == 112 assert get_sz(hello_dex.stringIds) == 0x168 assert get_sz(hello_dex.typeIds) == (0x250-0x1d8) @@ -137,17 +166,19 @@ assert get_sz(hello_dex.annotationItems) == (0xf82-0xf31) assert get_sz(hello_dex.encodedArrayItems) == (0xf9d-0xf82) assert get_sz(hello_dex.classDatas) == (0x1024-0xf9d-1) - assert hello_dex.maps.sizeof(hello_dex.maps) == 0xd0 + assert hello_dex.maps.sizeof(hello_dex.maps, [hello_dex]) == 0xd0 hello_dex.compute_size() - unlinked_sz = hello_dex.sizeof(hello_dex) + unlinked_sz = hello_dex.sizeof() + unlinked_cdsize = hello_dex.classDatas.sizeof(hello_dex.classDatas, [hello_dex]) assert unlinked_sz == hello_dex.header.fileSize hello_linked = dexfile.DEXFile_linked.build_dependencies(hello_dex, decls) hello_linked.compute_size() - linked_sz = hello_linked.sizeof(hello_linked) + linked_sz = hello_linked.sizeof() + get_sz = lambda x: x.sizeof(x, [hello_linked]) assert get_sz(hello_linked.header) == 112 assert get_sz(hello_linked.stringIds) == 0x168 assert get_sz(hello_linked.typeIds) == (0x250-0x1d8) @@ -164,6 +195,9 @@ assert get_sz(hello_linked.annotationItems) == (0xf82-0xf31) assert get_sz(hello_linked.encodedArrayItems) == (0xf9d-0xf82) + linked_cdsize = hello_linked.classDatas.sizeof(hello_linked.classDatas, + [hello_linked]) + assert linked_cdsize == unlinked_cdsize # test for depend_idx_rel assert linked_sz == unlinked_sz first_strid = hello_linked.stringIds.items[0] @@ -172,7 +206,7 @@ hello_linked.stringIds.items.append(strid) hello_linked.compute_size() - linked_sz = hello_linked.sizeof(hello_linked) + linked_sz = hello_linked.sizeof() assert get_sz(hello_linked.header) == 112 assert get_sz(hello_linked.stringIds) == 0x16c
--- a/paraspace/tests/injection_test.py Thu Aug 11 09:20:46 2011 +0800 +++ b/paraspace/tests/injection_test.py Sun Aug 14 21:18:48 2011 +0800 @@ -656,7 +656,6 @@ method = hello_linked.find_method_idx(methodidx) blk = dexfile.DEXFile_linked.get_code_block_method(method) opvectors = decode_insn_blk(blk) - print opvectors pass pass @@ -696,14 +695,11 @@ elif methodname == 'write_file': assert methodid in hello_linked.methodIds.items methodidx = hello_linked.get_idx_methodid(methodid) - print dexfile.DEXFile_linked.get_typeid_name(methodid.classIdx) method = hello_linked.find_method_idx(methodidx) blk = dexfile.DEXFile_linked.get_code_block_method(method) opvectors = decode_insn_blk(blk) - print opvectors pass pass - assert False pass