Dalvik Verifier: copy1 v16 <-v22 type = 2 cat = 1 - PullRequest
0 голосов
/ 07 марта 2019

Следующий код smali не принят Dalvik:

.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-битными регистрами.Так что все должно быть хорошо.

1 Ответ

1 голос
/ 08 марта 2019

Из сообщения об ошибке тип p2 в этой точке равен «2», что равно kRegTypeConflict.Конфликтующий тип означает, что существует несколько путей кода, которые объединяются вместе, и каждый путь кода имеет несовместимый входящий тип в этом регистре.

Если вы посмотрите на начало метода, вы увидите ":cond_0 "метка, что означает, что в методе есть еще какое-то условие, которое может перейти туда.Значение p2 в этом условном выражении не является целым числом, поэтому у нас есть 1 кодовый путь (от начала метода), где p2 - целое число, и другой кодовый путь (из условного перехода), где оно является чем-то другим, поэтомуВерификатор помечает регистр как конфликтующий.

Невозможно прочитать регистр конфликтующего типа.В этом случае вы можете рассматривать его как неинициализированный регистр.

Если вы хотите увидеть больше информации о том, как типы регистров объединяются в этом случае, вы можете использовать опцию baskmali --register-info с флагом FULLMERGE.--register-info=ARGS,DEST,FULLMERGE.Или, если вы хотите видеть каждый регистр до и после каждой инструкции, вы можете использовать --register-info="ALL,FULLMERGE"

...