changeset 19:6008b9a9d33e

Declare dependencies for indics for classes in dexfile.py
author Thinker K.F. Li <thinker@codemud.net>
date Wed, 01 Jun 2011 20:48:35 +0800
parents f36b14d1f122
children 265f39947b36
files paraspace/dexfile.py
diffstat 1 files changed, 58 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- 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