# HG changeset patch # User Thinker K.F. Li # Date 1312628955 -28800 # Node ID 78357afb4a9ddd74df5758a5fabaf6a0454fc5df # Parent 6e4b6414789bcf8e5b73d1461eb41ca619cc3018 Test case for restore_dependencies() diff -r 6e4b6414789b -r 78357afb4a9d paraspace/dex_deptracker.py --- a/paraspace/dex_deptracker.py Sat Aug 06 19:07:20 2011 +0800 +++ b/paraspace/dex_deptracker.py Sat Aug 06 19:09:15 2011 +0800 @@ -777,6 +777,13 @@ return depon_dep_map +## \brief Update offset for all relocatable of a DEXFile. +# +# Update offset of instances of \ref _dex_type. +# +# \param dexroot is a linked (called build_dependencies()) \ref DEXFile. +# \param all_dep_decls is a dictionary returned by prepare_dep_decls(). +# def update_offset(dexroot, all_dep_decls): from dexfile import man_off @@ -794,10 +801,10 @@ return name_path moff = man_off(0) - queue = [(dexroot, 'DEXFile')] + queue = [(dexroot, 'DEXFile', None)] while queue: - obj, name_path = queue.pop() + obj, name_path, parent = queue.pop() obj_clazz, parent_clazz = _resolve_name_path(name_path) if isinstance(obj_clazz, dexfile.depend): @@ -818,7 +825,7 @@ pass if isinstance(obj, (tuple, list)): - attrs = [(elt, make_path(elt, name_path, str(idx))) + attrs = [(elt, make_path(elt, name_path, str(idx)), obj) for idx, elt in enumerate(obj)] attrs.reverse() queue = queue + attrs @@ -828,14 +835,19 @@ continue if not isinstance(obj, dexfile.relocatable): - clazz, parent = _resolve_name_path(name_path) - moff(clazz.sizeof(obj)) + #if isinstance(obj_clazz, dexfile.auto_align): + # obj = obj_clazz.recompute_align(moff()) + # print '%s %x %d' % (name_path, moff(), obj) + # name = name_path.split('.')[-1] + # _dex_tree_set_child(parent, name, obj) + # pass + moff(obj_clazz.sizeof(obj)) continue 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, name_path, attr_name)) + attrs = [(attr, make_path(attr, name_path, attr_name), obj) for attr, attr_name in attr_n_names] attrs.reverse() queue = queue + attrs @@ -844,6 +856,8 @@ def _sync_dex_header(dex): + from paraspace.dexfile import auto_align + header = dex.header map_items = dex.maps.items.items for map_item in map_items: @@ -896,10 +910,15 @@ data_sz = obj.sizeof(obj) map_item.offset = moff(data_sz) + if attr_name == 'maps': + padding_sz = dexfile.auto_align.sizeof(dex.maps.padding) + map_item.offset = map_item.offset + padding_sz + pass + if attr_name not in ('maps', 'header'): map_item.size = len(obj.items) else: - map_item.size = obj.sizeof(obj) + map_item.size = 1 pass pass pass @@ -917,6 +936,8 @@ ## \brief Restore to raw value before linking for dependencies. # def restore_dependencies(dexroot, all_dep_decls): + update_offset(dexroot, all_dep_decls) + for obj, parents, name_path in \ _travel_dex_relocatable(dexroot): if name_path not in all_dep_decls: diff -r 6e4b6414789b -r 78357afb4a9d paraspace/dexfile.py --- a/paraspace/dexfile.py Sat Aug 06 19:07:20 2011 +0800 +++ b/paraspace/dexfile.py Sat Aug 06 19:09:15 2011 +0800 @@ -305,11 +305,14 @@ def __init__(self, bits): self.bits = bits pass - - def parse(self, parent, data, off): + + def recompute_align(self, off): mask = (1 << self.bits) - 1 padding_sz = ((off + mask) & ~mask) - off return padding_sz + + def parse(self, parent, data, off): + return self.recompute_align(off) @staticmethod def sizeof(v): @@ -891,10 +894,11 @@ class _DEX_MapItemBlock(composite): + padding = auto_align(2) num = uint32 items = array('num', _DEX_MapItem) - child_names = 'num items'.split() + child_names = 'padding num items'.split() pass diff -r 6e4b6414789b -r 78357afb4a9d paraspace/tests/dex_deptracker_test.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paraspace/tests/dex_deptracker_test.py Sat Aug 06 19:09:15 2011 +0800 @@ -0,0 +1,46 @@ +from paraspace.dexfile import DEXFile, DEXFile_linked +from paraspace.dex_deptracker import prepare_dep_decls +from paraspace.dex_deptracker import restore_dependencies +import os + +def restore_dependencies_test(): + from paraspace.dexfile import _DEX_StringId + + srcdir = os.path.dirname(__file__) + srcroot = os.path.join(srcdir, '..', '..') + datadir = os.path.join(srcroot, 'data') + helloworld_path = os.path.join(datadir, 'helloworld.dex') + + decls = prepare_dep_decls() + + hello_dex = DEXFile.open(helloworld_path) + strids_size_saved = hello_dex.header.stringIdsSize + typeids_off_saved = hello_dex.header.typeIdsOff + data_off_saved = hello_dex.header.dataOff + map_off_saved = hello_dex.header.mapOff + file_sz_saved = hello_dex.header.fileSize + for map_item in hello_dex.maps.items.items: + print '%d %x' % (map_item.type, map_item.offset) + pass + + hello_linked = DEXFile_linked.build_dependencies(hello_dex, decls) + + first_strid = hello_linked.stringIds.items[0] + strid = _DEX_StringId() + strid.stringDataOff = first_strid.stringDataOff + hello_linked.stringIds.items.append(strid) + + restore_dependencies(hello_linked, decls) + + print file_sz_saved, hello_linked.header.fileSize + print map_off_saved, hello_linked.header.mapOff + for map_item in hello_linked.maps.items.items: + print '%d %x' % (map_item.type, map_item.offset) + pass + + assert hello_linked.header.fileSize == (file_sz_saved + 4) + assert hello_linked.header.stringIdsSize == (strids_size_saved + 1) + assert hello_linked.header.typeIdsOff == (typeids_off_saved + 4) + assert hello_linked.header.dataOff == (data_off_saved + 4) + assert hello_linked.header.mapOff == (map_off_saved + 4) + pass