Dalvik不接受以下smali代码:
.method getOrCompute(Ljava/lang/Object;ILcom/google/inject/internal/guava/base/$Function;)Ljava/lang/Object;
.registers 24
.param p2, "hash" # I
.annotation system Ldalvik/annotation/Signature;
value = {
"(TK;I",
"Lcom/google/inject/internal/guava/base/$Function",
"<-TK;+TV;>;)TV;"
}
.end annotation
.annotation system Ldalvik/annotation/Throws;
value = {
Ljava/util/concurrent/ExecutionException;
}
.end annotation
#@0
.prologue
.line 12
:cond_0
:try_start_0
move-object/16 v17, p3
#@3
move/16 v16, p2
验证者错误:
dalvikvm: VFY: copy1 v16<-v22 type=2 cat=1
dalvikvm: VFY: rejecting opcode 0x03 at 0x0003
dalvikvm: VFY: rejected Lcom/google/inject/internal/guava/collect/$ComputingConcurrentHashMap$ComputingSegment;.getOrCompute (Ljava/lang/Object;ILcom/google/inject/internal/guava/base/$Function;)Ljava/lang/Object;
dalvikvm: Verifier rejected class Lcom/google/inject/internal/guava/collect/$ComputingConcurrentHashMap$ComputingSegment;
我不太了解这个问题。 v16和v22(p2)是16位寄存器。所以一切都应该很好。
答案 0 :(得分:1)
从错误消息中可以看到,此时p2的类型为“ 2”,即kRegTypeConflict
。类型冲突意味着有多个代码路径合并在一起,并且每个代码路径在该寄存器中都有一个不兼容的传入类型。
如果您看一下方法的开头,则会看到“:cond_0”标签,这意味着该方法中的其他条件可以跳转到该条件。在该条件下p2的值不是整数,因此我们有1条代码路径(从方法的开头开始),其中p2是整数,而另一条代码路径(从条件跳转开始)在其他地方,因此验证程序将寄存器标记为冲突。
无法读取类型冲突的寄存器。此时,您基本上可以将其视为未初始化的寄存器。
如果您想了解有关在这种情况下如何合并寄存器类型的更多信息,可以将baskmali的--register-info
选项与FULLMERGE标志一起使用。 --register-info=ARGS,DEST,FULLMERGE
。或者,如果您想查看每条指令前后的每个寄存器,则可以使用--register-info="ALL,FULLMERGE"