From eb4e4cd85443f2ee410e258b4c983eedfbeb7cec Mon Sep 17 00:00:00 2001 From: "JesusFreke@JesusFreke.com" Date: Mon, 27 Apr 2009 00:18:39 +0000 Subject: [PATCH] Added support for Format21t git-svn-id: https://smali.googlecode.com/svn/trunk@20 55b6fa8a-2a1e-11de-a435-ffa8d773f76a --- .../antlr3/org/JesusFreke/smali/smaliLexer.g | 17 +++++ .../antlr3/org/JesusFreke/smali/smaliParser.g | 4 + .../org/JesusFreke/smali/smaliTreeWalker.g | 15 ++++ .../dexlib/code/Format/Format21t.java | 74 +++++++++++++++++++ src/test/resources/examples/HelloWorld2.smali | 31 ++++++++ 5 files changed, 141 insertions(+) create mode 100644 src/main/java/org/JesusFreke/dexlib/code/Format/Format21t.java diff --git a/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g b/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g index 92cf5f92..8fba5cfd 100644 --- a/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g +++ b/src/main/antlr3/org/JesusFreke/smali/smaliLexer.g @@ -284,6 +284,13 @@ INSTRUCTION_FORMAT21c_TYPE_PHRASE WS? ',' WS? CLASS_OR_ARRAY_TYPE_DESCRIPTOR_EMITCHILD; +INSTRUCTION_FORMAT21t_PHRASE + : INSTRUCTION_FORMAT21t_EMIT + WS + REGISTER_EMIT + WS? ',' WS? + (LABEL_EMIT | OFFSET_EMIT); + INSTRUCTION_FORMAT22c_FIELD_PHRASE : INSTRUCTION_FORMAT22c_FIELD_EMIT WS @@ -743,6 +750,16 @@ fragment INSTRUCTION_FORMAT21c_TYPE | 'new-instance' | 'const-class'; +fragment INSTRUCTION_FORMAT21t_EMIT + : INSTRUCTION_FORMAT21t {emit($INSTRUCTION_FORMAT21t, INSTRUCTION_FORMAT21t);}; +fragment INSTRUCTION_FORMAT21t + : 'if-eqz' + | 'if-nez' + | 'if-ltz' + | 'if-gez' + | 'if-gtz' + | 'if-lez'; + fragment INSTRUCTION_FORMAT22c_FIELD_EMIT : INSTRUCTION_FORMAT22c_FIELD {emit($INSTRUCTION_FORMAT22c_FIELD, INSTRUCTION_FORMAT22c_FIELD);}; fragment INSTRUCTION_FORMAT22c_FIELD diff --git a/src/main/antlr3/org/JesusFreke/smali/smaliParser.g b/src/main/antlr3/org/JesusFreke/smali/smaliParser.g index 0e564db1..f635a6ab 100644 --- a/src/main/antlr3/org/JesusFreke/smali/smaliParser.g +++ b/src/main/antlr3/org/JesusFreke/smali/smaliParser.g @@ -60,6 +60,7 @@ tokens { I_STATEMENT_FORMAT21c_TYPE; I_STATEMENT_FORMAT21c_FIELD; I_STATEMENT_FORMAT21c_STRING; + I_STATEMENT_FORMAT21t; I_STATEMENT_FORMAT22c_FIELD; I_STATEMENT_FORMAT22x; I_STATEMENT_FORMAT30t; @@ -161,6 +162,9 @@ instruction returns [int size] | //e.g. const-class v2 org/JesusFreke/HelloWorld2/HelloWorld2 INSTRUCTION_FORMAT21c_TYPE REGISTER class_or_array_type_descriptor {$size = Format21c.Format.getByteCount();} -> ^(I_STATEMENT_FORMAT21c_TYPE[$start, "I_STATEMENT_FORMAT21c"] INSTRUCTION_FORMAT21c_TYPE REGISTER class_or_array_type_descriptor) + | //e.g. if-eqz v0, endloop: + INSTRUCTION_FORMAT21t REGISTER (LABEL | OFFSET) {$size = Format21t.Format.getByteCount();} + -> ^(I_STATEMENT_FORMAT21t[$start, "I_STATEMENT_FORMAT21t"] INSTRUCTION_FORMAT21t REGISTER LABEL? OFFSET?) | //e.g. iput-object v1 v0 org/JesusFreke/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String; INSTRUCTION_FORMAT22c_FIELD REGISTER REGISTER fully_qualified_field {$size = Format22c.Format.getByteCount();} -> ^(I_STATEMENT_FORMAT22c_FIELD[$start, "I_INSTANCE_FIELD_STATEMENT"] INSTRUCTION_FORMAT22c_FIELD REGISTER REGISTER fully_qualified_field) diff --git a/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g b/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g index 038a4e01..d72d0e74 100644 --- a/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g +++ b/src/main/antlr3/org/JesusFreke/smali/smaliTreeWalker.g @@ -417,6 +417,21 @@ instruction returns[Instruction instruction] $instruction = Format21c.Format.make(dexFile, opcode.value, regA, typeIdItem); } + | //e.g. if-eqz v0, endloop: + ^(I_STATEMENT_FORMAT21t INSTRUCTION_FORMAT21t REGISTER offset_or_label) + { + Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT21t.text); + short regA = parseRegister_byte($REGISTER.text); + + int addressOffset = $offset_or_label.offsetValue; + + if (addressOffset < Short.MIN_VALUE || addressOffset > Short.MAX_VALUE) { + //TODO: throw correct exception type + throw new RuntimeException("The offset/label is out of range. The offset is " + Integer.toString(addressOffset) + " and the range for this opcode is [-32768, 32767]."); + } + + $instruction = Format21t.Format.make(dexFile, opcode.value, regA, (short)addressOffset); + } | //e.g. iput-object v1 v0 org/JesusFreke/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String; ^(I_STATEMENT_FORMAT22c_FIELD INSTRUCTION_FORMAT22c_FIELD registerA=REGISTER registerB=REGISTER fully_qualified_field) { diff --git a/src/main/java/org/JesusFreke/dexlib/code/Format/Format21t.java b/src/main/java/org/JesusFreke/dexlib/code/Format/Format21t.java new file mode 100644 index 00000000..c6c72016 --- /dev/null +++ b/src/main/java/org/JesusFreke/dexlib/code/Format/Format21t.java @@ -0,0 +1,74 @@ +/* + * [The "BSD licence"] + * Copyright (c) 2009 Ben Gruver + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.JesusFreke.dexlib.code.Format; + +import org.JesusFreke.dexlib.code.Instruction; +import org.JesusFreke.dexlib.code.Opcode; +import org.JesusFreke.dexlib.DexFile; + +public class Format21t extends Format +{ + public static final Format21t Format = new Format21t(); + + private Format21t() { + } + + public Instruction make(DexFile dexFile, byte opcode, short regA, short offB) { + byte[] bytes = new byte[4]; + + Opcode op = Opcode.getOpcodeByValue(opcode); + + checkOpcodeFormat(op); + + if (regA >= 1<<8) { + throw new RuntimeException("The register number must be less than v256"); + } + + if (offB == 0) { + throw new RuntimeException("The offset cannot be 0."); + } + + bytes[0] = opcode; + bytes[1] = (byte)regA; + bytes[2] = (byte)offB; + bytes[3] = (byte)(offB >> 8); + + return new Instruction(dexFile, bytes, null); + } + + public int getByteCount() + { + return 4; + } + + public String getFormatName() + { + return "21t"; + } +} diff --git a/src/test/resources/examples/HelloWorld2.smali b/src/test/resources/examples/HelloWorld2.smali index 88b9d26f..cbb2e01e 100644 --- a/src/test/resources/examples/HelloWorld2.smali +++ b/src/test/resources/examples/HelloWorld2.smali @@ -6,6 +6,8 @@ .field private static helloWorldStatic2 Ljava/lang/String; = "Static Initializer Hello World!" +.field private static branchTest I = 0 + ;This class should display the following text to the screen: ; @@ -23,6 +25,7 @@ ;Format20t with a label ;Format30t with a label ;Testing Format22x and Format32x +;Testing Format21t @@ -58,6 +61,22 @@ return-object v1 .end method +.method public testFormat21t()Ljava/lang/String; + .registers 3 + + const-string v0, "Testing Format21t" + const-string v1, "This shouldn't be displayed!" + + sget v2, org/JesusFreke/HelloWorld2/HelloWorld2/branchTest I + + if-eqz v2, HERE: + + return-object v1 + +HERE: + return-object v0 +.end method + .method public onCreate(Landroid/os/Bundle;)V .registers 6 @@ -235,6 +254,18 @@ move-result-object v2 + + ;test format21t + invoke-virtual {v4}, org/JesusFreke/HelloWorld2/HelloWorld2/testFormat21t()Ljava/lang/String; + move-result-object v1 + + invoke-virtual {v2, v1}, java/lang/String/concat(Ljava/lang/String;)Ljava/lang/String; + move-result-object v2 + + invoke-virtual {v2, v3}, java/lang/String/concat(Ljava/lang/String;)Ljava/lang/String; + move-result-object v2 + + check-cast v4, Landroid/app/Activity; invoke-virtual {v0,v2}, android/widget/TextView/setText(Ljava/lang/CharSequence;)V