首页 > 代码库 > apktool分析odex不能合并原因分析
apktool分析odex不能合并原因分析
华为hornor的apach-xml.odex不能合并
错误信息
Error occurred while disassembling classLorg.apache.xalan.templates.ElemNumber; - skipping class
java.lang.RuntimeException: Invalid methodindex: 32
atorg.jf.dexlib2.analysis.InlineMethodResolver$InlineMethodResolver_version36.resolveExecuteInline(InlineMethodResolver.java:175)
atorg.jf.dexlib2.analysis.MethodAnalyzer.analyzeExecuteInlineRange(MethodAnalyzer.java:1448)
atorg.jf.dexlib2.analysis.MethodAnalyzer.analyzeInstruction(MethodAnalyzer.java:944)
atorg.jf.dexlib2.analysis.MethodAnalyzer.analyze(MethodAnalyzer.java:202)
atorg.jf.dexlib2.analysis.MethodAnalyzer.<init>(MethodAnalyzer.java:137)
atorg.jf.baksmali.Adaptors.MethodDefinition.addAnalyzedInstructionMethodItems(MethodDefinition.java:403)
atorg.jf.baksmali.Adaptors.MethodDefinition.getMethodItems(MethodDefinition.java:312)
atorg.jf.baksmali.Adaptors.MethodDefinition.writeTo(MethodDefinition.java:209)
atorg.jf.baksmali.Adaptors.ClassDefinition.writeVirtualMethods(ClassDefinition.java:332)
atorg.jf.baksmali.Adaptors.ClassDefinition.writeTo(ClassDefinition.java:113)
atorg.jf.baksmali.baksmali.disassembleClass(baksmali.java:230)
atorg.jf.baksmali.baksmali.disassembleDexFile(baksmali.java:148)
atorg.jf.baksmali.main.main(main.java:285)
通过跟踪bakmali
发现是odex优化有的inline method有问题, 如下高亮的odex指令转化成dex指令出错, 对应的代码是:
./xalan/templates/ElemNumber.java
String getCountString(TransformerImpl transformer, intsourceNode)
throws TransformerException
{
double d_count =java.lang.Math.floor(countObj.num()+ 0.5);
CODE:0003F930 #============================================================================
CODE:0003F930 # Method 1222 (0x4c6)
CODE:0003F930 word_3F930: .short 0x16 # DATA XREF: CODE:00121958i
CODE:0003F930 #Number of registers : 0x16
CODE:0003F932 .short 3 # Size of input args (in words): 0x3
CODE:0003F934 .short 4 # Size of output args (inwords) : 0x4
CODE:0003F936 .short 0 # Number of try_items : 0x0
CODE:0003F938 .int word_101B0E # Debug info
CODE:0003F93C .int 0xC3 # Size of bytecode (in 16-bitunits): 0xc3
CODE:0003F940 # Source file: ElemNumber.java
CODE:0003F940 java.lang.Stringorg.apache.xalan.templates.ElemNumber.getCountString(
CODE:0003F940 org.apache.xalan.transformer.TransformerImpltransformer,
CODE:0003F940 int sourceNode)
CODE:0003F940 this = v19
CODE:0003F940 transformer = v20
CODE:0003F940 sourceNode = v21
CODE:0003F940 .prologue_end
CODE:0003F940 .line 791
CODE:0003F940
CODE:0003F940 const/4 v12, 0
CODE:0003F942 .local name:‘list‘ type:‘[J‘
CODE:0003F942 list = v12
CODE:0003F942 .line 792
CODE:0003F942
CODE:0003F942 +invoke-virtual-quick/range {transformer..transformer}, [0047]
CODE:0003F948 move-result-object v14
CODE:0003F94A .local name:‘xctxt‘type:‘Lorg/apache/xpath/XPathContext;‘
CODE:0003F94A xctxt = v14
CODE:0003F94A .line 793
CODE:0003F94A
CODE:0003F94A +invoke-virtual-quick/range {transformer..transformer}, [002b]
CODE:0003F950 move-result-object v7
CODE:0003F952 .local name:‘ctable‘type:‘Lorg/apache/xalan/transformer/CountersTable;‘
CODE:0003F952 ctable = v7
CODE:0003F952 .line 795
CODE:0003F952
CODE:0003F952 move-object/from16 v0, this
CODE:0003F956 +iget-object-quick v15, v0, [obj+0074]
CODE:0003F95A if-eqz v15, loc_3FA0A
CODE:0003F95E .line 797
CODE:0003F95E
CODE:0003F95E move-object/from16 v0, this
CODE:0003F962 +iget-object-quick v15, v0, [obj+0074]
CODE:0003F966 move/from16 v0, sourceNode
CODE:0003F96A move-object/from16 v1, this
CODE:0003F96E +invoke-virtual-quick {v15, xctxt, v0, v1}, [000f]
CODE:0003F974 move-result-object v6
CODE:0003F976 .local name:‘countObj‘type:‘Lorg/apache/xpath/objects/XObject;‘
CODE:0003F976 countObj = v6
CODE:0003F976 .line 799
CODE:0003F976
CODE:0003F976 +invoke-virtual-quick {countObj}, [0041]
CODE:0003F97C move-result-wide v15:v16
CODE:0003F97E const-wide/high16 v17:v18, 0x3FE0000000000000
CODE:0003F982 add-double v15:v16, v15:v16, v17:v18
CODE:0003F986 +execute-inline/range {v15..v16}, [0020]
CODE:0003F98C move-result-wide v8:v9
CODE:0003F98E .local name:‘d_count‘ type:‘D‘
看baksmali代码,inlinemethod在baksmali实现,没有 java.lang.Math.floor:
由此,猜测,华为dex optimize时的inline method比这个多,所以只要在这个中加入华为的inline method,合并就可成功。
private static class InlineMethodResolver_version36extends InlineMethodResolver
{
private final Method[] inlineMethods;
private final Method indexOfIMethod;
private final Method indexOfIIMethod;
private final Method fastIndexOfMethod;
private final Method isEmptyMethod;
publicInlineMethodResolver_version36() {
//The 5th and 6th entries differbetweenfroyo and gingerbread. We have to look at the parameters being
//passed to distinguish betweenthem.
//froyo
indexOfIMethod = inlineMethod(VIRTUAL, "Ljava/lang/String;", "indexOf", "I", "I");
indexOfIIMethod = inlineMethod(VIRTUAL, "Ljava/lang/String;", "indexOf", "II", "I");
//gingerbread
fastIndexOfMethod =inlineMethod(DIRECT, "Ljava/lang/String;", "fastIndexOf", "II", "I");
isEmptyMethod = inlineMethod(VIRTUAL, "Ljava/lang/String;", "isEmpty", "", "Z");
inlineMethods = new Method[] {
inlineMethod(STATIC,"Lorg/apache/harmony/dalvik/NativeTestTarget;","emptyInlineMethod", "", "V"),
inlineMethod(VIRTUAL,"Ljava/lang/String;", "charAt", "I", "C"),
inlineMethod(VIRTUAL,"Ljava/lang/String;", "compareTo", "Ljava/lang/String;", "I"),
inlineMethod(VIRTUAL,"Ljava/lang/String;", "equals", "Ljava/lang/Object;", "Z"),
//froyo: deodexUtil.newInlineMethod(VIRTUAL, "Ljava/lang/String;","indexOf", "I", "I"),
//gingerbread: deodexUtil.newInlineMethod(VIRTUAL, "Ljava/lang/String;","fastIndexOf", "II", "I"),
null,
//froyo: deodexUtil.newInlineMethod(VIRTUAL, "Ljava/lang/String;","indexOf", "II", "I"),
//gingerbread: deodexUtil.newInlineMethod(VIRTUAL, "Ljava/lang/String;","isEmpty", "", "Z"),
null,
inlineMethod(VIRTUAL,"Ljava/lang/String;", "length", "", "I"),
inlineMethod(STATIC,"Ljava/lang/Math;", "abs", "I", "I"),
inlineMethod(STATIC,"Ljava/lang/Math;", "abs", "J", "J"),
inlineMethod(STATIC,"Ljava/lang/Math;", "abs", "F", "F"),
inlineMethod(STATIC,"Ljava/lang/Math;", "abs", "D", "D"),
inlineMethod(STATIC,"Ljava/lang/Math;", "min", "II", "I"),
inlineMethod(STATIC,"Ljava/lang/Math;", "max", "II", "I"),
inlineMethod(STATIC,"Ljava/lang/Math;", "sqrt", "D", "D"),
inlineMethod(STATIC,"Ljava/lang/Math;", "cos", "D", "D"),
inlineMethod(STATIC,"Ljava/lang/Math;", "sin", "D", "D"),
inlineMethod(STATIC,"Ljava/lang/Float;", "floatToIntBits", "F", "I"),
inlineMethod(STATIC,"Ljava/lang/Float;", "floatToRawIntBits", "F", "I"),
inlineMethod(STATIC,"Ljava/lang/Float;", "intBitsToFloat", "I", "F"),
inlineMethod(STATIC,"Ljava/lang/Double;", "doubleToLongBits", "D", "J"),
inlineMethod(STATIC,"Ljava/lang/Double;", "doubleToRawLongBits", "D", "J"),
inlineMethod(STATIC,"Ljava/lang/Double;", "longBitsToDouble", "J", "D"),
inlineMethod(STATIC,"Ljava/lang/StrictMath;", "abs", "I", "I"),
inlineMethod(STATIC,"Ljava/lang/StrictMath;", "abs", "J", "J"),
inlineMethod(STATIC,"Ljava/lang/StrictMath;", "abs", "F", "F"),
inlineMethod(STATIC,"Ljava/lang/StrictMath;", "abs", "D", "D"),
inlineMethod(STATIC,"Ljava/lang/StrictMath;", "min", "II", "I"),
inlineMethod(STATIC,"Ljava/lang/StrictMath;", "max", "II", "I"),
inlineMethod(STATIC,"Ljava/lang/StrictMath;", "sqrt", "D", "D"),
};
}
dalvik中对应的表在,因此,我们可以在华为的虚拟机中找到这个完整的表,
./vm/InlineNative.cpp
730 const InlineOperationgDvmInlineOpsTable[] = {
731 { org_apache_harmony_dalvik_NativeTestTarget_emptyInlineMethod,
732 "Lorg/apache/harmony/dalvik/NativeTestTarget;",
733 "emptyInlineMethod", "()V" },
734
735 {javaLangString_charAt, "Ljava/lang/String;", "charAt","(I)C" },
736 { javaLangString_compareTo,"Ljava/lang/String;", "compareTo","(Ljava/lang/String;)I" },
737 {javaLangString_equals, "Ljava/lang/String;", "equals","(Ljava/lang/Object;)Z" },
738 {javaLangString_fastIndexOf_II, "Ljava/lang/String;", "fastIndexOf","(II)I" },
739 {javaLangString_isEmpty, "Ljava/lang/String;", "isEmpty","()Z" },
740 {javaLangString_length, "Ljava/lang/String;", "length","()I" },
741
742 {javaLangMath_abs_int, "Ljava/lang/Math;", "abs","(I)I" },
743 { javaLangMath_abs_long,"Ljava/lang/Math;", "abs", "(J)J" },
744 {javaLangMath_abs_float, "Ljava/lang/Math;", "abs","(F)F" },
745 {javaLangMath_abs_double, "Ljava/lang/Math;", "abs","(D)D" },
746 {javaLangMath_min_int, "Ljava/lang/Math;", "min","(II)I" },
747 {javaLangMath_max_int, "Ljava/lang/Math;", "max","(II)I" },
748 {javaLangMath_sqrt, "Ljava/lang/Math;", "sqrt","(D)D" },
749 {javaLangMath_cos, "Ljava/lang/Math;", "cos","(D)D" },
750 {javaLangMath_sin, "Ljava/lang/Math;", "sin","(D)D" },
751
752 {javaLangFloat_floatToIntBits, "Ljava/lang/Float;","floatToIntBits", "(F)I" },
753 {javaLangFloat_floatToRawIntBits, "Ljava/lang/Float;","floatToRawIntBits", "(F)I" },
754 {javaLangFloat_intBitsToFloat, "Ljava/lang/Float;","intBitsToFloat", "(I)F" },
755
756 {javaLangDouble_doubleToLongBits, "Ljava/lang/Double;","doubleToLongBits", "(D)J" },
757 {javaLangDouble_doubleToRawLongBits, "Ljava/lang/Double;","doubleToRawLongBits", "(D)J" },
758 {javaLangDouble_longBitsToDouble, "Ljava/lang/Double;","longBitsToDouble", "(J)D" },
759
760 // Theseare implemented exactly the same in Math and StrictMath,
761 // so wecan make the StrictMath calls fast too. Note that this
762 // isn‘ttrue in general!
763 {javaLangMath_abs_int, "Ljava/lang/StrictMath;", "abs","(I)I" },
764 {javaLangMath_abs_long, "Ljava/lang/StrictMath;", "abs","(J)J" },
765 {javaLangMath_abs_float, "Ljava/lang/StrictMath;", "abs","(F)F" },
766 {javaLangMath_abs_double, "Ljava/lang/StrictMath;", "abs","(D)D" },
767 {javaLangMath_min_int, "Ljava/lang/StrictMath;", "min","(II)I" },
768 {javaLangMath_max_int, "Ljava/lang/StrictMath;", "max","(II)I" },
769 {javaLangMath_sqrt, "Ljava/lang/StrictMath;", "sqrt","(D)D" },
770 };
797 const InlineOperation* dvmGetInlineOpsTable()
798 {
799 returngDvmInlineOpsTable;
800 }
用IDA反汇编libdvm.so得到这个表, 黄色为增加的:
.data.rel.ro:000AD3BC dvmCompilerTemplateEnd DCDsub_2940C ; DATA XREF: .text:00023934o
.data.rel.ro:000AD3BC ;.text:off_23994o ...
.data.rel.ro:000AD3BC ;Alternative name is ‘dvmCompilerTemplateEnd‘
.data.rel.ro:000AD3BC ; gDvmInlineOpsTable
.data.rel.ro:000AD3C0 DCD aLorgApacheHa_4 ;"Lorg/apache/harmony/dalvik/NativeTestTa"...
.data.rel.ro:000AD3C4 DCD aEmptyinlinemet ; "emptyInlineMethod"
.data.rel.ro:000AD3C8 DCD aV_1 ; "()V"
.data.rel.ro:000AD3CC DCD_Z21javaLangString_charAtjjjjP6JValue ;javaLangString_charAt(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD3D0 DCD aLjavaLangSt_21 ; "Ljava/lang/String;"
.data.rel.ro:000AD3D4 DCD aCharat_0 ; "charAt"
.data.rel.ro:000AD3D8 DCD aIC_0 ; "(I)C"
.data.rel.ro:000AD3DC DCD_Z24javaLangString_compareTojjjjP6JValue ; javaLangString_compareTo(uint,uint,uint,uint,JValue*)
.data.rel.ro:000AD3E0 DCD aLjavaLangSt_21 ; "Ljava/lang/String;"
.data.rel.ro:000AD3E4 DCD aCompareto_0 ; "compareTo"
.data.rel.ro:000AD3E8 DCD aLjavaLangSt_22 ; "(Ljava/lang/String;)I"
.data.rel.ro:000AD3EC DCD_Z21javaLangString_equalsjjjjP6JValue ;javaLangString_equals(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD3F0 DCD aLjavaLangSt_21 ; "Ljava/lang/String;"
.data.rel.ro:000AD3F4 DCD aEquals_0 ; "equals"
.data.rel.ro:000AD3F8 DCD aLjavaLangOb_40 ; "(Ljava/lang/Object;)Z"
.data.rel.ro:000AD3FC DCD_Z29javaLangString_fastIndexOf_IIjjjjP6JValue ; javaLangString_fastIndexOf_II(uint,uint,uint,uint,JValue*)
.data.rel.ro:000AD400 DCD aLjavaLangSt_21 ; "Ljava/lang/String;"
.data.rel.ro:000AD404 DCD aFastindexof_0 ; "fastIndexOf"
.data.rel.ro:000AD408 DCD aIiI_0 ; "(II)I"
.data.rel.ro:000AD40C DCD_Z22javaLangString_isEmptyjjjjP6JValue ;javaLangString_isEmpty(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD410 DCD aLjavaLangSt_21 ; "Ljava/lang/String;"
.data.rel.ro:000AD414 DCD aIsempty_0 ; "isEmpty"
.data.rel.ro:000AD418 DCD aZ_1 ; "()Z"
.data.rel.ro:000AD41C DCD_Z21javaLangString_lengthjjjjP6JValue ; javaLangString_length(uint,uint,uint,uint,JValue*)
.data.rel.ro:000AD420 DCD aLjavaLangSt_21 ; "Ljava/lang/String;"
.data.rel.ro:000AD424 DCD aLength_0 ; "length"
.data.rel.ro:000AD428 DCD aI_3 ; "()I"
.data.rel.ro:000AD42C DCD_Z20javaLangMath_abs_intjjjjP6JValue ;javaLangMath_abs_int(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD430 DCD aLjavaLangMat_0 ; "Ljava/lang/Math;"
.data.rel.ro:000AD434 DCD aAbs_0 ; "abs"
.data.rel.ro:000AD438 DCD aII_0 ; "(I)I"
.data.rel.ro:000AD43C DCD_Z21javaLangMath_abs_longjjjjP6JValue ;javaLangMath_abs_long(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD440 DCD aLjavaLangMat_0 ; "Ljava/lang/Math;"
.data.rel.ro:000AD444 DCD aAbs_0 ; "abs"
.data.rel.ro:000AD448 DCD aJJ_0 ; "(J)J"
.data.rel.ro:000AD44C DCD _Z22javaLangMath_abs_floatjjjjP6JValue; javaLangMath_abs_float(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD450 DCD aLjavaLangMat_0 ; "Ljava/lang/Math;"
.data.rel.ro:000AD454 DCD aAbs_0 ; "abs"
.data.rel.ro:000AD458 DCD aFF_0 ; "(F)F"
.data.rel.ro:000AD45C DCD_Z23javaLangMath_abs_doublejjjjP6JValue ;javaLangMath_abs_double(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD460 DCD aLjavaLangMat_0 ; "Ljava/lang/Math;"
.data.rel.ro:000AD464 DCD aAbs_0 ; "abs"
.data.rel.ro:000AD468 DCD aDD_1 ; "(D)D"
.data.rel.ro:000AD46C DCD_Z20javaLangMath_min_intjjjjP6JValue ; javaLangMath_min_int(uint,uint,uint,uint,JValue*)
.data.rel.ro:000AD470 DCD aLjavaLangMat_0 ; "Ljava/lang/Math;"
.data.rel.ro:000AD474 DCD aMin_1 ; "min"
.data.rel.ro:000AD478 DCD aIiI_0 ; "(II)I"
.data.rel.ro:000AD47C DCD_Z20javaLangMath_max_intjjjjP6JValue ;javaLangMath_max_int(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD480 DCD aLjavaLangMat_0 ; "Ljava/lang/Math;"
.data.rel.ro:000AD484 DCD aMax_0 ; "max"
.data.rel.ro:000AD488 DCD aIiI_0 ; "(II)I"
.data.rel.ro:000AD48C DCD_Z17javaLangMath_sqrtjjjjP6JValue ;javaLangMath_sqrt(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD490 DCD aLjavaLangMat_0 ; "Ljava/lang/Math;"
.data.rel.ro:000AD494 DCD aSqrt_0 ; "sqrt"
.data.rel.ro:000AD498 DCD aDD_1 ; "(D)D"
.data.rel.ro:000AD49C DCD _Z16javaLangMath_cosjjjjP6JValue; javaLangMath_cos(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD4A0 DCD aLjavaLangMat_0 ; "Ljava/lang/Math;"
.data.rel.ro:000AD4A4 DCD aCos_0 ; "cos"
.data.rel.ro:000AD4A8 DCD aDD_1 ; "(D)D"
.data.rel.ro:000AD4AC DCD_Z16javaLangMath_sinjjjjP6JValue ; javaLangMath_sin(uint,uint,uint,uint,JValue*)
.data.rel.ro:000AD4B0 DCD aLjavaLangMat_0 ; "Ljava/lang/Math;"
.data.rel.ro:000AD4B4 DCD aSin_0 ; "sin"
.data.rel.ro:000AD4B8 DCD aDD_1 ; "(D)D"
.data.rel.ro:000AD4BC DCD_Z28javaLangFloat_floatToIntBitsjjjjP6JValue ; javaLangFloat_floatToIntBits(uint,uint,uint,uint,JValue*)
.data.rel.ro:000AD4C0 DCD aLjavaLangFlo_0 ; "Ljava/lang/Float;"
.data.rel.ro:000AD4C4 DCD aFloattointbi_0 ; "floatToIntBits"
.data.rel.ro:000AD4C8 DCD aFI_0 ; "(F)I"
.data.rel.ro:000AD4CC DCD_Z31javaLangFloat_floatToRawIntBitsjjjjP6JValue ;javaLangFloat_floatToRawIntBits(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD4D0 DCD aLjavaLangFlo_0 ; "Ljava/lang/Float;"
.data.rel.ro:000AD4D4 DCD aFloattorawin_0 ; "floatToRawIntBits"
.data.rel.ro:000AD4D8 DCD aFI_0 ; "(F)I"
.data.rel.ro:000AD4DC DCD_Z28javaLangFloat_intBitsToFloatjjjjP6JValue ; javaLangFloat_intBitsToFloat(uint,uint,uint,uint,JValue*)
.data.rel.ro:000AD4E0 DCD aLjavaLangFlo_0 ; "Ljava/lang/Float;"
.data.rel.ro:000AD4E4 DCD aIntbitstoflo_0 ; "intBitsToFloat"
.data.rel.ro:000AD4E8 DCD aIF_0 ; "(I)F"
.data.rel.ro:000AD4EC DCD_Z31javaLangDouble_doubleToLongBitsjjjjP6JValue ;javaLangDouble_doubleToLongBits(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD4F0 DCD aLjavaLangDou_0 ; "Ljava/lang/Double;"
.data.rel.ro:000AD4F4 DCD aDoubletolong_0 ; "doubleToLongBits"
.data.rel.ro:000AD4F8 DCD aDJ_0 ; "(D)J"
.data.rel.ro:000AD4FC DCD_Z34javaLangDouble_doubleToRawLongBitsjjjjP6JValue ;javaLangDouble_doubleToRawLongBits(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD500 DCD aLjavaLangDou_0 ; "Ljava/lang/Double;"
.data.rel.ro:000AD504 DCD aDoubletorawl_0 ; "doubleToRawLongBits"
.data.rel.ro:000AD508 DCD aDJ_0 ; "(D)J"
.data.rel.ro:000AD50C DCD_Z31javaLangDouble_longBitsToDoublejjjjP6JValue ;javaLangDouble_longBitsToDouble(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD510 DCD aLjavaLangDou_0 ; "Ljava/lang/Double;"
.data.rel.ro:000AD514 DCD aLongbitstodo_0 ; "longBitsToDouble"
.data.rel.ro:000AD518 DCD aJD_0 ; "(J)D"
.data.rel.ro:000AD51C DCD _Z20javaLangMath_abs_intjjjjP6JValue; javaLangMath_abs_int(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD520 DCD aLjavaLangStric ; "Ljava/lang/StrictMath;"
.data.rel.ro:000AD524 DCD aAbs_0 ; "abs"
.data.rel.ro:000AD528 DCD aII_0 ; "(I)I"
.data.rel.ro:000AD52C DCD_Z21javaLangMath_abs_longjjjjP6JValue ;javaLangMath_abs_long(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD530 DCD aLjavaLangStric ; "Ljava/lang/StrictMath;"
.data.rel.ro:000AD534 DCD aAbs_0 ; "abs"
.data.rel.ro:000AD538 DCD aJJ_0 ; "(J)J"
.data.rel.ro:000AD53C DCD_Z22javaLangMath_abs_floatjjjjP6JValue ; javaLangMath_abs_float(uint,uint,uint,uint,JValue*)
.data.rel.ro:000AD540 DCD aLjavaLangStric ; "Ljava/lang/StrictMath;"
.data.rel.ro:000AD544 DCD aAbs_0 ; "abs"
.data.rel.ro:000AD548 DCD aFF_0 ; "(F)F"
.data.rel.ro:000AD54C DCD_Z23javaLangMath_abs_doublejjjjP6JValue ;javaLangMath_abs_double(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD550 DCD aLjavaLangStric ; "Ljava/lang/StrictMath;"
.data.rel.ro:000AD554 DCD aAbs_0 ; "abs"
.data.rel.ro:000AD558 DCD aDD_1 ; "(D)D"
.data.rel.ro:000AD55C DCD_Z20javaLangMath_min_intjjjjP6JValue ;javaLangMath_min_int(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD560 DCD aLjavaLangStric ; "Ljava/lang/StrictMath;"
.data.rel.ro:000AD564 DCD aMin_1 ; "min"
.data.rel.ro:000AD568 DCD aIiI_0 ; "(II)I"
.data.rel.ro:000AD56C DCD_Z20javaLangMath_max_intjjjjP6JValue ;javaLangMath_max_int(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD570 DCD aLjavaLangStric ; "Ljava/lang/StrictMath;"
.data.rel.ro:000AD574 DCD aMax_0 ; "max"
.data.rel.ro:000AD578 DCD aIiI_0 ; "(II)I"
.data.rel.ro:000AD57C DCD_Z17javaLangMath_sqrtjjjjP6JValue ;javaLangMath_sqrt(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD580 DCD aLjavaLangStric ; "Ljava/lang/StrictMath;"
.data.rel.ro:000AD584 DCD aSqrt_0 ; "sqrt"
.data.rel.ro:000AD588 DCD aDD_1 ; "(D)D"
.data.rel.ro:000AD58C DCD _Z17javaLangMath_atanjjjjP6JValue; javaLangMath_atan(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD590 DCD aLjavaLangMat_0 ; "Ljava/lang/Math;"
.data.rel.ro:000AD594 DCD aAtan_0 ; "atan"
.data.rel.ro:000AD598 DCD aDD_1 ; "(D)D"
.data.rel.ro:000AD59C DCD_Z16javaLangMath_logjjjjP6JValue ; javaLangMath_log(uint,uint,uint,uint,JValue*)
.data.rel.ro:000AD5A0 DCD aLjavaLangMat_0 ; "Ljava/lang/Math;"
.data.rel.ro:000AD5A4 DCD aLog_0 ; "log"
.data.rel.ro:000AD5A8 DCD aDD_1 ; "(D)D"
.data.rel.ro:000AD5AC DCD_Z16javaLangMath_expjjjjP6JValue ; javaLangMath_exp(uint,uint,uint,uint,JValue*)
.data.rel.ro:000AD5B0 DCD aLjavaLangMat_0 ; "Ljava/lang/Math;"
.data.rel.ro:000AD5B4 DCD aExp_0 ; "exp"
.data.rel.ro:000AD5B8 DCD aDD_1 ; "(D)D"
.data.rel.ro:000AD5BC DCD_Z18javaLangMath_floorjjjjP6JValue ;javaLangMath_floor(uint,uint,uint,uint,JValue *)
.data.rel.ro:000AD5C0 DCD aLjavaLangMat_0 ; "Ljava/lang/Math;"
.data.rel.ro:000AD5C4 DCD aFloor_0 ; "floor"
.data.rel.ro:000AD5C8 DCD aDD_1 ; "(D)D"
.data.rel.ro:000AD5CC off_AD5CC DCD dvmJitToInterpNormal
在./dexlib2/src/main/java/org/jf/dexlib2/analysis/InlineMethodResolver.java修改如下,
111 privatestatic class InlineMethodResolver_version36extends InlineMethodResolver
112 {
113 private final Method[] inlineMethods;
114 private final Method indexOfIMethod;
115 private final Method indexOfIIMethod;
116 private final Method fastIndexOfMethod;
117 private final Method isEmptyMethod;
118
119 publicInlineMethodResolver_version36() {
120 //The 5th and 6th entries differ between froyo and gingerbread. We haveto look at the parameters being
121 //passed to distinguish between them.
122
123 //froyo
124 indexOfIMethod = inlineMethod(VIRTUAL, "Ljava/lang/String;","indexOf", "I", "I");
125 indexOfIIMethod = inlineMethod(VIRTUAL, "Ljava/lang/String;","indexOf", "II", "I");
126
127 //gingerbread
128 fastIndexOfMethod = inlineMethod(DIRECT, "Ljava/lang/String;","fastIndexOf", "II", "I");
129 isEmptyMethod = inlineMethod(VIRTUAL, "Ljava/lang/String;","isEmpty", "", "Z");
131 inlineMethods= new Method[] {
132 inlineMethod(STATIC,"Lorg/apache/harmony/dalvik/NativeTestTarget;","emptyInlineMethod", "", "V"),
133 inlineMethod(VIRTUAL, "Ljava/lang/String;","charAt", "I", "C"),
134 inlineMethod(VIRTUAL, "Ljava/lang/String;","compareTo", "Ljava/lang/String;", "I"),
135 inlineMethod(VIRTUAL, "Ljava/lang/String;","equals", "Ljava/lang/Object;", "Z"),
136 //froyo: deodexUtil.new InlineMethod(VIRTUAL, "Ljava/lang/String;","indexOf", "I", "I"),
137 //gingerbread: deodexUtil.new InlineMethod(VIRTUAL,"Ljava/lang/String;", "fastIndexOf", "II","I"),
138 null,
139 //froyo: deodexUtil.new InlineMethod(VIRTUAL, "Ljava/lang/String;","indexOf", "II", "I"),
140 //gingerbread: deodexUtil.new InlineMethod(VIRTUAL,"Ljava/lang/String;", "isEmpty", "","Z"),
141 null,
142 inlineMethod(VIRTUAL, "Ljava/lang/String;","length", "", "I"),
143 inlineMethod(STATIC, "Ljava/lang/Math;", "abs","I", "I"),
144 inlineMethod(STATIC, "Ljava/lang/Math;", "abs","J", "J"),
145 inlineMethod(STATIC, "Ljava/lang/Math;", "abs","F", "F"),
146 inlineMethod(STATIC,"Ljava/lang/Math;", "abs", "D", "D"),
147 inlineMethod(STATIC, "Ljava/lang/Math;", "min","II", "I"),
148 inlineMethod(STATIC, "Ljava/lang/Math;", "max","II", "I"),
149 inlineMethod(STATIC, "Ljava/lang/Math;", "sqrt","D", "D"),
150 inlineMethod(STATIC, "Ljava/lang/Math;", "cos","D", "D"),
151 inlineMethod(STATIC, "Ljava/lang/Math;", "sin","D", "D"),
152 inlineMethod(STATIC, "Ljava/lang/Float;","floatToIntBits", "F", "I"),
153 inlineMethod(STATIC, "Ljava/lang/Float;","floatToRawIntBits", "F", "I"),
154 inlineMethod(STATIC, "Ljava/lang/Float;","intBitsToFloat", "I", "F"),
155 inlineMethod(STATIC, "Ljava/lang/Double;","doubleToLongBits", "D", "J"),
156 inlineMethod(STATIC, "Ljava/lang/Double;","doubleToRawLongBits", "D", "J"),
157 inlineMethod(STATIC, "Ljava/lang/Double;","longBitsToDouble", "J", "D"),
158 inlineMethod(STATIC, "Ljava/lang/StrictMath;","abs", "I", "I"),
159 inlineMethod(STATIC, "Ljava/lang/StrictMath;","abs", "J", "J"),
160 inlineMethod(STATIC, "Ljava/lang/StrictMath;","abs", "F", "F"),
161 inlineMethod(STATIC, "Ljava/lang/StrictMath;","abs", "D", "D"),
162 inlineMethod(STATIC, "Ljava/lang/StrictMath;","min", "II", "I"),
163 inlineMethod(STATIC, "Ljava/lang/StrictMath;","max", "II", "I"),
164 inlineMethod(STATIC, "Ljava/lang/StrictMath;","sqrt", "D", "D"),
164 inlineMethod(STATIC, "Ljava/lang/Math;", "atan","D", "D"),
164 inlineMethod(STATIC, "Ljava/lang/Math;", "log","D", "D"),
164 inlineMethod(STATIC, "Ljava/lang/Math;", "exp","D", "D"),
164 inlineMethod(STATIC, "Ljava/lang/Math;", "floor","D", "D"),
165 };
166 }
apktool分析odex不能合并原因分析