# HG changeset patch # User Thinker K.F. Li # Date 1306932515 -28800 # Node ID 6008b9a9d33ec375e3f1844af86c2b5456a97e89 # Parent f36b14d1f1222374f3cc54fb288b4cbf7566a38f Declare dependencies for indics for classes in dexfile.py diff -r f36b14d1f122 -r 6008b9a9d33e paraspace/dexfile.py --- a/paraspace/dexfile.py Wed Jun 01 17:51:24 2011 +0800 +++ b/paraspace/dexfile.py Wed Jun 01 20:48:35 2011 +0800 @@ -600,6 +600,10 @@ pass +class depend_idx(depend): + pass + + class _DEX_header(composite): magic = rawstr(8) checksum = uint32 @@ -682,15 +686,15 @@ class _DEX_TypeId(composite): - descriptorIdx = uint32 + descriptorIdx = depend_idx('DEXFile.stringIds')(uint32) child_names = ('descriptorIdx',) pass class _DEX_ProtoId(composite): - shortyIdx = uint32 - returnTypeIdx = uint32 + shortyIdx = depend_idx('DEXFile.stringIds')(uint32) + returnTypeIdx = depend_idx('DEXFile.typeIds')(uint32) parametersOff = depend_off('_DEX_TypeList')(uint32) child_names = 'shortyIdx returnTypeIdx parametersOff'.split() @@ -698,29 +702,29 @@ class _DEX_FieldId(composite): - classIdx = uint16 - typeIdx = uint16 - nameIdx = uint32 + classIdx = depend_idx('DEXFile.typeIds')(uint16) + typeIdx = depend_idx('DEXFile.typeIds')(uint16) + nameIdx = depend_idx('DEXFile.stringIds')(uint32) child_names = 'classIdx typeIdx nameIdx'.split() pass class _DEX_MethodId(composite): - classIdx = uint16 - protoIdx = uint16 - nameIdx = uint32 + classIdx = depend_idx('DEXFile.typeIds')(uint16) + protoIdx = depend_idx('DEXFile.protoIds')(uint16) + nameIdx = depend_idx('DEXFile.stringIds')(uint32) child_names = 'classIdx protoIdx nameIdx'.split() pass class _DEX_ClassDef(composite): - classIdx = uint32 + classIdx = depend_idx('DEXFile.typeIds')(uint32) accessFlags = uint32 - superclassIdx = uint32 + superclassIdx = depend_idx('DEXFile.typeIds')(uint32) interfacesOff = depend_off('_DEX_TypeList')(uint32) - sourceFileIdx = uint32 + sourceFileIdx = depend_idx('DEXFile.stringIds')(uint32) annotationsOff = depend_off('_DEX_AnnotationsDirectoryItem')(uint32) classDataOff = uint32 staticValuesOff = depend_off('_DEX_EncodedArrayItem')(uint32) @@ -744,7 +748,7 @@ class _DEX_Field(composite): - fieldIdx = uleb128 + fieldIdx = depend_idx('DEXFile.fieldIds')(uleb128) accessFlags = uleb128 child_names = 'fieldIdx accessFlags'.split() @@ -752,7 +756,7 @@ class _DEX_Method(composite): - methodIdx = uleb128 + methodIdx = depend_idx('DEXFile.methodIds')(uleb128) accessFlags = uleb128 codeOff = depend_off('_DEX_Code')(uleb128) @@ -793,7 +797,7 @@ class _DEX_CatchHandler(composite): - typeIdx = uleb128 + typeIdx = depend_idx('DEXFile.typeIds')(uleb128) address = uleb128 child_names = 'typeIdx address'.split() @@ -864,7 +868,7 @@ class _DEX_FieldAnnotationsItem(composite): - fieldIdx = uint32 + fieldIdx = depend_idx('DEXFile.fieldIds')(uint32) annotationsOff = depend_off('_DEX_AnnotationSetItem')(uint32) child_names = 'fieldIdx annotationsOff'.split() @@ -872,7 +876,7 @@ class _DEX_MethodAnnotationsItem(composite): - methodIdx = uint32 + methodIdx = depend_idx('DEXFile.methodIds')(uint32) annotationsOff = depend_off('_DEX_AnnotationSetItem')(uint32) child_names = 'methodIdx annotationsOff'.split() @@ -880,7 +884,7 @@ class _DEX_ParameterAnnotationsItem(composite): - methodIdx = uint32 + methodIdx = depend_idx('DEXFile.methodIds')(uint32) annotationsOff = depend_off('_DEX_AnnotationSetItem')(uint32) child_names = 'methodIdx annotationsOff'.split() @@ -916,7 +920,7 @@ # # \see createAnnotationMember() in dalvik/vm/reflect/Annotation.c # -class _DEX_AnnotationMember(composite): +class _DEX_AnnotationMember_noname(composite): # # Constants from DexFile.h # @@ -940,7 +944,6 @@ kDexAnnotationValueTypeMask = 0x1f kDexAnnotationValueArgShift = 5 - nameIdx = uleb128 valueType = uint8 value_map = { kDexAnnotationByte: rawstr_size_name('value_width'), @@ -962,7 +965,7 @@ } value = switch('vtype', value_map) - child_names = 'nameIdx valueType value'.split() + child_names = 'valueType value'.split() @property def vtype(self): @@ -981,8 +984,10 @@ pass -class _DEX_AnnotationMember_noname(_DEX_AnnotationMember): - child_names = 'valueType value'.split() +class _DEX_AnnotationMember(_DEX_AnnotationMember_noname): + nameIdx = depend_idx('DEXFile.stringIds')(uleb128) + + child_names = 'nameIdx valueType value'.split() pass @@ -993,13 +998,12 @@ # # \see processEncodedAnnotation() in dalvik/vm/reflect/Annotation.c # -class _DEX_AnnotationItem(composite): - visibility = uint8 - typeIdx = uleb128 +class _DEX_AnnotationItem_novisibility(composite): + typeIdx = depend_idx('DEXFile.typeIds')(uleb128) size = uleb128 members = array('size', _DEX_AnnotationMember) - child_names = 'visibility typeIdx size members'.split() + child_names = 'typeIdx size members'.split() kDexVisibilityBuild = 0x00 kDexVisibilityRuntime = 0x01 @@ -1007,8 +1011,10 @@ pass -class _DEX_AnnotationItem_novisibility(_DEX_AnnotationItem): - child_names = 'typeIdx size members'.split() +class _DEX_AnnotationItem(_DEX_AnnotationItem_novisibility): + visibility = uint8 + + child_names = 'visibility typeIdx size members'.split() pass @@ -1347,11 +1353,14 @@ _nest_types = (array, cond, switch) -def _dig_clazz(clazz_name, clazz, population): +def _dig_clazz(name_path, clazz, population): deps = {} for attr in dir(clazz): - namelist = [clazz_name, attr] + namelist = [name_path, attr] + + digged_flag = False + value_type = getattr(clazz, attr) while isinstance(value_type, _nest_types) or \ (type(value_type) == type and @@ -1363,10 +1372,20 @@ namelist.append('value') value_type = value_type.child_type elif isinstance(value_type, switch): - namelist.append('value') - value_type = value_type.child_type - pass + for key, child_type in value_type.map.items(): + if child_type in population.values(): + continue + child_name_path = '.'.join(namelist) + '.' + repr(key) + child_deps = \ + _dig_clazz(child_name_path, child_type, population) + deps.update(child_deps) + pass + digged_flag = True + break pass + + if digged_flag: + continue if isinstance(value_type, depend): from_name = '.'.join(namelist) @@ -1377,6 +1396,9 @@ depend_name = value_type.depend_on relative_to = value_type.relative_to deps[from_name] = (depend_off_rel, depend_name, relative_to) + elif isinstance(value_type, depend_idx): + depend_name = value_type.depend_on + deps[from_name] = (depend_idx, depend_name) pass pass pass @@ -1388,8 +1410,8 @@ if name.startswith('_DEX_')]) all_deps = {} - for clazz_name, clazz in population.items(): - deps = _dig_clazz(clazz_name, clazz, population) + for name_path, clazz in population.items(): + deps = _dig_clazz(name_path, clazz, population) all_deps.update(deps) pass