From 6c6b9f0845e32ee841b267395bdf77fa9217e83b Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Sat, 9 Jul 2016 13:41:30 -0700 Subject: [PATCH 01/13] Upgrade to gradle 2.14 --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 52141 -> 53638 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++-- gradlew | 10 +++------- gradlew.bat | 2 +- 5 files changed, 7 insertions(+), 11 deletions(-) diff --git a/build.gradle b/build.gradle index 80ac25f8..6f47823d 100644 --- a/build.gradle +++ b/build.gradle @@ -197,5 +197,5 @@ buildscript { } task wrapper(type: Wrapper) { - gradleVersion = '2.11' + gradleVersion = '2.14' } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 085a1cdc27db1185342f15a00441734e74fe3735..5ccda13e9cb94678ba179b32452cf3d60dc36353 100644 GIT binary patch delta 19363 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 m@d;TN$kx6KBnkk5&&- +cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" -cd "$SAVED" >&- +cd "$SAVED" >/dev/null CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -114,6 +109,7 @@ fi if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` diff --git a/gradlew.bat b/gradlew.bat index aec99730..72d362da 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -46,7 +46,7 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args if "%@eval[2+2]" == "4" goto 4NT_args From 07dc76c03f5409dda8ec1f9c36ffbc8546bbbf14 Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Sat, 9 Jul 2016 13:42:15 -0700 Subject: [PATCH 02/13] Switch to jprante's jflex plugin --- build.gradle | 3 +-- smali/build.gradle | 11 +++-------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/build.gradle b/build.gradle index 6f47823d..ac8bdcb8 100644 --- a/build.gradle +++ b/build.gradle @@ -105,8 +105,7 @@ subprojects { antlr: 'org.antlr:antlr:3.5.2', stringtemplate: 'org.antlr:stringtemplate:3.2.1', commons_cli: 'commons-cli:commons-cli:1.2', - jflex: 'de.jflex:jflex:1.4.3', - jflex_plugin: 'co.tomlee.gradle.plugins:gradle-jflex-plugin:0.0.2', + jflex_plugin: 'org.xbib.gradle.plugin:gradle-plugin-jflex:1.1.0', proguard_gradle: 'net.sf.proguard:proguard-gradle:5.2.1', dx: 'com.google.android.tools:dx:1.7', gson: 'com.google.code.gson:gson:2.3.1' diff --git a/smali/build.gradle b/smali/build.gradle index 75001d73..318b5a97 100644 --- a/smali/build.gradle +++ b/smali/build.gradle @@ -30,7 +30,7 @@ */ apply plugin: 'antlr' -apply plugin: 'jflex' +apply plugin: 'org.xbib.gradle.plugin.jflex' buildscript { repositories { @@ -46,10 +46,6 @@ configurations { // Remove the full antlr library that's added by the antlr plugin. We manually // add the smaller antlr_runtime library instead compile.exclude group: 'org.antlr', module: 'antlr' - - // The jflex lexer doesn't have any runtime dependencies, so remove the dependency - // that gets added by the jflex plugin - compile.exclude group: 'de.jflex', module: 'jflex' } sourceSets { @@ -86,7 +82,6 @@ dependencies { testCompile depends.junit antlr depends.antlr - jflex depends.jflex } processResources.inputs.property('version', version) @@ -119,8 +114,8 @@ generateGrammarSource { outputDirectory = new File(outputDirectory, 'org/jf/smali') } -generateJFlexSource { - outputDirectory = new File(outputDirectory, 'org/jf/smali') +jflex { + generateDir = new File(generateDir, 'org/jf/smali') } uploadArchives { From d5c6ffa0595cf5bfe5fcf1054670d9d20de3a253 Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Sun, 10 Jul 2016 20:04:02 -0700 Subject: [PATCH 03/13] Move existing smali tests to the org.jf.smali package --- .../{ => org/jf/smali}/ByteLiteralTest.java | 43 ++++++++------- .../jf/smali}/ImplicitReferenceTest.java | 10 ++-- .../{ => org/jf/smali}/IntLiteralTest.java | 43 ++++++++------- .../java/{ => org/jf/smali}/LexerTest.java | 55 +++++++++---------- .../{ => org/jf/smali}/LongLiteralTest.java | 43 ++++++++------- .../{ => org/jf/smali}/ShortLiteralTest.java | 43 ++++++++------- 6 files changed, 124 insertions(+), 113 deletions(-) rename smali/src/test/java/{ => org/jf/smali}/ByteLiteralTest.java (77%) rename smali/src/test/java/{ => org/jf/smali}/ImplicitReferenceTest.java (97%) rename smali/src/test/java/{ => org/jf/smali}/IntLiteralTest.java (79%) rename smali/src/test/java/{ => org/jf/smali}/LexerTest.java (77%) rename smali/src/test/java/{ => org/jf/smali}/LongLiteralTest.java (80%) rename smali/src/test/java/{ => org/jf/smali}/ShortLiteralTest.java (78%) diff --git a/smali/src/test/java/ByteLiteralTest.java b/smali/src/test/java/org/jf/smali/ByteLiteralTest.java similarity index 77% rename from smali/src/test/java/ByteLiteralTest.java rename to smali/src/test/java/org/jf/smali/ByteLiteralTest.java index 2e6511da..7bf7c54e 100644 --- a/smali/src/test/java/ByteLiteralTest.java +++ b/smali/src/test/java/org/jf/smali/ByteLiteralTest.java @@ -1,32 +1,35 @@ /* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) + * Copyright 2016, Google Inc. * 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. + * modification, are permitted provided that the following conditions are + * met: * - * 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, + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import org.jf.smali.LiteralTools; +package org.jf.smali;import org.jf.smali.LiteralTools; import org.junit.Assert; import org.junit.Test; diff --git a/smali/src/test/java/ImplicitReferenceTest.java b/smali/src/test/java/org/jf/smali/ImplicitReferenceTest.java similarity index 97% rename from smali/src/test/java/ImplicitReferenceTest.java rename to smali/src/test/java/org/jf/smali/ImplicitReferenceTest.java index b080c8a5..83046536 100644 --- a/smali/src/test/java/ImplicitReferenceTest.java +++ b/smali/src/test/java/org/jf/smali/ImplicitReferenceTest.java @@ -1,18 +1,18 @@ /* - * Copyright 2014, Google Inc. + * Copyright 2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * - * * Redistributions of source code must retain the above copyright + * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above + * 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. - * * Neither the name of Google Inc. nor the names of its + * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * @@ -29,7 +29,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import com.google.common.collect.Lists; +package org.jf.smali;import com.google.common.collect.Lists; import com.google.common.collect.Maps; import junit.framework.Assert; import org.antlr.runtime.RecognitionException; diff --git a/smali/src/test/java/IntLiteralTest.java b/smali/src/test/java/org/jf/smali/IntLiteralTest.java similarity index 79% rename from smali/src/test/java/IntLiteralTest.java rename to smali/src/test/java/org/jf/smali/IntLiteralTest.java index f5a8c969..6cc7fbd6 100644 --- a/smali/src/test/java/IntLiteralTest.java +++ b/smali/src/test/java/org/jf/smali/IntLiteralTest.java @@ -1,32 +1,35 @@ /* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) + * Copyright 2016, Google Inc. * 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. + * modification, are permitted provided that the following conditions are + * met: * - * 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, + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import org.jf.smali.LiteralTools; +package org.jf.smali;import org.jf.smali.LiteralTools; import org.junit.Assert; import org.junit.Test; diff --git a/smali/src/test/java/LexerTest.java b/smali/src/test/java/org/jf/smali/LexerTest.java similarity index 77% rename from smali/src/test/java/LexerTest.java rename to smali/src/test/java/org/jf/smali/LexerTest.java index d156015a..5f1f21e4 100644 --- a/smali/src/test/java/LexerTest.java +++ b/smali/src/test/java/org/jf/smali/LexerTest.java @@ -1,39 +1,38 @@ /* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver + * Copyright 2016, Google Inc. * 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. + * modification, are permitted provided that the following conditions are + * met: * - * 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, + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import org.antlr.runtime.ANTLRInputStream; +package org.jf.smali;import org.antlr.runtime.ANTLRInputStream; import org.antlr.runtime.CommonToken; import org.antlr.runtime.CommonTokenStream; import org.antlr.runtime.RecognitionException; -import org.jf.smali.expectedTokensTestGrammarLexer; -import org.jf.smali.expectedTokensTestGrammarParser; -import org.jf.smali.smaliFlexLexer; -import org.jf.smali.smaliParser; import org.junit.Assert; import org.junit.Test; @@ -135,9 +134,9 @@ public class LexerTest { String smaliFile = String.format("LexerTest%s%s.smali", File.separatorChar, test); String tokensFile = String.format("LexerTest%s%s.tokens", File.separatorChar, test); - expectedTokensTestGrammarLexer expectedTokensLexer = null; + org.jf.smali.expectedTokensTestGrammarLexer expectedTokensLexer = null; try { - expectedTokensLexer = new expectedTokensTestGrammarLexer(new ANTLRInputStream( + expectedTokensLexer = new org.jf.smali.expectedTokensTestGrammarLexer(new ANTLRInputStream( LexerTest.class.getClassLoader().getResourceAsStream(tokensFile))); } catch (IOException ex) { throw new RuntimeException(ex); @@ -145,8 +144,8 @@ public class LexerTest { CommonTokenStream expectedTokensStream = new CommonTokenStream(expectedTokensLexer); - expectedTokensTestGrammarParser expectedTokensParser = - new expectedTokensTestGrammarParser(expectedTokensStream); + org.jf.smali.expectedTokensTestGrammarParser expectedTokensParser = + new org.jf.smali.expectedTokensTestGrammarParser(expectedTokensStream); try { expectedTokensParser.top(); } catch (RecognitionException ex) { diff --git a/smali/src/test/java/LongLiteralTest.java b/smali/src/test/java/org/jf/smali/LongLiteralTest.java similarity index 80% rename from smali/src/test/java/LongLiteralTest.java rename to smali/src/test/java/org/jf/smali/LongLiteralTest.java index f68cf5a7..4659a0ba 100644 --- a/smali/src/test/java/LongLiteralTest.java +++ b/smali/src/test/java/org/jf/smali/LongLiteralTest.java @@ -1,32 +1,35 @@ /* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) + * Copyright 2016, Google Inc. * 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. + * modification, are permitted provided that the following conditions are + * met: * - * 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, + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import org.jf.smali.LiteralTools; +package org.jf.smali;import org.jf.smali.LiteralTools; import org.junit.Assert; import org.junit.Test; diff --git a/smali/src/test/java/ShortLiteralTest.java b/smali/src/test/java/org/jf/smali/ShortLiteralTest.java similarity index 78% rename from smali/src/test/java/ShortLiteralTest.java rename to smali/src/test/java/org/jf/smali/ShortLiteralTest.java index e366be85..2ba22ac6 100644 --- a/smali/src/test/java/ShortLiteralTest.java +++ b/smali/src/test/java/org/jf/smali/ShortLiteralTest.java @@ -1,32 +1,35 @@ /* - * [The "BSD licence"] - * Copyright (c) 2010 Ben Gruver (JesusFreke) + * Copyright 2016, Google Inc. * 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. + * modification, are permitted provided that the following conditions are + * met: * - * 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, + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import org.jf.smali.LiteralTools; +package org.jf.smali;import org.jf.smali.LiteralTools; import org.junit.Assert; import org.junit.Test; From c347e68b46da4d78d1f5c7a3704ee59aa5e87ef5 Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Sun, 10 Jul 2016 21:35:07 -0700 Subject: [PATCH 04/13] Allow invalid register references in debug items related to locals. Art doesn't complain about this, so we shouldn't throw an error when encountering a dex file with something like this. --- .../java/org/jf/baksmali/LargeLocalTest.java | 54 +++++++++++++++++++ .../LargeLocalTest/LargeEndLocal.smali | 11 ++++ .../LargeLocalTest/LargeRestartLocal.smali | 11 ++++ .../LargeLocalTest/LargeStartLocal.smali | 11 ++++ .../jf/dexlib2/dexbacked/util/DebugInfo.java | 29 ++++++++-- 5 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 baksmali/src/test/java/org/jf/baksmali/LargeLocalTest.java create mode 100644 baksmali/src/test/resources/LargeLocalTest/LargeEndLocal.smali create mode 100644 baksmali/src/test/resources/LargeLocalTest/LargeRestartLocal.smali create mode 100644 baksmali/src/test/resources/LargeLocalTest/LargeStartLocal.smali diff --git a/baksmali/src/test/java/org/jf/baksmali/LargeLocalTest.java b/baksmali/src/test/java/org/jf/baksmali/LargeLocalTest.java new file mode 100644 index 00000000..28def63d --- /dev/null +++ b/baksmali/src/test/java/org/jf/baksmali/LargeLocalTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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.jf.baksmali; + +import org.junit.Test; + +/** + * Test for a bug related to debug items that refer to a register that's outside the expected range for a method + */ +public class LargeLocalTest extends IdenticalRoundtripTest { + @Test + public void testLargeEndLocal() { + runTest("LargeEndLocal"); + } + + @Test + public void testLargeRestartLocal() { + runTest("LargeRestartLocal"); + } + + @Test + public void testLargeStartLocal() { + runTest("LargeStartLocal"); + } +} diff --git a/baksmali/src/test/resources/LargeLocalTest/LargeEndLocal.smali b/baksmali/src/test/resources/LargeLocalTest/LargeEndLocal.smali new file mode 100644 index 00000000..8c7e72ce --- /dev/null +++ b/baksmali/src/test/resources/LargeLocalTest/LargeEndLocal.smali @@ -0,0 +1,11 @@ +.class LLargeRestartLocal; +.super Ljava/lang/Object; + + +# virtual methods +.method public static main([Ljava/lang/String;)V + .registers 2 + + .end local p99 + return-void +.end method diff --git a/baksmali/src/test/resources/LargeLocalTest/LargeRestartLocal.smali b/baksmali/src/test/resources/LargeLocalTest/LargeRestartLocal.smali new file mode 100644 index 00000000..41c60d02 --- /dev/null +++ b/baksmali/src/test/resources/LargeLocalTest/LargeRestartLocal.smali @@ -0,0 +1,11 @@ +.class LLargeEndLocal; +.super Ljava/lang/Object; + + +# virtual methods +.method public static main([Ljava/lang/String;)V + .registers 2 + + .restart local p99 + return-void +.end method diff --git a/baksmali/src/test/resources/LargeLocalTest/LargeStartLocal.smali b/baksmali/src/test/resources/LargeLocalTest/LargeStartLocal.smali new file mode 100644 index 00000000..b811844b --- /dev/null +++ b/baksmali/src/test/resources/LargeLocalTest/LargeStartLocal.smali @@ -0,0 +1,11 @@ +.class LLargeStartLocal; +.super Ljava/lang/Object; + + +# virtual methods +.method public static main([Ljava/lang/String;)V + .registers 2 + + .local p99, "blah":I + return-void +.end method diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/util/DebugInfo.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/util/DebugInfo.java index 8a32b5f6..ef240718 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/util/DebugInfo.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/util/DebugInfo.java @@ -182,7 +182,9 @@ public abstract class DebugInfo implements Iterable { String type = dexFile.getOptionalType(reader.readSmallUleb128() - 1); ImmutableStartLocal startLocal = new ImmutableStartLocal(codeAddress, register, name, type, null); - locals[register] = startLocal; + if (register >= 0 && register < locals.length) { + locals[register] = startLocal; + } return startLocal; } case DebugItemType.START_LOCAL_EXTENDED: { @@ -192,13 +194,23 @@ public abstract class DebugInfo implements Iterable { String signature = dexFile.getOptionalString(reader.readSmallUleb128() - 1); ImmutableStartLocal startLocal = new ImmutableStartLocal(codeAddress, register, name, type, signature); - locals[register] = startLocal; + if (register >= 0 && register < locals.length) { + locals[register] = startLocal; + } return startLocal; } case DebugItemType.END_LOCAL: { int register = reader.readSmallUleb128(); - LocalInfo localInfo = locals[register]; + boolean replaceLocalInTable = true; + LocalInfo localInfo; + if (register >= 0 && register < locals.length) { + localInfo = locals[register]; + } else { + localInfo = EMPTY_LOCAL_INFO; + replaceLocalInTable = false; + } + if (localInfo instanceof EndLocal) { localInfo = EMPTY_LOCAL_INFO; // don't replace the local info in locals. The new EndLocal won't have any info at all, @@ -216,11 +228,18 @@ public abstract class DebugInfo implements Iterable { } case DebugItemType.RESTART_LOCAL: { int register = reader.readSmallUleb128(); - LocalInfo localInfo = locals[register]; + LocalInfo localInfo; + if (register >= 0 && register < locals.length) { + localInfo = locals[register]; + } else { + localInfo = EMPTY_LOCAL_INFO; + } ImmutableRestartLocal restartLocal = new ImmutableRestartLocal(codeAddress, register, localInfo.getName(), localInfo.getType(), localInfo.getSignature()); - locals[register] = restartLocal; + if (register >= 0 && register < locals.length) { + locals[register] = restartLocal; + } return restartLocal; } case DebugItemType.PROLOGUE_END: { From 2709afc5f8624e206709a284b974c2d26c5817f0 Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Sat, 16 Jul 2016 13:46:49 -0700 Subject: [PATCH 05/13] Bump the version number to 2.1.3 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ac8bdcb8..56aaa3f6 100644 --- a/build.gradle +++ b/build.gradle @@ -31,7 +31,7 @@ apply plugin: 'idea' -version = '2.1.2' +version = '2.1.3' if (!('release' in gradle.startParameter.taskNames)) { def versionSuffix From f8f4e3224062c583a7d41c26c4ffe81f7143bd6f Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Sat, 23 Jul 2016 15:16:39 -0700 Subject: [PATCH 06/13] Update smalidea to work with newer versions of IDEA This moves from using the deprecated DebuggerSupport class to the new JvmSteppingCommandProvider This also bumps the minimum required IDEA version to 15 --- smalidea/build.gradle | 2 +- .../debugging/SmaliDebuggerSupport.java | 81 ------------------- .../SmaliSteppingCommandProvider.java | 54 +++++++++++++ .../src/main/resources/META-INF/plugin.xml | 5 +- 4 files changed, 57 insertions(+), 85 deletions(-) delete mode 100644 smalidea/src/main/java/org/jf/smalidea/debugging/SmaliDebuggerSupport.java create mode 100644 smalidea/src/main/java/org/jf/smalidea/debugging/SmaliSteppingCommandProvider.java diff --git a/smalidea/build.gradle b/smalidea/build.gradle index 6b855d7b..8cba19d2 100644 --- a/smalidea/build.gradle +++ b/smalidea/build.gradle @@ -93,7 +93,7 @@ if (!('idea' in gradle.startParameter.taskNames)) { apply plugin: 'org.jetbrains.intellij' intellij { - version 'IC-14.1.4' + version 'IC-15.0.6' pluginName 'smalidea' updateSinceUntilBuild false diff --git a/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliDebuggerSupport.java b/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliDebuggerSupport.java deleted file mode 100644 index f822fd1f..00000000 --- a/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliDebuggerSupport.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2014, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "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 COPYRIGHT - * OWNER OR CONTRIBUTORS 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.jf.smalidea.debugging; - -import com.intellij.debugger.actions.StepOverActionHandler; -import com.intellij.debugger.impl.DebuggerSession; -import com.intellij.debugger.ui.JavaDebuggerSupport; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.project.Project; -import com.intellij.xdebugger.impl.actions.DebuggerActionHandler; -import com.sun.jdi.request.StepRequest; -import org.jetbrains.annotations.NotNull; - -public class SmaliDebuggerSupport extends JavaDebuggerSupport { - private static boolean useModifiedMethod; - - static { - try { - DebuggerSession.class.getMethod("stepOver", boolean.class, int.class); - useModifiedMethod = true; - } catch (NoSuchMethodException ex) { - useModifiedMethod = false; - } - } - - private final StepOverActionHandler myStepOverActionHandler = new StepOverActionHandler() { - @Override - public void perform(@NotNull final Project project, AnActionEvent e) { - final DebuggerSession session = getSession(project); - - if (session != null) { - if (useModifiedMethod) { - session.stepOver(false, StepRequest.STEP_MIN); - } else { - session.stepOver(false); - } - } - } - - @Override public boolean isEnabled(@NotNull Project project, AnActionEvent event) { - // TODO: check if we're currently in a smali file? - return super.isEnabled(project, event); - } - }; - - @NotNull - @Override - public DebuggerActionHandler getStepOverHandler() { - return myStepOverActionHandler; - } - -} diff --git a/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliSteppingCommandProvider.java b/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliSteppingCommandProvider.java new file mode 100644 index 00000000..4be1e7f0 --- /dev/null +++ b/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliSteppingCommandProvider.java @@ -0,0 +1,54 @@ +/* + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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.jf.smalidea.debugging; + +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.engine.ContextUtil; +import com.intellij.debugger.engine.DebugProcessImpl.ResumeCommand; +import com.intellij.debugger.engine.SuspendContextImpl; +import com.intellij.debugger.impl.JvmSteppingCommandProvider; +import com.sun.jdi.request.StepRequest; +import org.jetbrains.annotations.NotNull; +import org.jf.smalidea.SmaliLanguage; + +public class SmaliSteppingCommandProvider extends JvmSteppingCommandProvider { + @Override + public ResumeCommand getStepOverCommand(@NotNull final SuspendContextImpl suspendContext, boolean ignoreBreakpoints, + int stepSize) { + SourcePosition locationPosition = ContextUtil.getSourcePosition(suspendContext); + if (locationPosition != null && locationPosition.getFile().getLanguage() == SmaliLanguage.INSTANCE) { + return suspendContext.getDebugProcess().createStepOverCommand(suspendContext, ignoreBreakpoints, + StepRequest.STEP_MIN); + } + return null; + } +} diff --git a/smalidea/src/main/resources/META-INF/plugin.xml b/smalidea/src/main/resources/META-INF/plugin.xml index 6e24054b..8ae92dad 100644 --- a/smalidea/src/main/resources/META-INF/plugin.xml +++ b/smalidea/src/main/resources/META-INF/plugin.xml @@ -12,7 +12,7 @@ ]]> - + @@ -23,8 +23,7 @@ - + Date: Sat, 23 Jul 2016 15:16:56 -0700 Subject: [PATCH 07/13] Don't try to resolve smali type references when in dumb mode --- .../java/org/jf/smalidea/util/NameUtils.java | 5 +++++ .../org/jf/smalidea/ClassReferenceTest.java | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/smalidea/src/main/java/org/jf/smalidea/util/NameUtils.java b/smalidea/src/main/java/org/jf/smalidea/util/NameUtils.java index 305c7f8a..47cb08ca 100644 --- a/smalidea/src/main/java/org/jf/smalidea/util/NameUtils.java +++ b/smalidea/src/main/java/org/jf/smalidea/util/NameUtils.java @@ -32,6 +32,7 @@ package org.jf.smalidea.util; import com.google.common.collect.ImmutableMap; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.impl.ResolveScopeManager; @@ -129,6 +130,10 @@ public class NameUtils { public static PsiClass resolveSmaliType(@NotNull Project project, @NotNull GlobalSearchScope scope, @NotNull String smaliType) { + if (DumbService.isDumb(project)) { + return null; + } + JavaPsiFacade facade = JavaPsiFacade.getInstance(project); String javaType = NameUtils.smaliToJavaType(smaliType); diff --git a/smalidea/src/test/java/org/jf/smalidea/ClassReferenceTest.java b/smalidea/src/test/java/org/jf/smalidea/ClassReferenceTest.java index 05f3b1be..9d61bf02 100644 --- a/smalidea/src/test/java/org/jf/smalidea/ClassReferenceTest.java +++ b/smalidea/src/test/java/org/jf/smalidea/ClassReferenceTest.java @@ -31,6 +31,7 @@ package org.jf.smalidea; +import com.intellij.openapi.project.DumbServiceImpl; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl; import com.intellij.psi.JavaResolveResult; @@ -66,6 +67,24 @@ public class ClassReferenceTest extends ResolveTestCase { Assert.assertEquals("java.lang.Object", ((PsiClass)resolveResults[0].getElement()).getQualifiedName()); } + /** + * Test a reference to a java class from a smali class, while in dumb mode + */ + public void testJavaReferenceFromSmaliInDumbMode() throws Exception { + SmaliClassTypeElement typeElement = (SmaliClassTypeElement)configureByFileText( + ".class public Lblah; .super Ljava/lang/Object;", "blah.smali"); + + Assert.assertNotNull(typeElement); + Assert.assertEquals("Object", typeElement.getName()); + + DumbServiceImpl.getInstance(getProject()).setDumb(true); + + PsiClass psiClass = typeElement.resolve(); + Assert.assertNull(psiClass); + + DumbServiceImpl.getInstance(getProject()).setDumb(false); + } + /** * Test a reference to a smali class from a smali class */ @@ -105,6 +124,8 @@ public class ClassReferenceTest extends ResolveTestCase { Assert.assertEquals("blarg", smaliClass.getQualifiedName()); } + + @Override protected Sdk getTestProjectJdk() { return JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk(); From a95d0a43a52560ecd3be975d443d4126523a2e6c Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Sun, 24 Jul 2016 14:37:57 -0700 Subject: [PATCH 08/13] Implement SmaliClass.getPresentation This fixes an issue when trying to use ctrl+n to find a smali class --- .../src/main/java/org/jf/smalidea/psi/impl/SmaliClass.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClass.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClass.java index 684293fa..c7e7321d 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClass.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClass.java @@ -35,6 +35,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.intellij.debugger.SourcePosition; import com.intellij.lang.ASTNode; +import com.intellij.navigation.ItemPresentation; +import com.intellij.navigation.ItemPresentationProviders; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; @@ -86,6 +88,10 @@ public class SmaliClass extends SmaliStubBasedPsiElement impleme return name.substring(lastDot+1); } + @Override public ItemPresentation getPresentation() { + return ItemPresentationProviders.getItemPresentation(this); + } + @Nullable @Override public String getQualifiedName() { SmaliClassStatement classStatement = getStubOrPsiChild(SmaliElementTypes.CLASS_STATEMENT); if (classStatement == null) { From 3aad871652025f8410051561f8e31e6b6ca140cc Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Sun, 24 Jul 2016 15:04:57 -0700 Subject: [PATCH 09/13] Add more info to troubleshoot crashes related to LazyValue.getValue being null --- .../jf/smalidea/debugging/value/LazyValue.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/smalidea/src/main/java/org/jf/smalidea/debugging/value/LazyValue.java b/smalidea/src/main/java/org/jf/smalidea/debugging/value/LazyValue.java index 746a629b..0eeb010b 100644 --- a/smalidea/src/main/java/org/jf/smalidea/debugging/value/LazyValue.java +++ b/smalidea/src/main/java/org/jf/smalidea/debugging/value/LazyValue.java @@ -102,13 +102,16 @@ public class LazyValue implements Value { } @Nullable - private T getNullableValue() { + protected T getNullableValue(boolean allowNull) { if (value == null) { try { if (evaluationContext == null) { final DebuggerContextImpl debuggerContext = DebuggerManagerEx.getInstanceEx(project).getContext(); evaluationContext = debuggerContext.createEvaluationContext(); if (evaluationContext == null) { + if (!allowNull) { + throw new IllegalStateException("Can't create evaluation context"); + } return null; } } @@ -116,6 +119,9 @@ public class LazyValue implements Value { value = SmaliCodeFragmentFactory.evaluateRegister(evaluationContext, method, registerNumber, type); evaluationContext = null; } catch (EvaluateException ex) { + if (!allowNull) { + throw new IllegalStateException(ex); + } return null; } } @@ -124,7 +130,7 @@ public class LazyValue implements Value { @Nonnull protected T getValue() { - T value = getNullableValue(); + T value = getNullableValue(false); assert value != null; return value; } @@ -154,7 +160,7 @@ public class LazyValue implements Value { } @Override public boolean equals(Object obj) { - Value value = getNullableValue(); + Value value = getNullableValue(true); if (value != null) { return value.equals(obj); } @@ -162,7 +168,7 @@ public class LazyValue implements Value { } @Override public int hashCode() { - Value value = getNullableValue(); + Value value = getNullableValue(true); if (value != null) { return value.hashCode(); } @@ -170,7 +176,7 @@ public class LazyValue implements Value { } @Override public String toString() { - Value value = getNullableValue(); + Value value = getNullableValue(true); if (value != null) { return value.toString(); } From a5d82813f1519197ffb5471be75cd915564ffacb Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Sun, 24 Jul 2016 15:12:24 -0700 Subject: [PATCH 10/13] Call ContextUtil.getSourcePosition on the debugger manager thread --- .../debugging/SmaliSteppingCommandProvider.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliSteppingCommandProvider.java b/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliSteppingCommandProvider.java index 4be1e7f0..8c756810 100644 --- a/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliSteppingCommandProvider.java +++ b/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliSteppingCommandProvider.java @@ -35,6 +35,7 @@ import com.intellij.debugger.SourcePosition; import com.intellij.debugger.engine.ContextUtil; import com.intellij.debugger.engine.DebugProcessImpl.ResumeCommand; import com.intellij.debugger.engine.SuspendContextImpl; +import com.intellij.debugger.engine.events.DebuggerCommandImpl; import com.intellij.debugger.impl.JvmSteppingCommandProvider; import com.sun.jdi.request.StepRequest; import org.jetbrains.annotations.NotNull; @@ -44,8 +45,16 @@ public class SmaliSteppingCommandProvider extends JvmSteppingCommandProvider { @Override public ResumeCommand getStepOverCommand(@NotNull final SuspendContextImpl suspendContext, boolean ignoreBreakpoints, int stepSize) { - SourcePosition locationPosition = ContextUtil.getSourcePosition(suspendContext); - if (locationPosition != null && locationPosition.getFile().getLanguage() == SmaliLanguage.INSTANCE) { + + final SourcePosition[] location = new SourcePosition[1]; + + suspendContext.getDebugProcess().getManagerThread().invokeAndWait(new DebuggerCommandImpl() { + @Override protected void action() throws Exception { + location[0] = ContextUtil.getSourcePosition(suspendContext); + } + }) ; + + if (location[0] != null && location[0].getFile().getLanguage() == SmaliLanguage.INSTANCE) { return suspendContext.getDebugProcess().createStepOverCommand(suspendContext, ignoreBreakpoints, StepRequest.STEP_MIN); } From afc1f1593936326e1c99f8328bbce8b495865000 Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Thu, 4 Aug 2016 17:31:18 +0100 Subject: [PATCH 11/13] smali/dexlib: deal with invoke-polymorphic / invoke-polymorphic/range. - Introduces two new instruction formats, 45cc and 4rcc. As the name suggests, these instructions are similar to 35c and 3rc, expect that they encode an additional constant pool reference in their 4th byte. - Introduce two new instructions, invoke-polymorphic and invoke-polymorphic/range - used to implement signature polymorphism. - Allow instructions to directly reference the proto_id section of the dex file. This involves the introduction of a new kind of reference (MethodProtoReference) and has the side effect of cleaning up a fair amount of special casing in ProtoPool. - Disable support for ART version based switches (and remove LambdaTest which depends on it). Experimental lambda support and support for ART version based switches will be removed in a follow up change. Bug: 30550796 Test: test-art Test: ./gradlew build --- .../Format/InstructionMethodItem.java | 66 +++++++++--- .../src/main/java/org/jf/dexlib2/Format.java | 2 + .../src/main/java/org/jf/dexlib2/Opcode.java | 15 ++- .../java/org/jf/dexlib2/ReferenceType.java | 9 +- .../reference/BaseMethodProtoReference.java | 66 ++++++++++++ .../instruction/BuilderInstruction35c.java | 2 +- .../instruction/BuilderInstruction45cc.java | 87 +++++++++++++++ .../instruction/BuilderInstruction4rcc.java | 72 +++++++++++++ .../instruction/DexBackedInstruction.java | 4 + .../instruction/DexBackedInstruction45cc.java | 101 ++++++++++++++++++ .../instruction/DexBackedInstruction4rcc.java | 80 ++++++++++++++ .../DexBackedMethodProtoReference.java | 77 +++++++++++++ .../reference/DexBackedReference.java | 2 + .../instruction/DualReferenceInstruction.java | 22 ++-- .../instruction/formats/Instruction45cc.java | 38 +++++++ .../instruction/formats/Instruction4rcc.java | 38 +++++++ .../iface/reference/MethodProtoReference.java | 96 +++++++++++++++++ .../instruction/ImmutableInstruction35c.java | 2 +- .../instruction/ImmutableInstruction35mi.java | 2 +- .../instruction/ImmutableInstruction35ms.java | 2 +- .../ImmutableMethodProtoReference.java | 72 +++++++++++++ .../reference/ImmutableReferenceFactory.java | 5 + .../org/jf/dexlib2/util/Preconditions.java | 2 +- .../org/jf/dexlib2/util/ReferenceUtil.java | 19 +++- .../java/org/jf/dexlib2/writer/DexWriter.java | 27 +++-- .../jf/dexlib2/writer/InstructionWriter.java | 74 ++++++++++--- .../org/jf/dexlib2/writer/MethodSection.java | 8 +- .../writer/builder/BuilderMethodPool.java | 8 +- ....java => BuilderMethodProtoReference.java} | 30 ++---- .../builder/BuilderMethodReference.java | 4 +- .../writer/builder/BuilderProtoPool.java | 91 +++++----------- .../jf/dexlib2/writer/builder/DexBuilder.java | 9 +- .../org/jf/dexlib2/writer/pool/DexPool.java | 5 +- .../jf/dexlib2/writer/pool/MethodPool.java | 13 +-- .../dexlib2/writer/pool/PoolMethodProto.java | 56 ++++++++++ .../org/jf/dexlib2/writer/pool/ProtoPool.java | 88 +++------------ smali/src/main/antlr/smaliParser.g | 20 +++- smali/src/main/antlr/smaliTreeWalker.g | 44 ++++++++ smali/src/main/jflex/smaliLexer.jflex | 8 ++ 39 files changed, 1125 insertions(+), 241 deletions(-) create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/base/reference/BaseMethodProtoReference.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/builder/instruction/BuilderInstruction45cc.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/builder/instruction/BuilderInstruction4rcc.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction45cc.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction4rcc.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedMethodProtoReference.java rename baksmali/src/test/java/org/jf/baksmali/LambdaTest.java => dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/DualReferenceInstruction.java (73%) create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction45cc.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction4rcc.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/iface/reference/MethodProtoReference.java create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableMethodProtoReference.java rename dexlib2/src/main/java/org/jf/dexlib2/writer/builder/{BuilderProtoReference.java => BuilderMethodProtoReference.java} (69%) create mode 100644 dexlib2/src/main/java/org/jf/dexlib2/writer/pool/PoolMethodProto.java diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java index fc43d6f1..39485c90 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java @@ -79,11 +79,20 @@ public class InstructionMethodItem extends MethodItem { return opcode.isVolatileFieldAccessor() || opcode == Opcode.THROW_VERIFICATION_ERROR; } + private String writeInvalidItemIndex(InvalidItemIndex ex, int type, IndentingWriter writer) + throws IOException { + writer.write("#"); + writer.write(ex.getMessage()); + writer.write("\n"); + return String.format("%s@%d", ReferenceType.toString(type), ex.getInvalidIndex()); + } + @Override public boolean writeTo(IndentingWriter writer) throws IOException { Opcode opcode = instruction.getOpcode(); String verificationErrorName = null; String referenceString = null; + String referenceString2 = null; boolean commentOutInstruction = false; @@ -100,25 +109,19 @@ public class InstructionMethodItem extends MethodItem { if (instruction instanceof ReferenceInstruction) { ReferenceInstruction referenceInstruction = (ReferenceInstruction)instruction; + String classContext = null; + if (methodDef.classDef.options.useImplicitReferences) { + classContext = methodDef.method.getDefiningClass(); + } + try { Reference reference = referenceInstruction.getReference(); - - String classContext = null; - if (methodDef.classDef.options.useImplicitReferences) { - classContext = methodDef.method.getDefiningClass(); - } - referenceString = ReferenceUtil.getReferenceString(reference, classContext); assert referenceString != null; } catch (InvalidItemIndex ex) { - writer.write("#"); - writer.write(ex.getMessage()); - writer.write("\n"); commentOutInstruction = true; - - referenceString = String.format("%s@%d", - ReferenceType.toString(referenceInstruction.getReferenceType()), - ex.getInvalidIndex()); + referenceString = writeInvalidItemIndex(ex, referenceInstruction.getReferenceType(), + writer); } catch (ReferenceType.InvalidReferenceTypeException ex) { writer.write("#invalid reference type: "); writer.printSignedIntAsDec(ex.getReferenceType()); @@ -126,6 +129,25 @@ public class InstructionMethodItem extends MethodItem { referenceString = "invalid_reference"; } + + if (instruction instanceof DualReferenceInstruction) { + DualReferenceInstruction dualReferenceInstruction = + (DualReferenceInstruction) instruction; + try { + Reference reference2 = dualReferenceInstruction.getReference2(); + referenceString2 = ReferenceUtil.getReferenceString(reference2, classContext); + } catch (InvalidItemIndex ex) { + commentOutInstruction = true; + referenceString2 = writeInvalidItemIndex(ex, + dualReferenceInstruction.getReferenceType2(), writer); + } catch (ReferenceType.InvalidReferenceTypeException ex) { + writer.write("#invalid reference type: "); + writer.printSignedIntAsDec(ex.getReferenceType()); + commentOutInstruction = true; + + referenceString2 = "invalid_reference"; + } + } } if (instruction instanceof Instruction31t) { @@ -355,6 +377,24 @@ public class InstructionMethodItem extends MethodItem { writer.write(", "); writeVtableIndex(writer); break; + case Format45cc: + writeOpcode(writer); + writer.write(' '); + writeInvokeRegisters(writer); + writer.write(", "); + writer.write(referenceString); + writer.write(", "); + writer.write(referenceString2); + break; + case Format4rcc: + writeOpcode(writer); + writer.write(' '); + writeInvokeRangeRegisters(writer); + writer.write(", "); + writer.write(referenceString); + writer.write(", "); + writer.write(referenceString2); + break; default: assert false; return false; diff --git a/dexlib2/src/main/java/org/jf/dexlib2/Format.java b/dexlib2/src/main/java/org/jf/dexlib2/Format.java index ee34aa50..42e8e144 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/Format.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/Format.java @@ -63,6 +63,8 @@ public enum Format { Format3rc(6), Format3rmi(6), Format3rms(6), + Format45cc(8), + Format4rcc(8), Format51l(10), ArrayPayload(-1, true), PackedSwitchPayload(-1, true), diff --git a/dexlib2/src/main/java/org/jf/dexlib2/Opcode.java b/dexlib2/src/main/java/org/jf/dexlib2/Opcode.java index 3a642358..9559760a 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/Opcode.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/Opcode.java @@ -294,8 +294,8 @@ public enum Opcode INVOKE_VIRTUAL_QUICK(combine(allApis(0xf8), allArtVersions(0xe9)), "invoke-virtual-quick", ReferenceType.NONE, Format.Format35ms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT), INVOKE_VIRTUAL_QUICK_RANGE(combine(allApis(0xf9), allArtVersions(0xea)), "invoke-virtual-quick/range", ReferenceType.NONE, Format.Format3rms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT), - INVOKE_SUPER_QUICK(allApis(0xfa), "invoke-super-quick", ReferenceType.NONE, Format.Format35ms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT), - INVOKE_SUPER_QUICK_RANGE(allApis(0xfb), "invoke-super-quick/range", ReferenceType.NONE, Format.Format3rms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT), + INVOKE_SUPER_QUICK(lastApi(0xfa, 25), "invoke-super-quick", ReferenceType.NONE, Format.Format35ms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT), + INVOKE_SUPER_QUICK_RANGE(lastApi(0xfb, 25), "invoke-super-quick/range", ReferenceType.NONE, Format.Format3rms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT), IPUT_OBJECT_VOLATILE(firstApi(0xfc, 9), "iput-object-volatile", ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.VOLATILE_FIELD_ACCESSOR | Opcode.CAN_THROW | Opcode.CAN_CONTINUE), SGET_OBJECT_VOLATILE(firstApi(0xfd, 9), "sget-object-volatile", ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.VOLATILE_FIELD_ACCESSOR | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.STATIC_FIELD_ACCESSOR), @@ -313,7 +313,9 @@ public enum Opcode // TODO: do we need a capture/liberate wide? LIBERATE_VARIABLE(allArtVersions(0xf7), "liberate-variable", ReferenceType.STRING, Format.Format22c, Opcode.SETS_REGISTER | Opcode.EXPERIMENTAL), BOX_LAMBDA(allArtVersions(0xf8), "box-lambda", ReferenceType.NONE, Format.Format22x, Opcode.SETS_REGISTER | Opcode.EXPERIMENTAL), - UNBOX_LAMBDA(allArtVersions(0xf9), "unbox-lambda", ReferenceType.TYPE, Format.Format22c, Opcode.SETS_REGISTER | Opcode.EXPERIMENTAL); + UNBOX_LAMBDA(allArtVersions(0xf9), "unbox-lambda", ReferenceType.TYPE, Format.Format22c, Opcode.SETS_REGISTER | Opcode.EXPERIMENTAL), + INVOKE_POLYMORPHIC(firstApi(0xfa, 26), "invoke-polymorphic", ReferenceType.METHOD, ReferenceType.METHOD_PROTO, Format.Format45cc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT), + INVOKE_POLYMORPHIC_RANGE(firstApi(0xfb, 26), "invoke-polymorphic/range", ReferenceType.METHOD, ReferenceType.METHOD_PROTO, Format.Format4rcc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT); //if the instruction can throw an exception public static final int CAN_THROW = 0x1; @@ -359,6 +361,7 @@ public enum Opcode public final int referenceType; public final Format format; public final int flags; + public final int referenceType2; Opcode(int opcodeValue, String opcodeName, int referenceType, Format format) { this(opcodeValue, opcodeName, referenceType, format, 0); @@ -369,6 +372,11 @@ public enum Opcode } Opcode(List versionConstraints, String opcodeName, int referenceType, Format format, int flags) { + this(versionConstraints, opcodeName, referenceType, -1, format, flags); + } + + Opcode(List versionConstraints, String opcodeName, int referenceType, int referenceType2, + Format format, int flags) { ImmutableRangeMap.Builder apiToValueBuilder = ImmutableRangeMap.builder(); ImmutableRangeMap.Builder artVersionToValueBuilder = ImmutableRangeMap.builder(); @@ -385,6 +393,7 @@ public enum Opcode this.artVersionToValueMap = artVersionToValueBuilder.build(); this.name = opcodeName; this.referenceType = referenceType; + this.referenceType2 = referenceType2; this.format = format; this.flags = flags; } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/ReferenceType.java b/dexlib2/src/main/java/org/jf/dexlib2/ReferenceType.java index 3371f818..fa8b9687 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/ReferenceType.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/ReferenceType.java @@ -39,7 +39,8 @@ public final class ReferenceType { public static final int TYPE = 1; public static final int FIELD = 2; public static final int METHOD = 3; - public static final int NONE = 4; + public static final int METHOD_PROTO = 4; + public static final int NONE = 5; public static String toString(int referenceType) { switch (referenceType) { @@ -51,6 +52,8 @@ public final class ReferenceType { return "field"; case METHOD: return "method"; + case METHOD_PROTO: + return "method_proto"; default: throw new InvalidReferenceTypeException(referenceType); } @@ -65,6 +68,8 @@ public final class ReferenceType { return FIELD; } else if (reference instanceof MethodReference) { return METHOD; + } else if (reference instanceof MethodProtoReference) { + return METHOD_PROTO; } else { throw new IllegalStateException("Invalid reference"); } @@ -76,7 +81,7 @@ public final class ReferenceType { * @throws InvalidReferenceTypeException */ public static void validateReferenceType(int referenceType) { - if (referenceType < 0 || referenceType > 3) { + if (referenceType < 0 || referenceType > 4) { throw new InvalidReferenceTypeException(referenceType); } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/base/reference/BaseMethodProtoReference.java b/dexlib2/src/main/java/org/jf/dexlib2/base/reference/BaseMethodProtoReference.java new file mode 100644 index 00000000..c0d38b0b --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/base/reference/BaseMethodProtoReference.java @@ -0,0 +1,66 @@ +/* + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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.jf.dexlib2.base.reference; + +import com.google.common.collect.Ordering; +import org.jf.dexlib2.iface.reference.MethodProtoReference; +import org.jf.util.CharSequenceUtils; +import org.jf.util.CollectionUtils; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + + +public abstract class BaseMethodProtoReference implements MethodProtoReference { + @Override + public int hashCode() { + int hashCode = getReturnType().hashCode(); + return hashCode*31 + getParameterTypes().hashCode(); + } + + @Override + public boolean equals(@Nullable Object o) { + if (o instanceof MethodProtoReference) { + MethodProtoReference other = (MethodProtoReference)o; + return getReturnType().equals(other.getReturnType()) && + CharSequenceUtils.listEquals(getParameterTypes(), other.getParameterTypes()); + } + return false; + } + + @Override + public int compareTo(@Nonnull MethodProtoReference o) { + int res = getReturnType().compareTo(o.getReturnType()); + if (res != 0) return res; + return CollectionUtils.compareAsIterable(Ordering.usingToString(), getParameterTypes(), o.getParameterTypes()); + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/builder/instruction/BuilderInstruction35c.java b/dexlib2/src/main/java/org/jf/dexlib2/builder/instruction/BuilderInstruction35c.java index 283464fe..5ec58a92 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/builder/instruction/BuilderInstruction35c.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/builder/instruction/BuilderInstruction35c.java @@ -60,7 +60,7 @@ public class BuilderInstruction35c extends BuilderInstruction implements Instruc int registerG, @Nonnull Reference reference) { super(opcode); - this.registerCount = Preconditions.check35cRegisterCount(registerCount); + this.registerCount = Preconditions.check35cAnd45ccRegisterCount(registerCount); this.registerC = (registerCount>0) ? Preconditions.checkNibbleRegister(registerC) : 0; this.registerD = (registerCount>1) ? Preconditions.checkNibbleRegister(registerD) : 0; this.registerE = (registerCount>2) ? Preconditions.checkNibbleRegister(registerE) : 0; diff --git a/dexlib2/src/main/java/org/jf/dexlib2/builder/instruction/BuilderInstruction45cc.java b/dexlib2/src/main/java/org/jf/dexlib2/builder/instruction/BuilderInstruction45cc.java new file mode 100644 index 00000000..b0e3f427 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/builder/instruction/BuilderInstruction45cc.java @@ -0,0 +1,87 @@ +/* + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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.jf.dexlib2.builder.instruction; + +import org.jf.dexlib2.Format; +import org.jf.dexlib2.Opcode; +import org.jf.dexlib2.builder.BuilderInstruction; +import org.jf.dexlib2.iface.instruction.formats.Instruction45cc; +import org.jf.dexlib2.iface.reference.Reference; +import org.jf.dexlib2.util.Preconditions; + +import javax.annotation.Nonnull; + +public class BuilderInstruction45cc extends BuilderInstruction implements Instruction45cc { + public static final Format FORMAT = Format.Format45cc; + + protected final int registerCount; + protected final int registerC; + protected final int registerD; + protected final int registerE; + protected final int registerF; + protected final int registerG; + @Nonnull protected final Reference reference; + @Nonnull protected final Reference reference2; + + public BuilderInstruction45cc(@Nonnull Opcode opcode, + int registerCount, + int registerC, + int registerD, + int registerE, + int registerF, + int registerG, + @Nonnull Reference reference, + @Nonnull Reference reference2) { + super(opcode); + this.registerCount = Preconditions.check35cAnd45ccRegisterCount(registerCount); + this.registerC = (registerCount>0) ? Preconditions.checkNibbleRegister(registerC) : 0; + this.registerD = (registerCount>1) ? Preconditions.checkNibbleRegister(registerD) : 0; + this.registerE = (registerCount>2) ? Preconditions.checkNibbleRegister(registerE) : 0; + this.registerF = (registerCount>3) ? Preconditions.checkNibbleRegister(registerF) : 0; + this.registerG = (registerCount>4) ? Preconditions.checkNibbleRegister(registerG) : 0; + this.reference = reference; + this.reference2 = reference2; + } + + @Override public int getRegisterCount() { return registerCount; } + @Override public int getRegisterC() { return registerC; } + @Override public int getRegisterD() { return registerD; } + @Override public int getRegisterE() { return registerE; } + @Override public int getRegisterF() { return registerF; } + @Override public int getRegisterG() { return registerG; } + @Nonnull @Override public Reference getReference() { return reference; } + @Override public int getReferenceType() { return opcode.referenceType; } + @Nonnull @Override public Reference getReference2() { return reference2; } + @Override public int getReferenceType2() { return opcode.referenceType2; } + + @Override public Format getFormat() { return FORMAT; } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/builder/instruction/BuilderInstruction4rcc.java b/dexlib2/src/main/java/org/jf/dexlib2/builder/instruction/BuilderInstruction4rcc.java new file mode 100644 index 00000000..3ee7ef9d --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/builder/instruction/BuilderInstruction4rcc.java @@ -0,0 +1,72 @@ +/* + * Copyright 2012, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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.jf.dexlib2.builder.instruction; + +import org.jf.dexlib2.Format; +import org.jf.dexlib2.Opcode; +import org.jf.dexlib2.builder.BuilderInstruction; +import org.jf.dexlib2.iface.instruction.formats.Instruction4rcc; +import org.jf.dexlib2.iface.reference.Reference; +import org.jf.dexlib2.util.Preconditions; + +import javax.annotation.Nonnull; + +public class BuilderInstruction4rcc extends BuilderInstruction implements Instruction4rcc { + public static final Format FORMAT = Format.Format4rcc; + + protected final int startRegister; + protected final int registerCount; + + @Nonnull protected final Reference reference; + @Nonnull protected final Reference reference2; + + public BuilderInstruction4rcc(@Nonnull Opcode opcode, + int startRegister, + int registerCount, + @Nonnull Reference reference, + @Nonnull Reference reference2) { + super(opcode); + this.startRegister = Preconditions.checkShortRegister(startRegister); + this.registerCount = Preconditions.checkRegisterRangeCount(registerCount); + this.reference = reference; + this.reference2 = reference2; + } + + @Override public int getStartRegister() { return startRegister; } + @Override public int getRegisterCount() { return registerCount; } + @Nonnull @Override public Reference getReference() { return reference; } + @Override public int getReferenceType() { return opcode.referenceType; } + @Nonnull @Override public Reference getReference2() { return reference2; } + @Override public int getReferenceType2() { return opcode.referenceType2; } + + @Override public Format getFormat() { return FORMAT; } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction.java index ac82f4b4..2973398a 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction.java @@ -139,6 +139,10 @@ public abstract class DexBackedInstruction implements Instruction { return new DexBackedInstruction3rmi(dexFile, opcode, instructionStartOffset); case Format3rms: return new DexBackedInstruction3rms(dexFile, opcode, instructionStartOffset); + case Format45cc: + return new DexBackedInstruction45cc(dexFile, opcode, instructionStartOffset); + case Format4rcc: + return new DexBackedInstruction4rcc(dexFile, opcode, instructionStartOffset); case Format51l: return new DexBackedInstruction51l(dexFile, opcode, instructionStartOffset); case PackedSwitchPayload: diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction45cc.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction45cc.java new file mode 100644 index 00000000..bbdc229f --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction45cc.java @@ -0,0 +1,101 @@ +/* + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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.jf.dexlib2.dexbacked.instruction; + +import org.jf.dexlib2.Opcode; +import org.jf.dexlib2.dexbacked.DexBackedDexFile; +import org.jf.dexlib2.dexbacked.reference.DexBackedReference; +import org.jf.dexlib2.iface.instruction.formats.Instruction45cc; +import org.jf.dexlib2.iface.reference.Reference; +import org.jf.util.NibbleUtils; + +import javax.annotation.Nonnull; + +public class DexBackedInstruction45cc extends DexBackedInstruction implements Instruction45cc { + public DexBackedInstruction45cc(@Nonnull DexBackedDexFile dexFile, + @Nonnull Opcode opcode, + int instructionStart) { + super(dexFile, opcode, instructionStart); + } + + @Override public int getRegisterCount() { + return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 1)); + } + + @Override + public int getRegisterC() { + return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 4)); + } + + @Override + public int getRegisterD() { + return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 4)); + } + + @Override + public int getRegisterE() { + return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 5)); + } + + @Override + public int getRegisterF() { + return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 5)); + } + + @Override + public int getRegisterG() { + return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 1)); + } + + @Nonnull + @Override + public Reference getReference() { + return DexBackedReference.makeReference(dexFile, opcode.referenceType, + dexFile.readUshort(instructionStart + 2)); + } + + @Override + public int getReferenceType() { + return opcode.referenceType; + } + + @Override + public Reference getReference2() { + return DexBackedReference.makeReference(dexFile, opcode.referenceType2, + dexFile.readUshort(instructionStart + 3)); + } + + @Override + public int getReferenceType2() { + return opcode.referenceType2; + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction4rcc.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction4rcc.java new file mode 100644 index 00000000..629e753b --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction4rcc.java @@ -0,0 +1,80 @@ +/* + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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.jf.dexlib2.dexbacked.instruction; + +import org.jf.dexlib2.Opcode; +import org.jf.dexlib2.dexbacked.DexBackedDexFile; +import org.jf.dexlib2.dexbacked.reference.DexBackedReference; +import org.jf.dexlib2.iface.instruction.formats.Instruction4rcc; +import org.jf.dexlib2.iface.reference.Reference; + +import javax.annotation.Nonnull; + +public class DexBackedInstruction4rcc extends DexBackedInstruction implements Instruction4rcc { + public DexBackedInstruction4rcc(@Nonnull DexBackedDexFile dexFile, + @Nonnull Opcode opcode, + int instructionStart) { + super(dexFile, opcode, instructionStart); + } + + @Override public int getRegisterCount() { + return dexFile.readUbyte(instructionStart + 1); + } + + @Override + public int getStartRegister() { + return dexFile.readUshort(instructionStart + 4); + } + + @Nonnull + @Override + public Reference getReference() { + return DexBackedReference.makeReference(dexFile, opcode.referenceType, + dexFile.readUshort(instructionStart + 2)); + } + + @Override + public int getReferenceType() { + return opcode.referenceType; + } + + @Override + public Reference getReference2() { + return DexBackedReference.makeReference(dexFile, opcode.referenceType2, + dexFile.readUshort(instructionStart + 3)); + } + + @Override + public int getReferenceType2() { + return opcode.referenceType2; + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedMethodProtoReference.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedMethodProtoReference.java new file mode 100644 index 00000000..12875b7b --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedMethodProtoReference.java @@ -0,0 +1,77 @@ +/* + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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.jf.dexlib2.dexbacked.reference; + +import com.google.common.collect.ImmutableList; +import org.jf.dexlib2.base.reference.BaseMethodProtoReference; +import org.jf.dexlib2.dexbacked.DexBackedDexFile; +import org.jf.dexlib2.dexbacked.raw.ProtoIdItem; +import org.jf.dexlib2.dexbacked.raw.TypeListItem; +import org.jf.dexlib2.dexbacked.util.FixedSizeList; + +import java.util.List; +import javax.annotation.Nonnull; + +public class DexBackedMethodProtoReference extends BaseMethodProtoReference { + @Nonnull public final DexBackedDexFile dexFile; + private final int protoIdItemOffset; + + public DexBackedMethodProtoReference(@Nonnull DexBackedDexFile dexFile, int protoIndex) { + this.dexFile = dexFile; + this.protoIdItemOffset = dexFile.getProtoIdItemOffset(protoIndex); + } + + @Nonnull + @Override + public List getParameterTypes() { + final int parametersOffset = dexFile.readSmallUint(protoIdItemOffset + ProtoIdItem.PARAMETERS_OFFSET); + if (parametersOffset > 0) { + final int parameterCount = dexFile.readSmallUint(parametersOffset + TypeListItem.SIZE_OFFSET); + final int paramListStart = parametersOffset + TypeListItem.LIST_OFFSET; + return new FixedSizeList() { + @Nonnull + @Override + public String readItem(final int index) { + return dexFile.getType(dexFile.readUshort(paramListStart + 2*index)); + } + @Override public int size() { return parameterCount; } + }; + } + return ImmutableList.of(); + } + + @Nonnull + @Override + public String getReturnType() { + return dexFile.getType(dexFile.readSmallUint(protoIdItemOffset + ProtoIdItem.RETURN_TYPE_OFFSET)); + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedReference.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedReference.java index b63c37c2..99d66ecd 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedReference.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/reference/DexBackedReference.java @@ -49,6 +49,8 @@ public abstract class DexBackedReference { return new DexBackedMethodReference(dexFile, referenceIndex); case ReferenceType.FIELD: return new DexBackedFieldReference(dexFile, referenceIndex); + case ReferenceType.METHOD_PROTO: + return new DexBackedMethodProtoReference(dexFile, referenceIndex); default: throw new ExceptionWithContext("Invalid reference type: %d", referenceType); } diff --git a/baksmali/src/test/java/org/jf/baksmali/LambdaTest.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/DualReferenceInstruction.java similarity index 73% rename from baksmali/src/test/java/org/jf/baksmali/LambdaTest.java rename to dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/DualReferenceInstruction.java index 5431df54..0f1f81b2 100644 --- a/baksmali/src/test/java/org/jf/baksmali/LambdaTest.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/DualReferenceInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright 2015, Google Inc. + * Copyright 2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,21 +29,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.jf.baksmali; +package org.jf.dexlib2.iface.instruction; -import org.junit.Test; +import org.jf.dexlib2.iface.reference.Reference; -public class LambdaTest extends IdenticalRoundtripTest { +import javax.annotation.Nonnull; - private baksmaliOptions createOptions() { - baksmaliOptions options = new baksmaliOptions(); - options.apiLevel = 23; // since we need at least level 23 for lambda opcodes - options.experimental = true; // since these opcodes aren't implemented in runtime yet); - return options; - } - - @Test - public void testHelloWorldLambda() { - runTest("HelloWorldLambda", createOptions()); - } +public interface DualReferenceInstruction extends ReferenceInstruction { + @Nonnull Reference getReference2(); + int getReferenceType2(); } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction45cc.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction45cc.java new file mode 100644 index 00000000..221fd623 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction45cc.java @@ -0,0 +1,38 @@ +/* + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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.jf.dexlib2.iface.instruction.formats; + +import org.jf.dexlib2.iface.instruction.DualReferenceInstruction; +import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction; + +public interface Instruction45cc extends FiveRegisterInstruction, DualReferenceInstruction { +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction4rcc.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction4rcc.java new file mode 100644 index 00000000..d0b930b1 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction4rcc.java @@ -0,0 +1,38 @@ +/* + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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.jf.dexlib2.iface.instruction.formats; + +import org.jf.dexlib2.iface.instruction.DualReferenceInstruction; +import org.jf.dexlib2.iface.instruction.RegisterRangeInstruction; + +public interface Instruction4rcc extends RegisterRangeInstruction, DualReferenceInstruction { +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/MethodProtoReference.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/MethodProtoReference.java new file mode 100644 index 00000000..e150c214 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/iface/reference/MethodProtoReference.java @@ -0,0 +1,96 @@ +/* + * Copyright 20116, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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.jf.dexlib2.iface.reference; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; + +/** + * This class represents a reference to a method prototype. + */ +public interface MethodProtoReference extends Reference, Comparable { + /** + * Gets a list of the types of the parameters of this method prototype. + * + * @return A list of the parameter types of this method prototype, as strings. + */ + @Nonnull List getParameterTypes(); + + /** + * Gets the return type of the referenced method prototype. + * + * @return The return type of the referenced method prototype. + */ + @Nonnull String getReturnType(); + + /** + * Returns a hashcode for this MethodProtoReference. + * + * This hashCode is defined to be the following: + * + *
+     * {@code
+     * int hashCode =  getReturnType().hashCode();
+     * hashCode = hashCode*31 + CharSequenceUtils.listHashCode(getParameters());
+     * }
+ * + * @return The hash code value for this ProtoReference + */ + @Override int hashCode(); + + /** + * Compares this MethodTypeReference to another MethodProtoReference for equality. + * + * This MethodTypeReference is equal to another MethodProtoReference if all of it's "fields" are equal. That is, if + * the return values of getReturnType() and getParameterTypes() are all equal. + * + * Equality for getParameters() should be tested by comparing the string representation of each element. I.e. + * CharSequenceUtils.listEquals(this.getParameterTypes(), other.getParameterTypes()) + * + * @param o The object to be compared for equality with this MethodProtoReference + * @return true if the specified object is equal to this MethodProtoReference + */ + @Override boolean equals(@Nullable Object o); + + /** + * Compare this MethodTypeReference to another MethodProtoReference. + * + * The comparison is based on the comparison of the return values of getReturnType() and getParameters(), + * in that order. getParameters() should be compared using the semantics of + * org.jf.util.CollectionUtils.compareAsList() + * + * @param o The MethodReference to compare with this MethodProtoReference + * @return An integer representing the result of the comparison + */ + @Override int compareTo(@Nonnull MethodProtoReference o); +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction35c.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction35c.java index 20976f80..7ac1a8f6 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction35c.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction35c.java @@ -61,7 +61,7 @@ public class ImmutableInstruction35c extends ImmutableInstruction implements Ins int registerG, @Nonnull Reference reference) { super(opcode); - this.registerCount = Preconditions.check35cRegisterCount(registerCount); + this.registerCount = Preconditions.check35cAnd45ccRegisterCount(registerCount); this.registerC = (registerCount>0) ? Preconditions.checkNibbleRegister(registerC) : 0; this.registerD = (registerCount>1) ? Preconditions.checkNibbleRegister(registerD) : 0; this.registerE = (registerCount>2) ? Preconditions.checkNibbleRegister(registerE) : 0; diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction35mi.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction35mi.java index def7eb60..5e58cae9 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction35mi.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction35mi.java @@ -58,7 +58,7 @@ public class ImmutableInstruction35mi extends ImmutableInstruction implements In int registerG, int inlineIndex) { super(opcode); - this.registerCount = Preconditions.check35cRegisterCount(registerCount); + this.registerCount = Preconditions.check35cAnd45ccRegisterCount(registerCount); this.registerC = (registerCount>0) ? Preconditions.checkNibbleRegister(registerC) : 0; this.registerD = (registerCount>1) ? Preconditions.checkNibbleRegister(registerD) : 0; this.registerE = (registerCount>2) ? Preconditions.checkNibbleRegister(registerE) : 0; diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction35ms.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction35ms.java index 16d7e913..0130f474 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction35ms.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction35ms.java @@ -58,7 +58,7 @@ public class ImmutableInstruction35ms extends ImmutableInstruction implements In int registerG, int vtableIndex) { super(opcode); - this.registerCount = Preconditions.check35cRegisterCount(registerCount); + this.registerCount = Preconditions.check35cAnd45ccRegisterCount(registerCount); this.registerC = (registerCount>0) ? Preconditions.checkNibbleRegister(registerC) : 0; this.registerD = (registerCount>1) ? Preconditions.checkNibbleRegister(registerD) : 0; this.registerE = (registerCount>2) ? Preconditions.checkNibbleRegister(registerE) : 0; diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableMethodProtoReference.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableMethodProtoReference.java new file mode 100644 index 00000000..8c2afe59 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableMethodProtoReference.java @@ -0,0 +1,72 @@ +/* + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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.jf.dexlib2.immutable.reference; + +import com.google.common.collect.ImmutableList; +import org.jf.dexlib2.base.reference.BaseMethodProtoReference; +import org.jf.dexlib2.iface.reference.MethodProtoReference; +import org.jf.dexlib2.immutable.util.CharSequenceConverter; + +import java.util.List; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class ImmutableMethodProtoReference extends BaseMethodProtoReference implements ImmutableReference { + @Nonnull protected final ImmutableList parameters; + @Nonnull protected final String returnType; + + public ImmutableMethodProtoReference(@Nullable Iterable parameters, + @Nonnull String returnType) { + this.parameters = CharSequenceConverter.immutableStringList(parameters); + this.returnType = returnType; + } + + @Nonnull public static ImmutableMethodProtoReference of(@Nonnull MethodProtoReference methodProtoReference) { + if (methodProtoReference instanceof ImmutableMethodProtoReference) { + return (ImmutableMethodProtoReference) methodProtoReference; + } + return new ImmutableMethodProtoReference( + methodProtoReference.getParameterTypes(), + methodProtoReference.getReturnType()); + } + + @Override + public List getParameterTypes() { + return parameters; + } + + @Override + public String getReturnType() { + return returnType; + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableReferenceFactory.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableReferenceFactory.java index 0d27e47f..d0007479 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableReferenceFactory.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/reference/ImmutableReferenceFactory.java @@ -52,6 +52,9 @@ public class ImmutableReferenceFactory { if (reference instanceof MethodReference) { return ImmutableMethodReference.of((MethodReference)reference); } + if (reference instanceof MethodProtoReference) { + return ImmutableMethodProtoReference.of((MethodProtoReference) reference); + } throw new ExceptionWithContext("Invalid reference type"); } @@ -66,6 +69,8 @@ public class ImmutableReferenceFactory { return ImmutableFieldReference.of((FieldReference)reference); case ReferenceType.METHOD: return ImmutableMethodReference.of((MethodReference)reference); + case ReferenceType.METHOD_PROTO: + return ImmutableMethodProtoReference.of((MethodProtoReference)reference); } throw new ExceptionWithContext("Invalid reference type: %d", referenceType); } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java b/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java index 51c083ca..3b30d075 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java @@ -125,7 +125,7 @@ public class Preconditions { return offset; } - public static int check35cRegisterCount(int registerCount) { + public static int check35cAnd45ccRegisterCount(int registerCount) { if (registerCount < 0 || registerCount > 5) { throw new IllegalArgumentException( String.format("Invalid register count: %d. Must be between 0 and 5, inclusive.", registerCount)); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/util/ReferenceUtil.java b/dexlib2/src/main/java/org/jf/dexlib2/util/ReferenceUtil.java index 81b042ec..4e46a0e9 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/util/ReferenceUtil.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/util/ReferenceUtil.java @@ -60,6 +60,17 @@ public final class ReferenceUtil { return sb.toString(); } + public static String getMethodProtoDescriptor(MethodProtoReference methodProtoReference) { + StringBuilder sb = new StringBuilder(); + sb.append('('); + for (CharSequence paramType : methodProtoReference.getParameterTypes()) { + sb.append(paramType); + } + sb.append(')'); + sb.append(methodProtoReference.getReturnType()); + return sb.toString(); + } + public static void writeMethodDescriptor(Writer writer, MethodReference methodReference) throws IOException { writeMethodDescriptor(writer, methodReference, false); } @@ -134,12 +145,16 @@ public final class ReferenceUtil { if (reference instanceof FieldReference) { FieldReference fieldReference = (FieldReference)reference; boolean useImplicitReference = fieldReference.getDefiningClass().equals(containingClass); - return getFieldDescriptor((FieldReference)reference, useImplicitReference); + return getFieldDescriptor(fieldReference, useImplicitReference); } if (reference instanceof MethodReference) { MethodReference methodReference = (MethodReference)reference; boolean useImplicitReference = methodReference.getDefiningClass().equals(containingClass); - return getMethodDescriptor((MethodReference)reference, useImplicitReference); + return getMethodDescriptor(methodReference, useImplicitReference); + } + if (reference instanceof MethodProtoReference) { + MethodProtoReference methodProtoReference = (MethodProtoReference)reference; + return getMethodProtoDescriptor(methodProtoReference); } return null; } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java index 4e81f7fa..5329351e 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java @@ -54,6 +54,7 @@ import org.jf.dexlib2.iface.instruction.OneRegisterInstruction; import org.jf.dexlib2.iface.instruction.ReferenceInstruction; import org.jf.dexlib2.iface.instruction.formats.*; import org.jf.dexlib2.iface.reference.FieldReference; +import org.jf.dexlib2.iface.reference.MethodProtoReference; import org.jf.dexlib2.iface.reference.MethodReference; import org.jf.dexlib2.iface.reference.StringReference; import org.jf.dexlib2.iface.reference.TypeReference; @@ -84,7 +85,7 @@ import java.util.zip.Adler32; public abstract class DexWriter< StringKey extends CharSequence, StringRef extends StringReference, TypeKey extends CharSequence, - TypeRef extends TypeReference, ProtoKey extends Comparable, + TypeRef extends TypeReference, ProtoRefKey extends MethodProtoReference, FieldRefKey extends FieldReference, MethodRefKey extends MethodReference, ClassKey extends Comparable, AnnotationKey extends Annotation, AnnotationSetKey, @@ -125,9 +126,9 @@ public abstract class DexWriter< protected final StringSection stringSection; protected final TypeSection typeSection; - protected final ProtoSection protoSection; + protected final ProtoSection protoSection; protected final FieldSection fieldSection; - protected final MethodSection methodSection; + protected final MethodSection methodSection; protected final ClassSection classSection; @@ -138,9 +139,9 @@ public abstract class DexWriter< protected DexWriter(Opcodes opcodes, StringSection stringSection, TypeSection typeSection, - ProtoSection protoSection, + ProtoSection protoSection, FieldSection fieldSection, - MethodSection methodSection, + MethodSection methodSection, ClassSection classSection, TypeListSection typeListSection, @@ -347,12 +348,12 @@ public abstract class DexWriter< protoSectionOffset = writer.getPosition(); int index = 0; - List> protoEntries = Lists.newArrayList(protoSection.getItems()); - Collections.sort(protoEntries, DexWriter.comparableKeyComparator()); + List> protoEntries = Lists.newArrayList(protoSection.getItems()); + Collections.sort(protoEntries, DexWriter.comparableKeyComparator()); - for (Map.Entry entry: protoEntries) { + for (Map.Entry entry: protoEntries) { entry.setValue(index++); - ProtoKey key = entry.getKey(); + ProtoRefKey key = entry.getKey(); writer.writeInt(stringSection.getItemIndex(protoSection.getShorty(key))); writer.writeInt(typeSection.getItemIndex(protoSection.getReturnType(key))); writer.writeInt(typeListSection.getNullableItemOffset(protoSection.getParameters(key))); @@ -946,7 +947,7 @@ public abstract class DexWriter< InstructionWriter instructionWriter = InstructionWriter.makeInstructionWriter(opcodes, writer, stringSection, typeSection, fieldSection, - methodSection); + methodSection, protoSection); writer.writeInt(codeUnitCount); for (Instruction instruction: instructions) { @@ -1029,6 +1030,12 @@ public abstract class DexWriter< case Format3rc: instructionWriter.write((Instruction3rc)instruction); break; + case Format45cc: + instructionWriter.write((Instruction45cc) instruction); + break; + case Format4rcc: + instructionWriter.write((Instruction4rcc) instruction); + break; case Format51l: instructionWriter.write((Instruction51l)instruction); break; diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/InstructionWriter.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/InstructionWriter.java index f16256c5..c240c515 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/InstructionWriter.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/InstructionWriter.java @@ -36,11 +36,14 @@ import com.google.common.primitives.Ints; import org.jf.dexlib2.Opcode; import org.jf.dexlib2.Opcodes; import org.jf.dexlib2.ReferenceType; +import org.jf.dexlib2.iface.instruction.DualReferenceInstruction; import org.jf.dexlib2.iface.instruction.ReferenceInstruction; import org.jf.dexlib2.iface.instruction.SwitchElement; import org.jf.dexlib2.iface.instruction.formats.*; import org.jf.dexlib2.iface.reference.FieldReference; +import org.jf.dexlib2.iface.reference.MethodProtoReference; import org.jf.dexlib2.iface.reference.MethodReference; +import org.jf.dexlib2.iface.reference.Reference; import org.jf.dexlib2.iface.reference.StringReference; import org.jf.dexlib2.iface.reference.TypeReference; import org.jf.util.ExceptionWithContext; @@ -51,25 +54,29 @@ import java.util.Comparator; import java.util.List; public class InstructionWriter { + FieldRefKey extends FieldReference, MethodRefKey extends MethodReference, + ProtoRefKey extends MethodProtoReference> { @Nonnull private final Opcodes opcodes; @Nonnull private final DexDataWriter writer; @Nonnull private final StringSection stringSection; @Nonnull private final TypeSection typeSection; @Nonnull private final FieldSection fieldSection; @Nonnull private final MethodSection methodSection; + @Nonnull private final ProtoSection protoSection; - @Nonnull static - InstructionWriter + @Nonnull static + InstructionWriter makeInstructionWriter( @Nonnull Opcodes opcodes, @Nonnull DexDataWriter writer, @Nonnull StringSection stringSection, @Nonnull TypeSection typeSection, @Nonnull FieldSection fieldSection, - @Nonnull MethodSection methodSection) { - return new InstructionWriter( - opcodes, writer, stringSection, typeSection, fieldSection, methodSection); + @Nonnull MethodSection methodSection, + @Nonnull ProtoSection protoSection) { + return new InstructionWriter( + opcodes, writer, stringSection, typeSection, fieldSection, methodSection, protoSection); } InstructionWriter(@Nonnull Opcodes opcodes, @@ -77,13 +84,15 @@ public class InstructionWriter stringSection, @Nonnull TypeSection typeSection, @Nonnull FieldSection fieldSection, - @Nonnull MethodSection methodSection) { + @Nonnull MethodSection methodSection, + @Nonnull ProtoSection protoSection) { this.opcodes = opcodes; this.writer = writer; this.stringSection = stringSection; this.typeSection = typeSection; this.fieldSection = fieldSection; this.methodSection = methodSection; + this.protoSection = protoSection; } private short getOpcodeValue(Opcode opcode) { @@ -347,6 +356,7 @@ public class InstructionWriter +public interface MethodSection extends IndexSection { @Nonnull TypeKey getDefiningClass(@Nonnull MethodRefKey key); - @Nonnull ProtoKey getPrototype(@Nonnull MethodRefKey key); - @Nonnull ProtoKey getPrototype(@Nonnull MethodKey key); + @Nonnull ProtoRefKey getPrototype(@Nonnull MethodRefKey key); + @Nonnull ProtoRefKey getPrototype(@Nonnull MethodKey key); @Nonnull StringKey getName(@Nonnull MethodRefKey key); int getMethodIndex(@Nonnull MethodKey key); } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderMethodPool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderMethodPool.java index 7dc924e7..2c5dd816 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderMethodPool.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderMethodPool.java @@ -43,7 +43,7 @@ import java.util.Map.Entry; import java.util.concurrent.ConcurrentMap; class BuilderMethodPool implements MethodSection{ + BuilderMethodProtoReference, BuilderMethodReference, BuilderMethod>{ @Nonnull private final BuilderContext context; @Nonnull private final ConcurrentMap internedItems = Maps.newConcurrentMap(); @@ -61,7 +61,7 @@ class BuilderMethodPool implements MethodSection { +public class BuilderMethodProtoReference extends BaseMethodProtoReference implements + MethodProtoReference, BuilderReference { @Nonnull final BuilderStringReference shorty; @Nonnull final BuilderTypeList parameterTypes; @Nonnull final BuilderTypeReference returnType; int index = DexWriter.NO_INDEX; - public BuilderProtoReference(@Nonnull BuilderStringReference shorty, @Nonnull BuilderTypeList parameterTypes, - @Nonnull BuilderTypeReference returnType) { + public BuilderMethodProtoReference(@Nonnull BuilderStringReference shorty, @Nonnull BuilderTypeList parameterTypes, + @Nonnull BuilderTypeReference returnType) { this.shorty = shorty; this.parameterTypes = parameterTypes; this.returnType = returnType; @@ -62,25 +65,12 @@ public class BuilderProtoReference implements BuilderProtoPool.ProtoKey, Compara } @Override - public int hashCode() { - int hashCode = getReturnType().hashCode(); - return hashCode*31 + getParameterTypes().hashCode(); + public int getIndex() { + return index; } @Override - public boolean equals(@Nullable Object o) { - if (o != null && o instanceof BuilderProtoReference) { - BuilderProtoReference other = (BuilderProtoReference)o; - return returnType.equals(other.returnType) && - CharSequenceUtils.listEquals(parameterTypes, other.parameterTypes); - } - return false; - } - - @Override - public int compareTo(@Nonnull BuilderProtoReference o) { - int res = returnType.compareTo(o.returnType); - if (res != 0) return res; - return CollectionUtils.compareAsIterable(Ordering.usingToString(), parameterTypes, o.parameterTypes); + public void setIndex(int index) { + this.index = index; } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderMethodReference.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderMethodReference.java index c913efa5..96708444 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderMethodReference.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderMethodReference.java @@ -39,12 +39,12 @@ import javax.annotation.Nonnull; public class BuilderMethodReference extends BaseMethodReference implements BuilderReference { @Nonnull final BuilderTypeReference definingClass; @Nonnull final BuilderStringReference name; - @Nonnull final BuilderProtoReference proto; + @Nonnull final BuilderMethodProtoReference proto; int index = DexWriter.NO_INDEX; BuilderMethodReference(@Nonnull BuilderTypeReference definingClass, @Nonnull BuilderStringReference name, - @Nonnull BuilderProtoReference proto) { + @Nonnull BuilderMethodProtoReference proto) { this.definingClass = definingClass; this.name = name; this.proto = proto; diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderProtoPool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderProtoPool.java index 6ed18fe8..de19fa30 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderProtoPool.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/BuilderProtoPool.java @@ -32,114 +32,75 @@ package org.jf.dexlib2.writer.builder; import com.google.common.collect.Maps; +import org.jf.dexlib2.iface.reference.MethodProtoReference; import org.jf.dexlib2.iface.reference.MethodReference; +import org.jf.dexlib2.immutable.reference.ImmutableMethodProtoReference; import org.jf.dexlib2.util.MethodUtil; import org.jf.dexlib2.writer.ProtoSection; -import org.jf.util.CharSequenceUtils; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.Collection; -import java.util.List; import java.util.Map.Entry; import java.util.concurrent.ConcurrentMap; class BuilderProtoPool - implements ProtoSection { + implements ProtoSection { @Nonnull private final BuilderContext context; - @Nonnull private final ConcurrentMap internedItems = + @Nonnull private final ConcurrentMap internedItems = Maps.newConcurrentMap(); BuilderProtoPool(@Nonnull BuilderContext context) { this.context = context; } - @Nonnull public BuilderProtoReference internProto(@Nonnull List parameters, - @Nonnull String returnType) { - ProtoKey key = new Key(parameters, returnType); - BuilderProtoReference ret = internedItems.get(key); + @Nonnull public BuilderMethodProtoReference internMethodProto(@Nonnull MethodProtoReference methodProto) { + BuilderMethodProtoReference ret = internedItems.get(methodProto); if (ret != null) { return ret; } - BuilderProtoReference protoReference = new BuilderProtoReference( - context.stringPool.internString(MethodUtil.getShorty(parameters, returnType)), - context.typeListPool.internTypeList(parameters), - context.typePool.internType(returnType)); + BuilderMethodProtoReference protoReference = new BuilderMethodProtoReference( + context.stringPool.internString(MethodUtil.getShorty( + methodProto.getParameterTypes(), methodProto.getReturnType())), + context.typeListPool.internTypeList(methodProto.getParameterTypes()), + context.typePool.internType(methodProto.getReturnType())); ret = internedItems.putIfAbsent(protoReference, protoReference); return ret==null?protoReference:ret; } - @Nonnull public BuilderProtoReference internProto(@Nonnull MethodReference methodReference) { - return internProto(methodReference.getParameterTypes(), methodReference.getReturnType()); + @Nonnull public BuilderMethodProtoReference internMethodProto(@Nonnull MethodReference methodReference) { + return internMethodProto(new ImmutableMethodProtoReference( + methodReference.getParameterTypes(), methodReference.getReturnType())); } - @Nonnull @Override public BuilderStringReference getShorty(@Nonnull BuilderProtoReference key) { - return key.shorty; + @Nonnull @Override public BuilderStringReference getShorty(@Nonnull BuilderMethodProtoReference proto) { + return proto.shorty; } - @Nonnull @Override public BuilderTypeReference getReturnType(@Nonnull BuilderProtoReference key) { - return key.returnType; + @Nonnull @Override public BuilderTypeReference getReturnType(@Nonnull BuilderMethodProtoReference proto) { + return proto.returnType; } - @Nullable @Override public BuilderTypeList getParameters(@Nonnull BuilderProtoReference key) { - return key.parameterTypes; + @Nullable @Override public BuilderTypeList getParameters(@Nonnull BuilderMethodProtoReference proto) { + return proto.parameterTypes; } - @Override public int getItemIndex(@Nonnull BuilderProtoReference key) { - return key.index; + @Override public int getItemIndex(@Nonnull BuilderMethodProtoReference proto) { + return proto.getIndex(); } - @Nonnull @Override public Collection> getItems() { - return new BuilderMapEntryCollection(internedItems.values()) { - @Override protected int getValue(@Nonnull BuilderProtoReference key) { + @Nonnull @Override public Collection> getItems() { + return new BuilderMapEntryCollection(internedItems.values()) { + @Override protected int getValue(@Nonnull BuilderMethodProtoReference key) { return key.index; } - @Override protected int setValue(@Nonnull BuilderProtoReference key, int value) { + @Override protected int setValue(@Nonnull BuilderMethodProtoReference key, int value) { int prev = key.index; key.index = value; return prev; } }; } - - // a placeholder interface to unify the temporary probing key and the BuilderProtoReference class - interface ProtoKey { - @Nonnull List getParameterTypes(); - @Nonnull String getReturnType(); - } - - // a temporary lightweight class to allow a quick probe if the given prototype has already been interned - private static class Key implements ProtoKey { - @Nonnull private final List parameters; - @Nonnull private final String returnType; - - public Key(@Nonnull List parameters, @Nonnull String returnType) { - this.parameters = parameters; - this.returnType = returnType; - } - - @Nonnull public List getParameterTypes() { - return parameters; - } - - @Nonnull public String getReturnType() { - return returnType; - } - - @Override public int hashCode() { - int hashCode = returnType.hashCode(); - return hashCode*31 + parameters.hashCode(); - } - - @Override public boolean equals(Object o) { - if (o != null && o instanceof ProtoKey) { - ProtoKey other = (ProtoKey)o; - return getReturnType().equals(other.getReturnType()) && - CharSequenceUtils.listEquals(getParameterTypes(), other.getParameterTypes()); - } - return false; - } - } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/DexBuilder.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/DexBuilder.java index d1190249..b7507fa6 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/DexBuilder.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/builder/DexBuilder.java @@ -54,7 +54,7 @@ import java.util.List; import java.util.Set; public class DexBuilder extends DexWriter { @@ -176,6 +176,10 @@ public class DexBuilder extends DexWriter, TypeListPool.Key>, Field, PoolMethod, EncodedValue, AnnotationElement> { diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/MethodPool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/MethodPool.java index 7ae42fb6..8103d319 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/MethodPool.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/MethodPool.java @@ -31,13 +31,14 @@ package org.jf.dexlib2.writer.pool; +import org.jf.dexlib2.iface.reference.MethodProtoReference; import org.jf.dexlib2.iface.reference.MethodReference; import org.jf.dexlib2.writer.MethodSection; import javax.annotation.Nonnull; public class MethodPool extends BaseIndexPool - implements MethodSection { + implements MethodSection { @Nonnull private final StringPool stringPool; @Nonnull private final TypePool typePool; @Nonnull private final ProtoPool protoPool; @@ -53,7 +54,7 @@ public class MethodPool extends BaseIndexPool Integer prev = internedItems.put(method, 0); if (prev == null) { typePool.intern(method.getDefiningClass()); - protoPool.intern(method); + protoPool.intern(new PoolMethodProto(method)); stringPool.intern(method.getName()); } } @@ -62,12 +63,12 @@ public class MethodPool extends BaseIndexPool return methodReference.getDefiningClass(); } - @Nonnull @Override public ProtoPool.Key getPrototype(@Nonnull MethodReference methodReference) { - return new ProtoPool.Key(methodReference); + @Nonnull @Override public MethodProtoReference getPrototype(@Nonnull MethodReference methodReference) { + return new PoolMethodProto(methodReference); } - @Nonnull @Override public ProtoPool.Key getPrototype(@Nonnull PoolMethod poolMethod) { - return new ProtoPool.Key(poolMethod); + @Nonnull @Override public MethodProtoReference getPrototype(@Nonnull PoolMethod poolMethod) { + return new PoolMethodProto(poolMethod); } @Nonnull @Override public CharSequence getName(@Nonnull MethodReference methodReference) { diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/PoolMethodProto.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/PoolMethodProto.java new file mode 100644 index 00000000..d180be1d --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/PoolMethodProto.java @@ -0,0 +1,56 @@ +/* + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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.jf.dexlib2.writer.pool; + +import org.jf.dexlib2.base.reference.BaseMethodProtoReference; +import org.jf.dexlib2.iface.reference.MethodProtoReference; +import org.jf.dexlib2.iface.reference.MethodReference; + +import java.util.List; + +public class PoolMethodProto extends BaseMethodProtoReference implements MethodProtoReference { + private final MethodReference methodReference; + + public PoolMethodProto(MethodReference methodReference) { + this.methodReference = methodReference; + } + + @Override + public List getParameterTypes() { + return methodReference.getParameterTypes(); + } + + @Override + public String getReturnType() { + return methodReference.getReturnType(); + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/ProtoPool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/ProtoPool.java index eeabdf4a..523e5f4d 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/ProtoPool.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/ProtoPool.java @@ -31,21 +31,18 @@ package org.jf.dexlib2.writer.pool; -import com.google.common.collect.Ordering; -import org.jf.dexlib2.iface.reference.MethodReference; +import org.jf.dexlib2.iface.reference.MethodProtoReference; import org.jf.dexlib2.util.MethodUtil; -import org.jf.dexlib2.writer.pool.ProtoPool.Key; import org.jf.dexlib2.writer.ProtoSection; -import org.jf.util.CharSequenceUtils; -import org.jf.util.CollectionUtils; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.Collection; import java.util.List; -public class ProtoPool extends BaseIndexPool - implements ProtoSection>> { +public class ProtoPool extends BaseIndexPool + implements ProtoSection>> { @Nonnull private final StringPool stringPool; @Nonnull private final TypePool typePool; @Nonnull private final TypeListPool typeListPool; @@ -57,78 +54,25 @@ public class ProtoPool extends BaseIndexPool this.typeListPool = typeListPool; } - public void intern(@Nonnull MethodReference method) { - // We can't use method directly, because it is likely a full MethodReference. We use a wrapper that computes - // hashCode and equals based only on the prototype fields - Key key = new Key(method); - Integer prev = internedItems.put(key, 0); + public void intern(@Nonnull MethodProtoReference reference) { + Integer prev = internedItems.put(reference, 0); if (prev == null) { - stringPool.intern(key.getShorty()); - typePool.intern(method.getReturnType()); - typeListPool.intern(method.getParameterTypes()); + stringPool.intern(getShorty(reference)); + typePool.intern(reference.getReturnType()); + typeListPool.intern(reference.getParameterTypes()); } } - @Nonnull @Override public CharSequence getShorty(@Nonnull Key key) { - return key.getShorty(); + @Nonnull @Override public CharSequence getShorty(@Nonnull MethodProtoReference reference) { + return MethodUtil.getShorty(reference.getParameterTypes(), reference.getReturnType()); } - @Nonnull @Override public CharSequence getReturnType(@Nonnull Key key) { - return key.getReturnType(); + @Nonnull @Override public CharSequence getReturnType(@Nonnull MethodProtoReference protoReference) { + return protoReference.getReturnType(); } - @Nullable @Override public TypeListPool.Key> getParameters(@Nonnull Key key) { - return new TypeListPool.Key>(key.getParameters()); - } - - public static class Key implements Comparable { - @Nonnull private final MethodReference method; - - public Key(@Nonnull MethodReference method) { - this.method = method; - } - - @Nonnull public String getReturnType() { return method.getReturnType(); } - @Nonnull public List getParameters() { - return method.getParameterTypes(); - } - - public String getShorty() { - return MethodUtil.getShorty(method.getParameterTypes(), method.getReturnType()); - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append('('); - for (CharSequence paramType: getParameters()) { - sb.append(paramType); - } - sb.append(')'); - sb.append(getReturnType()); - return sb.toString(); - } - - @Override - public int hashCode() { - int hashCode = getReturnType().hashCode(); - return hashCode*31 + CharSequenceUtils.listHashCode(getParameters()); - } - - @Override - public boolean equals(@Nullable Object o) { - if (o instanceof Key) { - Key other = (Key)o; - return getReturnType().equals(other.getReturnType()) && - CharSequenceUtils.listEquals(getParameters(), other.getParameters()); - } - return false; - } - - @Override - public int compareTo(@Nonnull Key o) { - int res = getReturnType().compareTo(o.getReturnType()); - if (res != 0) return res; - return CollectionUtils.compareAsIterable(Ordering.usingToString(), getParameters(), o.getParameters()); - } + @Nullable @Override public TypeListPool.Key> getParameters( + @Nonnull MethodProtoReference methodProto) { + return new TypeListPool.Key>(methodProto.getParameterTypes()); } } diff --git a/smali/src/main/antlr/smaliParser.g b/smali/src/main/antlr/smaliParser.g index fcccbe80..29148f7b 100644 --- a/smali/src/main/antlr/smaliParser.g +++ b/smali/src/main/antlr/smaliParser.g @@ -120,6 +120,8 @@ tokens { INSTRUCTION_FORMAT3rc_TYPE; INSTRUCTION_FORMAT3rmi_METHOD; INSTRUCTION_FORMAT3rms_METHOD; + INSTRUCTION_FORMAT45cc_METHOD; + INSTRUCTION_FORMAT4rcc_METHOD; INSTRUCTION_FORMAT51l; LINE_COMMENT; LINE_DIRECTIVE; @@ -234,6 +236,8 @@ tokens { I_STATEMENT_FORMAT35c_TYPE; I_STATEMENT_FORMAT3rc_METHOD; I_STATEMENT_FORMAT3rc_TYPE; + I_STATEMENT_FORMAT45cc_METHOD; + I_STATEMENT_FORMAT4rcc_METHOD; I_STATEMENT_FORMAT51l; I_STATEMENT_ARRAY_DATA; I_STATEMENT_PACKED_SWITCH; @@ -581,6 +585,8 @@ simple_name | INSTRUCTION_FORMAT35c_TYPE -> SIMPLE_NAME[$INSTRUCTION_FORMAT35c_TYPE] | INSTRUCTION_FORMAT35mi_METHOD -> SIMPLE_NAME[$INSTRUCTION_FORMAT35mi_METHOD] | INSTRUCTION_FORMAT35ms_METHOD -> SIMPLE_NAME[$INSTRUCTION_FORMAT35ms_METHOD] + | INSTRUCTION_FORMAT45cc_METHOD -> SIMPLE_NAME[$INSTRUCTION_FORMAT45cc_METHOD] + | INSTRUCTION_FORMAT4rcc_METHOD -> SIMPLE_NAME[$INSTRUCTION_FORMAT4rcc_METHOD] | INSTRUCTION_FORMAT51l -> SIMPLE_NAME[$INSTRUCTION_FORMAT51l]; member_name @@ -849,6 +855,8 @@ instruction | insn_format3rc_type | insn_format3rmi_method | insn_format3rms_method + | insn_format45cc_method + | insn_format4rcc_method | insn_format51l | insn_array_data_directive | insn_packed_switch_directive @@ -1106,6 +1114,16 @@ insn_format3rms_method throwOdexedInstructionException(input, $INSTRUCTION_FORMAT3rms_METHOD.text); }; +insn_format45cc_method + : //e.g. invoke-polymorphic {v0..v1}, java/lang/invoke/MethodHandle;->invoke([Ljava/lang/Object;)Ljava/lang/Object;, (I)J + INSTRUCTION_FORMAT45cc_METHOD OPEN_BRACE register_list CLOSE_BRACE COMMA method_reference COMMA method_prototype + -> ^(I_STATEMENT_FORMAT45cc_METHOD[$start, "I_STATEMENT_FORMAT45cc_METHOD"] INSTRUCTION_FORMAT45cc_METHOD register_list method_reference method_prototype); + +insn_format4rcc_method + : //e.g. invoke-polymorphic/range {v0,v1}, java/lang/invoke/MethodHandle;->invoke([Ljava/lang/Object;)Ljava/lang/Object;, (I)J + INSTRUCTION_FORMAT4rcc_METHOD OPEN_BRACE register_range CLOSE_BRACE COMMA method_reference COMMA method_prototype + -> ^(I_STATEMENT_FORMAT4rcc_METHOD[$start, "I_STATEMENT_FORMAT4rcc_METHOD"] INSTRUCTION_FORMAT4rcc_METHOD register_range method_reference method_prototype); + insn_format51l : //e.g. const-wide v0, 5000000000L INSTRUCTION_FORMAT51l REGISTER COMMA fixed_literal @@ -1141,4 +1159,4 @@ insn_sparse_switch_directive (fixed_32bit_literal ARROW label_ref)* END_SPARSE_SWITCH_DIRECTIVE -> ^(I_STATEMENT_SPARSE_SWITCH[$start, "I_STATEMENT_SPARSE_SWITCH"] - ^(I_SPARSE_SWITCH_ELEMENTS[$start, "I_SPARSE_SWITCH_ELEMENTS"] (fixed_32bit_literal label_ref)*)); \ No newline at end of file + ^(I_SPARSE_SWITCH_ELEMENTS[$start, "I_SPARSE_SWITCH_ELEMENTS"] (fixed_32bit_literal label_ref)*)); diff --git a/smali/src/main/antlr/smaliTreeWalker.g b/smali/src/main/antlr/smaliTreeWalker.g index c3a50994..7f5657a5 100644 --- a/smali/src/main/antlr/smaliTreeWalker.g +++ b/smali/src/main/antlr/smaliTreeWalker.g @@ -62,6 +62,7 @@ import org.jf.dexlib2.immutable.ImmutableAnnotation; import org.jf.dexlib2.immutable.ImmutableAnnotationElement; import org.jf.dexlib2.immutable.reference.ImmutableFieldReference; import org.jf.dexlib2.immutable.reference.ImmutableMethodReference; +import org.jf.dexlib2.immutable.reference.ImmutableMethodProtoReference; import org.jf.dexlib2.immutable.reference.ImmutableReference; import org.jf.dexlib2.immutable.reference.ImmutableTypeReference; import org.jf.dexlib2.immutable.value.*; @@ -766,6 +767,8 @@ instruction | insn_format35c_type | insn_format3rc_method | insn_format3rc_type + | insn_format45cc_method + | insn_format4rcc_method | insn_format51l_type | insn_array_data_directive | insn_packed_switch_directive @@ -1181,6 +1184,47 @@ insn_format3rc_type dexBuilder.internTypeReference($nonvoid_type_descriptor.type))); }; +insn_format45cc_method + : //e.g. invoke-polymorphic {v0, v1}, java/lang/invoke/MethodHandle;->invoke([Ljava/lang/Object;)Ljava/lang/Object;, (I)J + ^(I_STATEMENT_FORMAT45cc_METHOD INSTRUCTION_FORMAT45cc_METHOD register_list method_reference method_prototype) + { + Opcode opcode = opcodes.getOpcodeByName($INSTRUCTION_FORMAT45cc_METHOD.text); + + //this depends on the fact that register_list returns a byte[5] + byte[] registers = $register_list.registers; + byte registerCount = $register_list.registerCount; + + ImmutableMethodReference methodReference = $method_reference.methodReference; + ImmutableMethodProtoReference methodProtoReference = new ImmutableMethodProtoReference( + $method_prototype.parameters, + $method_prototype.returnType); + + $method::methodBuilder.addInstruction(new BuilderInstruction45cc(opcode, registerCount, registers[0], registers[1], + registers[2], registers[3], registers[4], + dexBuilder.internMethodReference(methodReference), + dexBuilder.internMethodProtoReference(methodProtoReference))); + }; + +insn_format4rcc_method + : //e.g. invoke-polymorphic {v0..v1}, java/lang/invoke/MethodHandle;->invoke([Ljava/lang/Object;)Ljava/lang/Object;, (I)J + ^(I_STATEMENT_FORMAT4rcc_METHOD INSTRUCTION_FORMAT4rcc_METHOD register_range method_reference method_prototype) + { + Opcode opcode = opcodes.getOpcodeByName($INSTRUCTION_FORMAT4rcc_METHOD.text); + int startRegister = $register_range.startRegister; + int endRegister = $register_range.endRegister; + + int registerCount = endRegister-startRegister+1; + + ImmutableMethodReference methodReference = $method_reference.methodReference; + ImmutableMethodProtoReference methodProtoReference = new ImmutableMethodProtoReference( + $method_prototype.parameters, + $method_prototype.returnType); + + $method::methodBuilder.addInstruction(new BuilderInstruction4rcc(opcode, startRegister, registerCount, + dexBuilder.internMethodReference(methodReference), + dexBuilder.internMethodProtoReference(methodProtoReference))); + }; + insn_format51l_type : //e.g. const-wide v0, 5000000000L ^(I_STATEMENT_FORMAT51l INSTRUCTION_FORMAT51l REGISTER fixed_64bit_literal) diff --git a/smali/src/main/jflex/smaliLexer.jflex b/smali/src/main/jflex/smaliLexer.jflex index 2f57a438..e0010a93 100644 --- a/smali/src/main/jflex/smaliLexer.jflex +++ b/smali/src/main/jflex/smaliLexer.jflex @@ -624,6 +624,14 @@ Type = {PrimitiveType} | {ClassDescriptor} | {ArrayPrefix} ({ClassDescriptor} | return newToken(INSTRUCTION_FORMAT3rms_METHOD); } + "invoke-polymorphic" { + return newToken(INSTRUCTION_FORMAT45cc_METHOD); + } + + "invoke-polymorphic/range" { + return newToken(INSTRUCTION_FORMAT4rcc_METHOD); + } + "const-wide" { return newToken(INSTRUCTION_FORMAT51l); } From 99b80bbc5a55f53e73a143a90f94faefbd5e4f7f Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Wed, 17 Aug 2016 11:39:28 +0100 Subject: [PATCH 12/13] Revert "Add lambda experimental dalvik opcodes" This reverts commit 144951a9e9e6c87866245f2bdeebf0ebedaa0e38. --- .../Format/InstructionMethodItem.java | 42 -------- .../LambdaTest/HelloWorldLambda.smali | 55 ----------- .../src/main/java/org/jf/dexlib2/Format.java | 1 - .../src/main/java/org/jf/dexlib2/Opcode.java | 9 -- .../builder/MutableMethodImplementation.java | 15 --- .../instruction/BuilderInstruction25x.java | 82 ---------------- .../instruction/DexBackedInstruction.java | 2 - .../instruction/DexBackedInstruction25x.java | 83 ---------------- .../jf/dexlib2/dexbacked/raw/CodeItem.java | 27 ------ ...FixedFourParameterRegisterInstruction.java | 47 --------- .../instruction/formats/Instruction25x.java | 37 ------- .../instruction/ImmutableInstruction.java | 2 - .../instruction/ImmutableInstruction25x.java | 97 ------------------- .../org/jf/dexlib2/util/Preconditions.java | 9 -- .../java/org/jf/dexlib2/writer/DexWriter.java | 3 - .../jf/dexlib2/writer/InstructionWriter.java | 14 --- .../HelloWorldFunctionalInterface.smali | 8 -- .../HelloWorldLambda/HelloWorldLambda.smali | 57 ----------- smali/src/main/antlr/smaliParser.g | 36 ------- smali/src/main/antlr/smaliTreeWalker.g | 73 -------------- smali/src/main/jflex/smaliLexer.jflex | 20 +--- .../resources/LexerTest/InstructionTest.smali | 6 -- .../LexerTest/InstructionTest.tokens | 6 -- 23 files changed, 2 insertions(+), 729 deletions(-) delete mode 100644 baksmali/src/test/resources/LambdaTest/HelloWorldLambda.smali delete mode 100644 dexlib2/src/main/java/org/jf/dexlib2/builder/instruction/BuilderInstruction25x.java delete mode 100644 dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction25x.java delete mode 100644 dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/OneFixedFourParameterRegisterInstruction.java delete mode 100644 dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction25x.java delete mode 100644 dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction25x.java delete mode 100644 examples/HelloWorldLambda/HelloWorldFunctionalInterface.smali delete mode 100644 examples/HelloWorldLambda/HelloWorldLambda.smali diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java index 39485c90..fe85fe00 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/InstructionMethodItem.java @@ -330,11 +330,6 @@ public class InstructionMethodItem extends MethodItem { writer.write(", "); writeThirdRegister(writer); break; - case Format25x: - writeOpcode(writer); - writer.write(' '); - writeInvoke25xRegisters(writer); // vC, {vD, ...} - break; case Format35c: writeOpcode(writer); writer.write(' '); @@ -478,43 +473,6 @@ public class InstructionMethodItem extends MethodItem { writer.write('}'); } - protected void writeInvoke25xRegisters(IndentingWriter writer) throws IOException { - OneFixedFourParameterRegisterInstruction instruction = - (OneFixedFourParameterRegisterInstruction)this.instruction; - final int parameterRegCount = instruction.getParameterRegisterCount(); - - writeRegister(writer, instruction.getRegisterFixedC()); // fixed register always present - - writer.write(", {"); - switch (parameterRegCount) { - case 1: - writeRegister(writer, instruction.getRegisterParameterD()); - break; - case 2: - writeRegister(writer, instruction.getRegisterParameterD()); - writer.write(", "); - writeRegister(writer, instruction.getRegisterParameterE()); - break; - case 3: - writeRegister(writer, instruction.getRegisterParameterD()); - writer.write(", "); - writeRegister(writer, instruction.getRegisterParameterE()); - writer.write(", "); - writeRegister(writer, instruction.getRegisterParameterF()); - break; - case 4: - writeRegister(writer, instruction.getRegisterParameterD()); - writer.write(", "); - writeRegister(writer, instruction.getRegisterParameterE()); - writer.write(", "); - writeRegister(writer, instruction.getRegisterParameterF()); - writer.write(", "); - writeRegister(writer, instruction.getRegisterParameterG()); - break; - } - writer.write('}'); - } - protected void writeInvokeRangeRegisters(IndentingWriter writer) throws IOException { RegisterRangeInstruction instruction = (RegisterRangeInstruction)this.instruction; diff --git a/baksmali/src/test/resources/LambdaTest/HelloWorldLambda.smali b/baksmali/src/test/resources/LambdaTest/HelloWorldLambda.smali deleted file mode 100644 index d70ced50..00000000 --- a/baksmali/src/test/resources/LambdaTest/HelloWorldLambda.smali +++ /dev/null @@ -1,55 +0,0 @@ -.class public LHelloWorldLambda; - -#Ye olde hello world application (with lambdas!) -#To assemble and run this on a phone or emulator: -# -#java -jar smali.jar -o classes.dex HelloWorldLambda.smali HelloWorldFunctionalInterface.smali -#zip HelloWorld.zip classes.dex -#adb push HelloWorld.zip /data/local -#adb shell dalvikvm -cp /data/local/HelloWorld.zip HelloWorld -# -#if you get out of memory type errors when running smali.jar, try -#java -Xmx512m -jar smali.jar HelloWorldLambda.smali -#instead - -.super Ljava/lang/Object; - -.method public static doHelloWorld(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V - .registers 6 # 4 parameters, 2 locals - liberate-variable v0, p0, "helloworld" - - sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream; - invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V - - return-void -.end method - -.method public static main([Ljava/lang/String;)V - .registers 9 # 1 parameter, 8 locals - - sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; - - const-string v1, "Hello World!" - const-string v2, "How" # vD - const-string v3, "are" # vE - const-string v4, "you" # vF - const-string v5, "doing?" # vG - - capture-variable v1, "helloworld" - - # TODO: do I need to pass the type of the lambda's functional interface here as a type id? - create-lambda v1, LHelloWorldLambda;->doHelloWorld(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V - # Method descriptor is not required here, because only the single-abstract method is ever invoked. - invoke-lambda v1, {v2, v3, v4, v5} - - box-lambda v6, v1 - invoke-virtual {v6, v2, v3, v4, v5}, LHelloWorldFunctionalInterface;->applyFourStrings(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V - - # FIXME: should be \HelloWorldFunctionalInterface; instead of L...; - - # TODO: do we really need the type descriptor here at all? - unbox-lambda v7, v6, LHelloWorldFunctionalInterface; - invoke-lambda v7, {v2, v3, v4, v5} - - return-void -.end method diff --git a/dexlib2/src/main/java/org/jf/dexlib2/Format.java b/dexlib2/src/main/java/org/jf/dexlib2/Format.java index 42e8e144..fd90a6dd 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/Format.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/Format.java @@ -51,7 +51,6 @@ public enum Format { Format22t(4), Format22x(4), Format23x(4), - Format25x(4), Format30t(6), Format31c(6), Format31i(6), diff --git a/dexlib2/src/main/java/org/jf/dexlib2/Opcode.java b/dexlib2/src/main/java/org/jf/dexlib2/Opcode.java index 9559760a..138c6c63 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/Opcode.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/Opcode.java @@ -305,15 +305,6 @@ public enum Opcode SPARSE_SWITCH_PAYLOAD(0x200, "sparse-switch-payload", ReferenceType.NONE, Format.SparseSwitchPayload, 0), ARRAY_PAYLOAD(0x300, "array-payload", ReferenceType.NONE, Format.ArrayPayload, 0), - // Reuse the deprecated f3-ff opcodes in Art: - INVOKE_LAMBDA(allArtVersions(0xf3),"invoke-lambda", ReferenceType.NONE, Format.Format25x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.EXPERIMENTAL), - // TODO: What about JUMBO support if the string ID is too large? - CAPTURE_VARIABLE(allArtVersions(0xf5), "capture-variable", ReferenceType.STRING, Format.Format21c, Opcode.EXPERIMENTAL), - CREATE_LAMBDA(allArtVersions(0xf6), "create-lambda", ReferenceType.METHOD, Format.Format21c, Opcode.SETS_REGISTER | Opcode.EXPERIMENTAL), - // TODO: do we need a capture/liberate wide? - LIBERATE_VARIABLE(allArtVersions(0xf7), "liberate-variable", ReferenceType.STRING, Format.Format22c, Opcode.SETS_REGISTER | Opcode.EXPERIMENTAL), - BOX_LAMBDA(allArtVersions(0xf8), "box-lambda", ReferenceType.NONE, Format.Format22x, Opcode.SETS_REGISTER | Opcode.EXPERIMENTAL), - UNBOX_LAMBDA(allArtVersions(0xf9), "unbox-lambda", ReferenceType.TYPE, Format.Format22c, Opcode.SETS_REGISTER | Opcode.EXPERIMENTAL), INVOKE_POLYMORPHIC(firstApi(0xfa, 26), "invoke-polymorphic", ReferenceType.METHOD, ReferenceType.METHOD_PROTO, Format.Format45cc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT), INVOKE_POLYMORPHIC_RANGE(firstApi(0xfb, 26), "invoke-polymorphic/range", ReferenceType.METHOD, ReferenceType.METHOD_PROTO, Format.Format4rcc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/builder/MutableMethodImplementation.java b/dexlib2/src/main/java/org/jf/dexlib2/builder/MutableMethodImplementation.java index b1e5dbbf..148bafd1 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/builder/MutableMethodImplementation.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/builder/MutableMethodImplementation.java @@ -615,9 +615,6 @@ public class MutableMethodImplementation implements MethodImplementation { case Format23x: setInstruction(location, newBuilderInstruction23x((Instruction23x) instruction)); return; - case Format25x: - setInstruction(location, newBuilderInstruction25x((Instruction25x) instruction)); - return; case Format30t: setInstruction(location, newBuilderInstruction30t(location.codeAddress, codeAddressToIndex, @@ -871,18 +868,6 @@ public class MutableMethodImplementation implements MethodImplementation { instruction.getReference()); } - @Nonnull - private BuilderInstruction25x newBuilderInstruction25x(@Nonnull Instruction25x instruction) { - return new BuilderInstruction25x( - instruction.getOpcode(), - instruction.getParameterRegisterCount(), - instruction.getRegisterFixedC(), - instruction.getRegisterParameterD(), - instruction.getRegisterParameterE(), - instruction.getRegisterParameterF(), - instruction.getRegisterParameterG()); - } - @Nonnull private BuilderInstruction3rc newBuilderInstruction3rc(@Nonnull Instruction3rc instruction) { return new BuilderInstruction3rc( diff --git a/dexlib2/src/main/java/org/jf/dexlib2/builder/instruction/BuilderInstruction25x.java b/dexlib2/src/main/java/org/jf/dexlib2/builder/instruction/BuilderInstruction25x.java deleted file mode 100644 index 3783d2b6..00000000 --- a/dexlib2/src/main/java/org/jf/dexlib2/builder/instruction/BuilderInstruction25x.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "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 COPYRIGHT - * OWNER OR CONTRIBUTORS 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.jf.dexlib2.builder.instruction; - -import org.jf.dexlib2.Format; -import org.jf.dexlib2.Opcode; -import org.jf.dexlib2.builder.BuilderInstruction; -import org.jf.dexlib2.iface.instruction.formats.Instruction25x; -import org.jf.dexlib2.util.Preconditions; - -import javax.annotation.Nonnull; - -public class BuilderInstruction25x extends BuilderInstruction implements Instruction25x { - public static final Format FORMAT = Format.Format25x; - - protected final int parameterRegisterCount; - protected final int registerClosure; - protected final int registerD; - protected final int registerE; - protected final int registerF; - protected final int registerG; - - public BuilderInstruction25x(@Nonnull Opcode opcode, - int parameterRegisterCount, - int registerClosure, - int registerD, - int registerE, - int registerF, - int registerG) { - super(opcode); - this.parameterRegisterCount = - Preconditions.check25xParameterRegisterCount(parameterRegisterCount); - this.registerClosure = Preconditions.checkNibbleRegister(registerClosure); //at least 1 reg - this.registerD = (parameterRegisterCount>0) ? - Preconditions.checkNibbleRegister(registerD) : 0; - this.registerE = (parameterRegisterCount>1) ? - Preconditions.checkNibbleRegister(registerE) : 0; - this.registerF = (parameterRegisterCount>2) ? - Preconditions.checkNibbleRegister(registerF) : 0; - this.registerG = (parameterRegisterCount>3) ? - Preconditions.checkNibbleRegister(registerG) : 0; - } - - @Override public int getRegisterCount() { return parameterRegisterCount + 1; } - @Override public int getParameterRegisterCount() { return parameterRegisterCount; } - @Override public int getRegisterFixedC() { return registerClosure; } - @Override public int getRegisterParameterD() { return registerD; } - @Override public int getRegisterParameterE() { return registerE; } - @Override public int getRegisterParameterF() { return registerF; } - @Override public int getRegisterParameterG() { return registerG; } - - @Override public Format getFormat() { return FORMAT; } -} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction.java index 2973398a..975e6813 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction.java @@ -115,8 +115,6 @@ public abstract class DexBackedInstruction implements Instruction { return new DexBackedInstruction22x(dexFile, opcode, instructionStartOffset); case Format23x: return new DexBackedInstruction23x(dexFile, opcode, instructionStartOffset); - case Format25x: - return new DexBackedInstruction25x(dexFile, opcode, instructionStartOffset); case Format30t: return new DexBackedInstruction30t(dexFile, opcode, instructionStartOffset); case Format31c: diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction25x.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction25x.java deleted file mode 100644 index 80fb8767..00000000 --- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/instruction/DexBackedInstruction25x.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "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 COPYRIGHT - * OWNER OR CONTRIBUTORS 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.jf.dexlib2.dexbacked.instruction; - -import org.jf.dexlib2.Opcode; -import org.jf.dexlib2.dexbacked.DexBackedDexFile; -import org.jf.dexlib2.iface.instruction.formats.Instruction25x; -import org.jf.util.NibbleUtils; - -import javax.annotation.Nonnull; - -public class DexBackedInstruction25x extends DexBackedInstruction implements Instruction25x { - public DexBackedInstruction25x(@Nonnull DexBackedDexFile dexFile, - @Nonnull Opcode opcode, - int instructionStart) { - super(dexFile, opcode, instructionStart); - } - - @Override - public int getRegisterCount() { - return getParameterRegisterCount() + 1; - } - - @Override - public int getParameterRegisterCount() { - return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 1)); - } - - @Override - public int getRegisterFixedC() { - return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 2)); - } - - @Override - public int getRegisterParameterD() { - return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 2)); - } - - @Override - public int getRegisterParameterE() { - return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 3)); - } - - @Override - public int getRegisterParameterF() { - return NibbleUtils.extractHighUnsignedNibble(dexFile.readUbyte(instructionStart + 3)); - } - - @Override - public int getRegisterParameterG() { - return NibbleUtils.extractLowUnsignedNibble(dexFile.readUbyte(instructionStart + 1)); - } - -} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/raw/CodeItem.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/raw/CodeItem.java index 27d72ad1..eeaff457 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/raw/CodeItem.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/raw/CodeItem.java @@ -129,9 +129,6 @@ public class CodeItem { case Format10x: annotateInstruction10x(out, instruction); break; - case Format25x: - annotateInstruction25x(out, (Instruction25x) instruction); - break; case Format35c: annotateInstruction35c(out, (Instruction35c)instruction); break; @@ -285,30 +282,6 @@ public class CodeItem { instruction.getOpcode().name, Joiner.on(", ").join(args), reference)); } - private void annotateInstruction25x(@Nonnull AnnotatedBytes out, - @Nonnull Instruction25x instruction) { - List args = Lists.newArrayList(); - - int registerCount = instruction.getRegisterCount(); //at least 1. - if (registerCount == 2) { - args.add(formatRegister(instruction.getRegisterParameterD())); - } else if (registerCount == 3) { - args.add(formatRegister(instruction.getRegisterParameterD())); - args.add(formatRegister(instruction.getRegisterParameterE())); - } else if (registerCount == 4) { - args.add(formatRegister(instruction.getRegisterParameterD())); - args.add(formatRegister(instruction.getRegisterParameterE())); - args.add(formatRegister(instruction.getRegisterParameterF())); - } else if (registerCount == 5) { - args.add(formatRegister(instruction.getRegisterParameterD())); - args.add(formatRegister(instruction.getRegisterParameterE())); - args.add(formatRegister(instruction.getRegisterParameterF())); - args.add(formatRegister(instruction.getRegisterParameterG())); - } - out.annotate(6, String.format("%s %s, {%s}", - instruction.getOpcode().name, instruction.getRegisterFixedC(), Joiner.on(", ").join(args))); - } - private void annotateInstruction3rc(@Nonnull AnnotatedBytes out, @Nonnull Instruction3rc instruction) { int startRegister = instruction.getStartRegister(); int endRegister = startRegister + instruction.getRegisterCount() - 1; diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/OneFixedFourParameterRegisterInstruction.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/OneFixedFourParameterRegisterInstruction.java deleted file mode 100644 index c03bff77..00000000 --- a/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/OneFixedFourParameterRegisterInstruction.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "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 COPYRIGHT - * OWNER OR CONTRIBUTORS 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.jf.dexlib2.iface.instruction; - -public interface OneFixedFourParameterRegisterInstruction extends VariableRegisterInstruction { - int getRegisterFixedC(); - int getRegisterParameterD(); - int getRegisterParameterE(); - int getRegisterParameterF(); - int getRegisterParameterG(); - - /** Returns the count of just the parameter register counts; in range of [0, 4] */ - int getParameterRegisterCount(); - - /** Includes the total sum of both fixed and parameter register counts; at least 1 */ - @Override - int getRegisterCount(); -} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction25x.java b/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction25x.java deleted file mode 100644 index 51df2dee..00000000 --- a/dexlib2/src/main/java/org/jf/dexlib2/iface/instruction/formats/Instruction25x.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "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 COPYRIGHT - * OWNER OR CONTRIBUTORS 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.jf.dexlib2.iface.instruction.formats; - -import org.jf.dexlib2.iface.instruction.OneFixedFourParameterRegisterInstruction; - -public interface Instruction25x extends OneFixedFourParameterRegisterInstruction { -} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction.java index ed50ef5b..432f1930 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction.java @@ -97,8 +97,6 @@ public abstract class ImmutableInstruction implements Instruction { return ImmutableInstruction22x.of((Instruction22x)instruction); case Format23x: return ImmutableInstruction23x.of((Instruction23x)instruction); - case Format25x: - return ImmutableInstruction25x.of((Instruction25x) instruction); case Format30t: return ImmutableInstruction30t.of((Instruction30t)instruction); case Format31c: diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction25x.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction25x.java deleted file mode 100644 index 2f31eaea..00000000 --- a/dexlib2/src/main/java/org/jf/dexlib2/immutable/instruction/ImmutableInstruction25x.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "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 COPYRIGHT - * OWNER OR CONTRIBUTORS 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.jf.dexlib2.immutable.instruction; - -import org.jf.dexlib2.Format; -import org.jf.dexlib2.Opcode; -import org.jf.dexlib2.iface.instruction.formats.Instruction25x; -import org.jf.dexlib2.util.Preconditions; - -import javax.annotation.Nonnull; - -public class ImmutableInstruction25x extends ImmutableInstruction implements Instruction25x { - public static final Format FORMAT = Format.Format25x; - - protected final int parameterRegisterCount; - protected final int registerClosure; - protected final int registerD; - protected final int registerE; - protected final int registerF; - protected final int registerG; - - public ImmutableInstruction25x(@Nonnull Opcode opcode, - int parameterRegisterCount, - int registerClosure, - int registerD, - int registerE, - int registerF, - int registerG) { - super(opcode); - this.parameterRegisterCount = - Preconditions.check25xParameterRegisterCount(parameterRegisterCount); - this.registerClosure = Preconditions.checkNibbleRegister(registerClosure); - this.registerD = (parameterRegisterCount>0) ? - Preconditions.checkNibbleRegister(registerD) : 0; - this.registerE = (parameterRegisterCount>1) ? - Preconditions.checkNibbleRegister(registerE) : 0; - this.registerF = (parameterRegisterCount>2) ? - Preconditions.checkNibbleRegister(registerF) : 0; - this.registerG = (parameterRegisterCount>3) ? - Preconditions.checkNibbleRegister(registerG) : 0; - } - - public static ImmutableInstruction25x of(Instruction25x instruction) { - if (instruction instanceof ImmutableInstruction25x) { - return (ImmutableInstruction25x)instruction; - } - return new ImmutableInstruction25x( - instruction.getOpcode(), - instruction.getRegisterCount(), - instruction.getRegisterFixedC(), - instruction.getRegisterParameterD(), - instruction.getRegisterParameterE(), - instruction.getRegisterParameterF(), - instruction.getRegisterParameterG()); - } - - - @Override public int getParameterRegisterCount() { return parameterRegisterCount; } - @Override public int getRegisterCount() { return parameterRegisterCount + 1; } - - @Override public int getRegisterFixedC() { return registerClosure; } - @Override public int getRegisterParameterD() { return registerD; } - @Override public int getRegisterParameterE() { return registerE; } - @Override public int getRegisterParameterF() { return registerF; } - @Override public int getRegisterParameterG() { return registerG; } - - @Override public Format getFormat() { return FORMAT; } -} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java b/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java index 3b30d075..2f9fe2d7 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java @@ -133,15 +133,6 @@ public class Preconditions { return registerCount; } - public static int check25xParameterRegisterCount(int registerCount) { - if (registerCount < 0 || registerCount > 4) { - throw new IllegalArgumentException( - String.format("Invalid parameter register count: %d. " + - "Must be between 0 and 4, inclusive.", registerCount)); - } - return registerCount; - } - public static int checkRegisterRangeCount(int registerCount) { if ((registerCount & 0xFFFFFF00) != 0) { throw new IllegalArgumentException( diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java index 5329351e..6ca1ce93 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java @@ -1006,9 +1006,6 @@ public abstract class DexWriter< case Format23x: instructionWriter.write((Instruction23x)instruction); break; - case Format25x: - instructionWriter.write((Instruction25x)instruction); - break; case Format30t: instructionWriter.write((Instruction30t)instruction); break; diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/InstructionWriter.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/InstructionWriter.java index c240c515..1b883f1f 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/InstructionWriter.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/InstructionWriter.java @@ -343,20 +343,6 @@ public class InstructionWriterout:Ljava/io/PrintStream; - - const-string v1, "Hello World!" - const-string v2, "How" # vD - const-string v3, "are" # vE - const-string v4, "you" # vF - const-string v5, "doing?" # vG - - capture-variable v1, "helloworld" - - # TODO: do I need to pass the type of the lambda's functional interface here as a type id? - create-lambda v1, LHelloWorldLambda;->doHelloWorld(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V - # Method descriptor is not required here, because only the single-abstract method is ever invoked. - invoke-lambda v1, {v2, v3, v4, v5} - - box-lambda v6, v1 # The type of v6 is now 'LHelloWorldFunctionalInterface;' - invoke-virtual {v6, v2, v3, v4, v5}, LHelloWorldFunctionalInterface;->applyFourStrings(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V - - # FIXME: should be \HelloWorldFunctionalInterface; instead of L...; - - # TODO: do we really need the type descriptor here at all? - unbox-lambda v7, v6, LHelloWorldFunctionalInterface; # The type of v7 is now \HelloWorldFunctionalInterface; - invoke-lambda v7, {v2, v3, v4, v5} - - return-void -.end method - -.method public static doHelloWorld(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V - .registers 6 # 4 parameters, 2 locals - - # This helloworld variable is brought to you by the variable liberation front - liberate-variable v0, p0, "helloworld" - - sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream; - invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V - - return-void -.end method diff --git a/smali/src/main/antlr/smaliParser.g b/smali/src/main/antlr/smaliParser.g index 29148f7b..29cd141b 100644 --- a/smali/src/main/antlr/smaliParser.g +++ b/smali/src/main/antlr/smaliParser.g @@ -86,8 +86,6 @@ tokens { INSTRUCTION_FORMAT21c_FIELD_ODEX; INSTRUCTION_FORMAT21c_STRING; INSTRUCTION_FORMAT21c_TYPE; - INSTRUCTION_FORMAT21c_LAMBDA; - INSTRUCTION_FORMAT21c_METHOD; INSTRUCTION_FORMAT21ih; INSTRUCTION_FORMAT21lh; INSTRUCTION_FORMAT21s; @@ -96,14 +94,12 @@ tokens { INSTRUCTION_FORMAT22c_FIELD; INSTRUCTION_FORMAT22c_FIELD_ODEX; INSTRUCTION_FORMAT22c_TYPE; - INSTRUCTION_FORMAT22c_STRING; INSTRUCTION_FORMAT22cs_FIELD; INSTRUCTION_FORMAT22s; INSTRUCTION_FORMAT22s_OR_ID; INSTRUCTION_FORMAT22t; INSTRUCTION_FORMAT22x; INSTRUCTION_FORMAT23x; - INSTRUCTION_FORMAT25x; INSTRUCTION_FORMAT30t; INSTRUCTION_FORMAT31c; INSTRUCTION_FORMAT31i; @@ -212,8 +208,6 @@ tokens { I_STATEMENT_FORMAT21c_TYPE; I_STATEMENT_FORMAT21c_FIELD; I_STATEMENT_FORMAT21c_STRING; - I_STATEMENT_FORMAT21c_LAMBDA; - I_STATEMENT_FORMAT21c_METHOD; I_STATEMENT_FORMAT21ih; I_STATEMENT_FORMAT21lh; I_STATEMENT_FORMAT21s; @@ -221,12 +215,10 @@ tokens { I_STATEMENT_FORMAT22b; I_STATEMENT_FORMAT22c_FIELD; I_STATEMENT_FORMAT22c_TYPE; - I_STATEMENT_FORMAT22c_STRING; I_STATEMENT_FORMAT22s; I_STATEMENT_FORMAT22t; I_STATEMENT_FORMAT22x; I_STATEMENT_FORMAT23x; - I_STATEMENT_FORMAT25x; I_STATEMENT_FORMAT30t; I_STATEMENT_FORMAT31c; I_STATEMENT_FORMAT31i; @@ -566,18 +558,14 @@ simple_name | INSTRUCTION_FORMAT21c_FIELD_ODEX -> SIMPLE_NAME[$INSTRUCTION_FORMAT21c_FIELD_ODEX] | INSTRUCTION_FORMAT21c_STRING -> SIMPLE_NAME[$INSTRUCTION_FORMAT21c_STRING] | INSTRUCTION_FORMAT21c_TYPE -> SIMPLE_NAME[$INSTRUCTION_FORMAT21c_TYPE] - | INSTRUCTION_FORMAT21c_LAMBDA -> SIMPLE_NAME[$INSTRUCTION_FORMAT21c_LAMBDA] - | INSTRUCTION_FORMAT21c_METHOD -> SIMPLE_NAME[$INSTRUCTION_FORMAT21c_METHOD] | INSTRUCTION_FORMAT21t -> SIMPLE_NAME[$INSTRUCTION_FORMAT21t] | INSTRUCTION_FORMAT22c_FIELD -> SIMPLE_NAME[$INSTRUCTION_FORMAT22c_FIELD] | INSTRUCTION_FORMAT22c_FIELD_ODEX -> SIMPLE_NAME[$INSTRUCTION_FORMAT22c_FIELD_ODEX] | INSTRUCTION_FORMAT22c_TYPE -> SIMPLE_NAME[$INSTRUCTION_FORMAT22c_TYPE] - | INSTRUCTION_FORMAT22c_STRING -> SIMPLE_NAME[$INSTRUCTION_FORMAT22c_STRING] | INSTRUCTION_FORMAT22cs_FIELD -> SIMPLE_NAME[$INSTRUCTION_FORMAT22cs_FIELD] | INSTRUCTION_FORMAT22s_OR_ID -> SIMPLE_NAME[$INSTRUCTION_FORMAT22s_OR_ID] | INSTRUCTION_FORMAT22t -> SIMPLE_NAME[$INSTRUCTION_FORMAT22t] | INSTRUCTION_FORMAT23x -> SIMPLE_NAME[$INSTRUCTION_FORMAT23x] - | INSTRUCTION_FORMAT25x -> SIMPLE_NAME[$INSTRUCTION_FORMAT25x] | INSTRUCTION_FORMAT31i_OR_ID -> SIMPLE_NAME[$INSTRUCTION_FORMAT31i_OR_ID] | INSTRUCTION_FORMAT31t -> SIMPLE_NAME[$INSTRUCTION_FORMAT31t] | INSTRUCTION_FORMAT35c_METHOD -> SIMPLE_NAME[$INSTRUCTION_FORMAT35c_METHOD] @@ -823,8 +811,6 @@ instruction | insn_format21c_field_odex | insn_format21c_string | insn_format21c_type - | insn_format21c_lambda - | insn_format21c_method | insn_format21ih | insn_format21lh | insn_format21s @@ -833,13 +819,11 @@ instruction | insn_format22c_field | insn_format22c_field_odex | insn_format22c_type - | insn_format22c_string | insn_format22cs_field | insn_format22s | insn_format22t | insn_format22x | insn_format23x - | insn_format25x | insn_format30t | insn_format31c | insn_format31i @@ -935,16 +919,6 @@ insn_format21c_type INSTRUCTION_FORMAT21c_TYPE REGISTER COMMA nonvoid_type_descriptor -> ^(I_STATEMENT_FORMAT21c_TYPE[$start, "I_STATEMENT_FORMAT21c"] INSTRUCTION_FORMAT21c_TYPE REGISTER nonvoid_type_descriptor); -insn_format21c_lambda - : //e.g. capture-variable v1, "foobar" - INSTRUCTION_FORMAT21c_LAMBDA REGISTER COMMA STRING_LITERAL - -> ^(I_STATEMENT_FORMAT21c_LAMBDA[$start, "I_STATEMENT_FORMAT21c_LAMBDA"] INSTRUCTION_FORMAT21c_LAMBDA REGISTER STRING_LITERAL); - -insn_format21c_method - : //e.g. create-lambda v1, java/io/PrintStream/print(Ljava/lang/Stream;)V - INSTRUCTION_FORMAT21c_METHOD REGISTER COMMA method_reference - -> ^(I_STATEMENT_FORMAT21c_METHOD[$start, "I_STATEMENT_FORMAT21c_METHOD"] INSTRUCTION_FORMAT21c_METHOD REGISTER method_reference); - insn_format21ih : //e.g. const/high16 v1, 1234 INSTRUCTION_FORMAT21ih REGISTER COMMA fixed_32bit_literal @@ -990,11 +964,6 @@ insn_format22c_type INSTRUCTION_FORMAT22c_TYPE REGISTER COMMA REGISTER COMMA nonvoid_type_descriptor -> ^(I_STATEMENT_FORMAT22c_TYPE[$start, "I_STATEMENT_FORMAT22c_TYPE"] INSTRUCTION_FORMAT22c_TYPE REGISTER REGISTER nonvoid_type_descriptor); -insn_format22c_string - : //e.g. liberate-variable v0, v1, "baz" - INSTRUCTION_FORMAT22c_STRING REGISTER COMMA REGISTER COMMA STRING_LITERAL - -> ^(I_STATEMENT_FORMAT22c_STRING[$start, "I_STATEMENT_FORMAT22c_STRING"] INSTRUCTION_FORMAT22c_STRING REGISTER REGISTER STRING_LITERAL); - insn_format22cs_field : //e.g. iget-quick v0, v1, field@0xc INSTRUCTION_FORMAT22cs_FIELD REGISTER COMMA REGISTER COMMA FIELD_OFFSET @@ -1022,11 +991,6 @@ insn_format23x INSTRUCTION_FORMAT23x REGISTER COMMA REGISTER COMMA REGISTER -> ^(I_STATEMENT_FORMAT23x[$start, "I_STATEMENT_FORMAT23x"] INSTRUCTION_FORMAT23x REGISTER REGISTER REGISTER); -insn_format25x - : //e.g. invoke-lambda vClosure, {vA, vB, vC, vD} -- up to 4 parameters + the closure. - INSTRUCTION_FORMAT25x REGISTER COMMA OPEN_BRACE register_list CLOSE_BRACE - -> ^(I_STATEMENT_FORMAT25x[$start, "I_STATEMENT_FORMAT25x"] INSTRUCTION_FORMAT25x REGISTER register_list); - insn_format30t : //e.g. goto/32 endloop: INSTRUCTION_FORMAT30t label_ref diff --git a/smali/src/main/antlr/smaliTreeWalker.g b/smali/src/main/antlr/smaliTreeWalker.g index 7f5657a5..d074579b 100644 --- a/smali/src/main/antlr/smaliTreeWalker.g +++ b/smali/src/main/antlr/smaliTreeWalker.g @@ -675,22 +675,6 @@ register_list returns[byte[\] registers, byte registerCount] $registers[$registerCount++] = parseRegister_nibble($REGISTER.text); })*); -register_list4 returns[byte[\] registers, byte registerCount] - @init - { - $registers = new byte[4]; - $registerCount = 0; - } - : ^(I_REGISTER_LIST - (REGISTER - { - if ($registerCount == 4) { - throw new SemanticException(input, $I_REGISTER_LIST, "A list4 of registers can only have a maximum of 4 " + - "registers. Use the /range alternate opcode instead."); - } - $registers[$registerCount++] = parseRegister_nibble($REGISTER.text); - })*); - register_range returns[int startRegister, int endRegister] : ^(I_REGISTER_RANGE (startReg=REGISTER endReg=REGISTER?)?) { @@ -743,8 +727,6 @@ instruction | insn_format21c_field | insn_format21c_string | insn_format21c_type - | insn_format21c_lambda - | insn_format21c_method | insn_format21ih | insn_format21lh | insn_format21s @@ -752,12 +734,10 @@ instruction | insn_format22b | insn_format22c_field | insn_format22c_type - | insn_format22c_string | insn_format22s | insn_format22t | insn_format22x | insn_format23x - | insn_format25x | insn_format30t | insn_format31c | insn_format31i @@ -884,30 +864,6 @@ insn_format21c_type dexBuilder.internTypeReference($nonvoid_type_descriptor.type))); }; -insn_format21c_lambda - : //e.g. capture-variable v1, "foobar" - ^(I_STATEMENT_FORMAT21c_LAMBDA INSTRUCTION_FORMAT21c_LAMBDA REGISTER string_literal) - { - Opcode opcode = opcodes.getOpcodeByName($INSTRUCTION_FORMAT21c_LAMBDA.text); - short regA = parseRegister_byte($REGISTER.text); - - $method::methodBuilder.addInstruction(new BuilderInstruction21c(opcode, regA, - dexBuilder.internStringReference($string_literal.value))); - }; - -insn_format21c_method - : //e.g. create-lambda v1, java/io/PrintStream/print(Ljava/lang/Stream;)V - ^(I_STATEMENT_FORMAT21c_METHOD INSTRUCTION_FORMAT21c_METHOD REGISTER method_reference) - { - Opcode opcode = opcodes.getOpcodeByName($INSTRUCTION_FORMAT21c_METHOD.text); - short regA = parseRegister_byte($REGISTER.text); - - ImmutableMethodReference methodReference = $method_reference.methodReference; - - $method::methodBuilder.addInstruction(new BuilderInstruction21c(opcode, regA, - dexBuilder.internMethodReference(methodReference))); - }; - insn_format21ih : //e.g. const/high16 v1, 1234 ^(I_STATEMENT_FORMAT21ih INSTRUCTION_FORMAT21ih REGISTER fixed_32bit_literal) @@ -994,18 +950,6 @@ insn_format22c_type dexBuilder.internTypeReference($nonvoid_type_descriptor.type))); }; -insn_format22c_string - : //e.g. liberate-variable v0, v1, "baz" - ^(I_STATEMENT_FORMAT22c_STRING INSTRUCTION_FORMAT22c_STRING registerA=REGISTER registerB=REGISTER string_literal) - { - Opcode opcode = opcodes.getOpcodeByName($INSTRUCTION_FORMAT22c_STRING.text); - byte regA = parseRegister_nibble($registerA.text); - byte regB = parseRegister_nibble($registerB.text); - - $method::methodBuilder.addInstruction(new BuilderInstruction22c(opcode, regA, regB, - dexBuilder.internStringReference($string_literal.value))); - }; - insn_format22s : //e.g. add-int/lit16 v0, v1, 12345 ^(I_STATEMENT_FORMAT22s INSTRUCTION_FORMAT22s registerA=REGISTER registerB=REGISTER short_integral_literal) @@ -1053,23 +997,6 @@ insn_format23x $method::methodBuilder.addInstruction(new BuilderInstruction23x(opcode, regA, regB, regC)); }; -insn_format25x - : //e.g. invoke-lambda vClosure, {vD, vE, vF, vG} -- up to 4 parameters + the closure. - ^(I_STATEMENT_FORMAT25x INSTRUCTION_FORMAT25x REGISTER register_list4) - { - Opcode opcode = opcodes.getOpcodeByName($INSTRUCTION_FORMAT25x.text); - - byte closureRegister = parseRegister_nibble($REGISTER.text); - - //this depends on the fact that register_list4 returns a byte[4] - byte[] registers = $register_list4.registers; - int parameterRegisterCount = $register_list4.registerCount; // don't count closure register - - $method::methodBuilder.addInstruction(new BuilderInstruction25x(opcode, - parameterRegisterCount, closureRegister, registers[0], registers[1], - registers[2], registers[3])); - }; - insn_format30t : //e.g. goto/32 endloop: ^(I_STATEMENT_FORMAT30t INSTRUCTION_FORMAT30t label_ref) diff --git a/smali/src/main/jflex/smaliLexer.jflex b/smali/src/main/jflex/smaliLexer.jflex index e0010a93..2cf3c869 100644 --- a/smali/src/main/jflex/smaliLexer.jflex +++ b/smali/src/main/jflex/smaliLexer.jflex @@ -476,14 +476,6 @@ Type = {PrimitiveType} | {ClassDescriptor} | {ArrayPrefix} ({ClassDescriptor} | return newToken(INSTRUCTION_FORMAT21c_TYPE); } - "capture-variable" { // e.g. 'capture-variable vB, ' - return newToken(INSTRUCTION_FORMAT21c_LAMBDA); - } - - "create-lambda" { // e.g. 'create-lambda vClosure, ' - return newToken(INSTRUCTION_FORMAT21c_METHOD); - } - "const/high16" { return newToken(INSTRUCTION_FORMAT21ih); } @@ -515,14 +507,10 @@ Type = {PrimitiveType} | {ClassDescriptor} | {ArrayPrefix} ({ClassDescriptor} | return newToken(INSTRUCTION_FORMAT22c_FIELD_ODEX); } - "instance-of" | "new-array" | "unbox-lambda" { + "instance-of" | "new-array" { return newToken(INSTRUCTION_FORMAT22c_TYPE); } - "liberate-variable" { - return newToken(INSTRUCTION_FORMAT22c_STRING); - } - "iget-quick" | "iget-wide-quick" | "iget-object-quick" | "iput-quick" | "iput-wide-quick" | "iput-object-quick" | "iput-boolean-quick" | "iput-byte-quick" | "iput-char-quick" | "iput-short-quick" { return newToken(INSTRUCTION_FORMAT22cs_FIELD); @@ -541,7 +529,7 @@ Type = {PrimitiveType} | {ClassDescriptor} | {ArrayPrefix} ({ClassDescriptor} | return newToken(INSTRUCTION_FORMAT22t); } - "move/from16" | "move-wide/from16" | "move-object/from16" | "box-lambda" { + "move/from16" | "move-wide/from16" | "move-object/from16" { return newToken(INSTRUCTION_FORMAT22x); } @@ -555,10 +543,6 @@ Type = {PrimitiveType} | {ClassDescriptor} | {ArrayPrefix} ({ClassDescriptor} | return newToken(INSTRUCTION_FORMAT23x); } - "invoke-lambda" { // e.g. invoke-lambda vClosure, {vD, vE, vF, vG} -- at most 4 params - return newToken(INSTRUCTION_FORMAT25x); - } - "goto/32" { return newToken(INSTRUCTION_FORMAT30t); } diff --git a/smali/src/test/resources/LexerTest/InstructionTest.smali b/smali/src/test/resources/LexerTest/InstructionTest.smali index 174cff8c..62e51006 100644 --- a/smali/src/test/resources/LexerTest/InstructionTest.smali +++ b/smali/src/test/resources/LexerTest/InstructionTest.smali @@ -85,8 +85,6 @@ const-string check-cast new-instance const-class -capture-variable -create-lambda const/high16 const-wide/high16 const/16 @@ -125,8 +123,6 @@ iput-wide-volatile iput-object-volatile instance-of new-array -unbox-lambda -liberate-variable iget-quick iget-wide-quick iget-object-quick @@ -153,7 +149,6 @@ if-le move/from16 move-wide/from16 move-object/from16 -box-lambda cmpl-float cmpg-float cmpl-double @@ -204,7 +199,6 @@ add-double sub-double mul-double div-double -invoke-lambda goto/32 const-string/jumbo const diff --git a/smali/src/test/resources/LexerTest/InstructionTest.tokens b/smali/src/test/resources/LexerTest/InstructionTest.tokens index fa959bad..dfbd584b 100644 --- a/smali/src/test/resources/LexerTest/InstructionTest.tokens +++ b/smali/src/test/resources/LexerTest/InstructionTest.tokens @@ -85,8 +85,6 @@ INSTRUCTION_FORMAT21c_STRING("const-string") INSTRUCTION_FORMAT21c_TYPE("check-cast") INSTRUCTION_FORMAT21c_TYPE("new-instance") INSTRUCTION_FORMAT21c_TYPE("const-class") -INSTRUCTION_FORMAT21c_LAMBDA("capture-variable") -INSTRUCTION_FORMAT21c_METHOD("create-lambda") INSTRUCTION_FORMAT21ih("const/high16") INSTRUCTION_FORMAT21lh("const-wide/high16") INSTRUCTION_FORMAT21s("const/16") @@ -125,8 +123,6 @@ INSTRUCTION_FORMAT22c_FIELD_ODEX("iput-wide-volatile") INSTRUCTION_FORMAT22c_FIELD_ODEX("iput-object-volatile") INSTRUCTION_FORMAT22c_TYPE("instance-of") INSTRUCTION_FORMAT22c_TYPE("new-array") -INSTRUCTION_FORMAT22c_TYPE("unbox-lambda") -INSTRUCTION_FORMAT22c_STRING("liberate-variable") INSTRUCTION_FORMAT22cs_FIELD("iget-quick") INSTRUCTION_FORMAT22cs_FIELD("iget-wide-quick") INSTRUCTION_FORMAT22cs_FIELD("iget-object-quick") @@ -153,7 +149,6 @@ INSTRUCTION_FORMAT22t("if-le") INSTRUCTION_FORMAT22x("move/from16") INSTRUCTION_FORMAT22x("move-wide/from16") INSTRUCTION_FORMAT22x("move-object/from16") -INSTRUCTION_FORMAT22x("box-lambda") INSTRUCTION_FORMAT23x("cmpl-float") INSTRUCTION_FORMAT23x("cmpg-float") INSTRUCTION_FORMAT23x("cmpl-double") @@ -204,7 +199,6 @@ INSTRUCTION_FORMAT23x("add-double") INSTRUCTION_FORMAT23x("sub-double") INSTRUCTION_FORMAT23x("mul-double") INSTRUCTION_FORMAT23x("div-double") -INSTRUCTION_FORMAT25x("invoke-lambda") INSTRUCTION_FORMAT30t("goto/32") INSTRUCTION_FORMAT31c("const-string/jumbo") INSTRUCTION_FORMAT31i_OR_ID("const") From 7079014a29869e1bac22226681de3471b6dc11b5 Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Tue, 23 Aug 2016 11:36:12 -0700 Subject: [PATCH 13/13] Add more error detail when interfaces can't be fully resolved --- .../org/jf/dexlib2/analysis/ClassProto.java | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassProto.java b/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassProto.java index 57aae115..bee3049a 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassProto.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassProto.java @@ -34,10 +34,7 @@ package org.jf.dexlib2.analysis; import com.google.common.base.Predicates; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; +import com.google.common.collect.*; import com.google.common.primitives.Ints; import org.jf.dexlib2.AccessFlags; import org.jf.dexlib2.analysis.util.TypeProtoUtils; @@ -71,6 +68,8 @@ public class ClassProto implements TypeProto { protected boolean vtableFullyResolved = true; protected boolean interfacesFullyResolved = true; + protected Set unresolvedInterfaces = null; + public ClassProto(@Nonnull ClassPath classPath, @Nonnull String type) { if (type.charAt(0) != 'L') { throw new ExceptionWithContext("Cannot construct ClassProto for non reference type: %s", type); @@ -130,6 +129,7 @@ public class ClassProto implements TypeProto { private final Supplier> interfacesSupplier = Suppliers.memoize(new Supplier>() { @Override public LinkedHashMap get() { + Set unresolvedInterfaces = new HashSet(0); LinkedHashMap interfaces = Maps.newLinkedHashMap(); try { @@ -141,6 +141,7 @@ public class ClassProto implements TypeProto { interfaces.put(interfaceType, interfaceDef); } catch (UnresolvedClassException ex) { interfaces.put(interfaceType, null); + unresolvedInterfaces.add(interfaceType); interfacesFullyResolved = false; } @@ -151,11 +152,13 @@ public class ClassProto implements TypeProto { } } if (!interfaceProto.interfacesFullyResolved) { + unresolvedInterfaces.addAll(interfaceProto.getUnresolvedInterfaces()); interfacesFullyResolved = false; } } } } catch (UnresolvedClassException ex) { + unresolvedInterfaces.add(type); interfacesFullyResolved = false; } @@ -166,8 +169,8 @@ public class ClassProto implements TypeProto { interfaces.put(getType(), null); } + String superclass = getSuperclass(); try { - String superclass = getSuperclass(); if (superclass != null) { ClassProto superclassProto = (ClassProto) classPath.getClass(superclass); for (String superclassInterface: superclassProto.getInterfaces().keySet()) { @@ -176,17 +179,31 @@ public class ClassProto implements TypeProto { } } if (!superclassProto.interfacesFullyResolved) { + unresolvedInterfaces.addAll(superclassProto.getUnresolvedInterfaces()); interfacesFullyResolved = false; } } } catch (UnresolvedClassException ex) { + unresolvedInterfaces.add(superclass); interfacesFullyResolved = false; } + if (unresolvedInterfaces.size() > 0) { + ClassProto.this.unresolvedInterfaces = unresolvedInterfaces; + } + return interfaces; } }); + @Nonnull + protected Set getUnresolvedInterfaces() { + if (unresolvedInterfaces == null) { + return ImmutableSet.of(); + } + return unresolvedInterfaces; + } + /** * Gets the interfaces directly implemented by this class, or the interfaces they transitively implement. * @@ -201,7 +218,8 @@ public class ClassProto implements TypeProto { FluentIterable.from(getInterfaces().values()).filter(Predicates.notNull()); if (!interfacesFullyResolved) { - throw new UnresolvedClassException("Interfaces for class %s not fully resolved", getType()); + throw new UnresolvedClassException("Interfaces for class %s not fully resolved: %s", getType(), + String.join(",", getUnresolvedInterfaces())); } return directInterfaces;