1cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver/* 2cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * Copyright 2014, Google Inc. 3cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * All rights reserved. 4cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * 5cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * Redistribution and use in source and binary forms, with or without 6cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * modification, are permitted provided that the following conditions are 7cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * met: 8cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * 9cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * * Redistributions of source code must retain the above copyright 10cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * notice, this list of conditions and the following disclaimer. 11cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * * Redistributions in binary form must reproduce the above 12cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * copyright notice, this list of conditions and the following disclaimer 13cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * in the documentation and/or other materials provided with the 14cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * distribution. 15cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * * Neither the name of Google Inc. nor the names of its 16cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * contributors may be used to endorse or promote products derived from 17cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * this software without specific prior written permission. 18cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * 19cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver */ 31cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver 32cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruverpackage org.jf.smalidea.dexlib.instruction; 33cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver 340dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruverimport com.google.common.base.Function; 350dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruverimport com.google.common.collect.Lists; 360dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruverimport org.jf.dexlib2.Opcode; 37cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruverimport org.jf.dexlib2.iface.instruction.SwitchElement; 38cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruverimport org.jf.dexlib2.iface.instruction.formats.SparseSwitchPayload; 390dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruverimport org.jf.smalidea.psi.impl.*; 400dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruverimport org.jf.smalidea.util.InstructionUtils; 41cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver 42cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruverimport javax.annotation.Nonnull; 43cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruverimport java.util.List; 44cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver 45cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruverpublic class SmalideaSparseSwitchPayload extends SmalideaInstruction implements SparseSwitchPayload { 46cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver public SmalideaSparseSwitchPayload(@Nonnull SmaliInstruction instruction) { 47cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver super(instruction); 48cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver } 49cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver 50cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver @Nonnull @Override public List<? extends SwitchElement> getSwitchElements() { 510dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver List<SmaliSparseSwitchElement> elements = psiInstruction.getSparseSwitchElements(); 520dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver 530dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver SmaliMethod smaliMethod = psiInstruction.getParentMethod(); 540dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver SmaliInstruction sparseSwitchInstruction = InstructionUtils.findFirstInstructionWithTarget( 550dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver smaliMethod, Opcode.SPARSE_SWITCH, psiInstruction.getOffset()); 560dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver final int baseOffset; 570dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver 580dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver if (sparseSwitchInstruction == null) { 590dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver baseOffset = 0; 600dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver } else { 610dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver baseOffset = sparseSwitchInstruction.getOffset(); 620dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver } 630dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver 640dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver return Lists.transform(elements, new Function<SmaliSparseSwitchElement, SwitchElement>() { 650dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver @Override public SwitchElement apply(final SmaliSparseSwitchElement element) { 660dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver return new SwitchElement() { 670dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver @Override public int getKey() { 680dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver return (int)element.getKey().getIntegralValue(); 690dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver } 700dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver 710dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver @Override public int getOffset() { 720dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver SmaliLabelReference labelReference = element.getTarget(); 730dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver if (labelReference == null) { 740dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver return 0; 750dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver } 760dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver 770dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver SmaliLabel label = labelReference.resolve(); 780dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver if (label == null) { 790dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver return 0; 800dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver } 810dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver 820dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver return label.getOffset() - baseOffset; 830dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver } 840dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver }; 850dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver } 860dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver }); 870dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver } 880dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver 890dd228064d9e7f617bfea1e805bab59525cf7097Ben Gruver @Override public int getCodeUnits() { 900a2debe4e6eb54a440ec5acbec4e42956da33c29Ben Gruver return psiInstruction.getInstructionSize()/2; 91cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver } 92cbd87b904e15c63d06f25b03b0eadf003780ec6cBen Gruver} 93