proguard.evaluation.value.InstructionOffsetValue Java Examples

The following examples show how to use proguard.evaluation.value.InstructionOffsetValue. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: EvaluationShrinker.java    From java-n-IDE-for-Android with Apache License 2.0 6 votes vote down vote up
/**
 * Returns whether any of the stack entries after the given offsets are
 * necessary.
 * @param instructionOffsets the offsets of the stack entries to be checked.
 * @param stackIndex         the index of the stack entries to be checked
 *                           (counting from the bottom).
 */
private boolean isAnyStackEntryNecessaryAfter(InstructionOffsetValue instructionOffsets,
                                              int                    stackIndex)
{
    int offsetCount = instructionOffsets.instructionOffsetCount();

    for (int offsetIndex = 0; offsetIndex < offsetCount; offsetIndex++)
    {
        if (isStackEntryNecessaryAfter(instructionOffsets.instructionOffset(offsetIndex), stackIndex))
        {
            return true;
        }
    }

    return false;
}
 
Example #2
Source File: EvaluationShrinker.java    From java-n-IDE-for-Android with Apache License 2.0 6 votes vote down vote up
/**
 * Marks the stack entries after the given offsets.
 * @param instructionOffsets the offsets of the stack entries to be marked.
 * @param stackIndex         the index of the stack entries to be marked
 *                           (counting from the bottom).
 */
private void markStackEntriesAfter(InstructionOffsetValue instructionOffsets,
                                   int                    stackIndex)
{
    if (instructionOffsets != null)
    {
        int offsetCount = instructionOffsets.instructionOffsetCount();
        for (int offsetIndex = 0; offsetIndex < offsetCount; offsetIndex++)
        {
            // Make sure the stack entry and the instruction are marked
            // at the producing offset.
            int offset = instructionOffsets.instructionOffset(offsetIndex);

            markStackEntryAfter(offset, stackIndex);
        }
    }
}
 
Example #3
Source File: EvaluationShrinker.java    From java-n-IDE-for-Android with Apache License 2.0 6 votes vote down vote up
/**
 * Returns whether the specified variable is ever necessary after all
 * instructions in the specified set of instructions offsets.
 */
private boolean isVariableNecessaryAfterAll(InstructionOffsetValue instructionOffsetValue,
                                            int                    variableIndex)
{
    int count = instructionOffsetValue.instructionOffsetCount();

    for (int index = 0; index < count; index++)
    {
        if (!isVariableNecessaryAfter(instructionOffsetValue.instructionOffset(index),
                                      variableIndex))
        {
            return false;
        }
    }

    return true;
}
 
Example #4
Source File: EvaluationShrinker.java    From java-n-IDE-for-Android with Apache License 2.0 6 votes vote down vote up
/**
 * Returns whether the specified variable is ever necessary after any
 * instructions in the specified set of instructions offsets.
 */
private boolean isVariableNecessaryAfterAny(InstructionOffsetValue instructionOffsetValue,
                                            int                    variableIndex)
{
    int count = instructionOffsetValue.instructionOffsetCount();

    for (int index = 0; index < count; index++)
    {
        if (isVariableNecessaryAfter(instructionOffsetValue.instructionOffset(index),
                                     variableIndex))
        {
            return true;
        }
    }

    return false;
}
 
Example #5
Source File: EvaluationShrinker.java    From java-n-IDE-for-Android with Apache License 2.0 6 votes vote down vote up
/**
 * Returns whether any of the given instruction offsets (at least one)
 * is larger than the given offset.
 */
private boolean isAnyLargerThan(InstructionOffsetValue instructionOffsets,
                                int                    instructionOffset)
{
    if (instructionOffsets != null)
    {
        // Loop over all instruction offsets.
        int branchCount = instructionOffsets.instructionOffsetCount();
        if (branchCount > 0)
        {
            for (int branchIndex = 0; branchIndex < branchCount; branchIndex++)
            {
                // Is the offset larger than the reference offset?
                if (instructionOffsets.instructionOffset(branchIndex) > instructionOffset)
                {
                    return true;
                }
            }
        }
    }

    return false;
}
 
Example #6
Source File: EvaluationShrinker.java    From java-n-IDE-for-Android with Apache License 2.0 6 votes vote down vote up
/**
 * Marks the variable and its producing instructions at the given offsets.
 * @param producerOffsets the offsets of the producers to be marked.
 * @param variableIndex   the index of the variable to be marked.
 */
private void markVariableProducers(InstructionOffsetValue producerOffsets,
                                   int                    variableIndex)
{
    if (producerOffsets != null)
    {
        int offsetCount = producerOffsets.instructionOffsetCount();
        for (int offsetIndex = 0; offsetIndex < offsetCount; offsetIndex++)
        {
            // Make sure the variable and the instruction are marked
            // at the producing offset.
            int offset = producerOffsets.instructionOffset(offsetIndex);

            markVariableAfter(offset, variableIndex);
            markInstruction(offset);
        }
    }
}
 
Example #7
Source File: EvaluationShrinker.java    From java-n-IDE-for-Android with Apache License 2.0 6 votes vote down vote up
/**
 * Marks the stack entry and its producing instructions at the given
 * offsets.
 * @param producerOffsets the offsets of the producers to be marked.
 * @param stackIndex      the index of the stack entry to be marked
 *                        (counting from the bottom).
 */
private void markStackEntryProducers(InstructionOffsetValue producerOffsets,
                                     int                    stackIndex)
{
    if (producerOffsets != null)
    {
        int offsetCount = producerOffsets.instructionOffsetCount();
        for (int offsetIndex = 0; offsetIndex < offsetCount; offsetIndex++)
        {
            // Make sure the stack entry and the instruction are marked
            // at the producing offset.
            int offset = producerOffsets.instructionOffset(offsetIndex);

            markStackEntryAfter(offset, stackIndex);
            markInstruction(offset);
        }
    }
}
 
Example #8
Source File: EvaluationShrinker.java    From java-n-IDE-for-Android with Apache License 2.0 6 votes vote down vote up
/**
 * Returns whether all of the given instruction offsets (at least one)
 * are smaller than or equal to the given offset.
 */
private boolean isAllSmallerThanOrEqual(InstructionOffsetValue instructionOffsets,
                                        int                    instructionOffset)
{
    if (instructionOffsets != null)
    {
        // Loop over all instruction offsets.
        int branchCount = instructionOffsets.instructionOffsetCount();
        if (branchCount > 0)
        {
            for (int branchIndex = 0; branchIndex < branchCount; branchIndex++)
            {
                // Is the offset larger than the reference offset?
                if (instructionOffsets.instructionOffset(branchIndex) > instructionOffset)
                {
                    return false;
                }
            }

            return true;
        }
    }

    return false;
}
 
Example #9
Source File: EvaluationSimplifier.java    From java-n-IDE-for-Android with Apache License 2.0 5 votes vote down vote up
/**
 * Deletes the given branch instruction, or replaces it by a simpler branch
 * instruction, if possible.
 */
private void replaceBranchInstruction(Clazz       clazz,
                                      int         offset,
                                      Instruction instruction)
{
    InstructionOffsetValue branchTargets = partialEvaluator.branchTargets(offset);

    // Is there exactly one branch target (not from a goto or jsr)?
    if (branchTargets != null &&
        branchTargets.instructionOffsetCount() == 1)
    {
        // Is it branching to the next instruction?
        int branchOffset = branchTargets.instructionOffset(0) - offset;
        if (branchOffset == instruction.length(offset))
        {
            if (DEBUG) System.out.println("  Ignoring zero branch instruction at ["+offset+"]");
        }
        else
        {
            // Replace the branch instruction by a simple branch instruction.
            Instruction replacementInstruction =
                new BranchInstruction(InstructionConstants.OP_GOTO_W,
                                      branchOffset).shrink();

            replaceInstruction(clazz, offset, instruction, replacementInstruction);
        }
    }
}
 
Example #10
Source File: PartialEvaluator.java    From java-n-IDE-for-Android with Apache License 2.0 5 votes vote down vote up
/**
 * Initializes the data structures for the variables, stack, etc.
 */
private void initializeParameters(Clazz           clazz,
                                  Method          method,
                                  CodeAttribute codeAttribute,
                                  TracedVariables variables)
{
    // Create the method parameters.
    TracedVariables parameters = new TracedVariables(codeAttribute.u2maxLocals);

    // Remember this instruction's offset with any stored value.
    Value storeValue = new InstructionOffsetValue(AT_METHOD_ENTRY);
    parameters.setProducerValue(storeValue);

    // Initialize the method parameters.
    invocationUnit.enterMethod(clazz, method, parameters);

    if (DEBUG)
    {
        System.out.println("  Params: "+parameters);
    }

    // Initialize the variables with the parameters.
    variables.initialize(parameters);

    // Set the store value of each parameter variable.
    InstructionOffsetValue atMethodEntry = new InstructionOffsetValue(AT_METHOD_ENTRY);

    for (int index = 0; index < parameters.size(); index++)
    {
        variables.setProducerValue(index, atMethodEntry);
    }
}
 
Example #11
Source File: BasicBranchUnit.java    From proguard with GNU General Public License v2.0 5 votes vote down vote up
public void branch(Clazz         clazz,
                   CodeAttribute codeAttribute,
                   int           offset,
                   int           branchTarget)
{
    // Override the branch targets.
    traceBranchTargets = new InstructionOffsetValue(branchTarget);

    wasCalled = true;
}
 
Example #12
Source File: BasicBranchUnit.java    From proguard with GNU General Public License v2.0 5 votes vote down vote up
public void branchConditionally(Clazz         clazz,
                                CodeAttribute codeAttribute,
                                int           offset,
                                int           branchTarget,
                                int           conditional)
{
    // Accumulate the branch targets.
    traceBranchTargets =
        traceBranchTargets.generalize(new InstructionOffsetValue(branchTarget)).instructionOffsetValue();

    wasCalled = true;
}
 
Example #13
Source File: BasicBranchUnit.java    From proguard with GNU General Public License v2.0 5 votes vote down vote up
public void returnFromMethod()
{
    // Stop processing this block.
    traceBranchTargets = InstructionOffsetValue.EMPTY_VALUE;

    wasCalled = true;
}
 
Example #14
Source File: BasicBranchUnit.java    From proguard with GNU General Public License v2.0 5 votes vote down vote up
public void throwException()
{
    // Stop processing this block.
    traceBranchTargets = InstructionOffsetValue.EMPTY_VALUE;

    wasCalled = true;
}
 
Example #15
Source File: EvaluationShrinker.java    From java-n-IDE-for-Android with Apache License 2.0 5 votes vote down vote up
/**
 * Marks the branch instructions of straddling branches, if they straddle
 * some code that has been marked.
 * @param instructionOffset   the offset of the branch origin or branch target.
 * @param branchOffsets       the offsets of the straddling branch targets
 *                            or branch origins.
 * @param isPointingToTargets <code>true</code> if the above offsets are
 *                            branch targets, <code>false</code> if they
 *                            are branch origins.
 */
private void markStraddlingBranches(int                    instructionOffset,
                                    InstructionOffsetValue branchOffsets,
                                    boolean                isPointingToTargets)
{
    if (branchOffsets != null)
    {
        // Loop over all branch offsets.
        int branchCount = branchOffsets.instructionOffsetCount();
        for (int branchIndex = 0; branchIndex < branchCount; branchIndex++)
        {
            // Is the branch straddling forward any necessary instructions?
            int branchOffset = branchOffsets.instructionOffset(branchIndex);

            // Is the offset pointing to a branch origin or to a branch target?
            if (isPointingToTargets)
            {
                markStraddlingBranch(instructionOffset,
                                     branchOffset,
                                     instructionOffset,
                                     branchOffset);
            }
            else
            {
                markStraddlingBranch(instructionOffset,
                                     branchOffset,
                                     branchOffset,
                                     instructionOffset);
            }
        }
    }
}
 
Example #16
Source File: LivenessAnalyzer.java    From java-n-IDE-for-Android with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the combined liveness mask of the variables right before the
 * specified instruction offsets.
 */
private long combinedLiveness(InstructionOffsetValue instructionOffsetValue)
{
    long alive = 0L;

    int count = instructionOffsetValue.instructionOffsetCount();
    for (int index = 0; index < count; index++)
    {
        alive |= isAliveBefore[instructionOffsetValue.instructionOffset(index)];
    }

    return alive;
}
 
Example #17
Source File: BasicBranchUnit.java    From java-n-IDE-for-Android with Apache License 2.0 5 votes vote down vote up
public void throwException()
{
    // Stop processing this block.
    traceBranchTargets = InstructionOffsetValue.EMPTY_VALUE;

    wasCalled = true;
}
 
Example #18
Source File: BasicBranchUnit.java    From java-n-IDE-for-Android with Apache License 2.0 5 votes vote down vote up
public void returnFromMethod()
{
    // Stop processing this block.
    traceBranchTargets = InstructionOffsetValue.EMPTY_VALUE;

    wasCalled = true;
}
 
Example #19
Source File: BasicBranchUnit.java    From java-n-IDE-for-Android with Apache License 2.0 5 votes vote down vote up
public void branchConditionally(Clazz         clazz,
                                CodeAttribute codeAttribute,
                                int           offset,
                                int           branchTarget,
                                int           conditional)
{
    // Accumulate the branch targets.
    traceBranchTargets =
        traceBranchTargets.generalize(new InstructionOffsetValue(branchTarget)).instructionOffsetValue();

    wasCalled = true;
}
 
Example #20
Source File: BasicBranchUnit.java    From java-n-IDE-for-Android with Apache License 2.0 5 votes vote down vote up
public void branch(Clazz         clazz,
                   CodeAttribute codeAttribute,
                   int           offset,
                   int           branchTarget)
{
    // Override the branch targets.
    traceBranchTargets = new InstructionOffsetValue(branchTarget);

    wasCalled = true;
}
 
Example #21
Source File: BasicBranchUnit.java    From bazel with Apache License 2.0 5 votes vote down vote up
public void branch(Clazz         clazz,
                   CodeAttribute codeAttribute,
                   int           offset,
                   int           branchTarget)
{
    // Override the branch targets.
    traceBranchTargets = new InstructionOffsetValue(branchTarget);

    wasCalled = true;
}
 
Example #22
Source File: BasicBranchUnit.java    From bazel with Apache License 2.0 5 votes vote down vote up
public void branchConditionally(Clazz         clazz,
                                CodeAttribute codeAttribute,
                                int           offset,
                                int           branchTarget,
                                int           conditional)
{
    // Accumulate the branch targets.
    traceBranchTargets =
        traceBranchTargets.generalize(new InstructionOffsetValue(branchTarget)).instructionOffsetValue();

    wasCalled = true;
}
 
Example #23
Source File: BasicBranchUnit.java    From bazel with Apache License 2.0 5 votes vote down vote up
public void returnFromMethod()
{
    // Stop processing this block.
    traceBranchTargets = InstructionOffsetValue.EMPTY_VALUE;

    wasCalled = true;
}
 
Example #24
Source File: BasicBranchUnit.java    From bazel with Apache License 2.0 5 votes vote down vote up
public void throwException()
{
    // Stop processing this block.
    traceBranchTargets = InstructionOffsetValue.EMPTY_VALUE;

    wasCalled = true;
}
 
Example #25
Source File: BasicBranchUnit.java    From bazel with Apache License 2.0 4 votes vote down vote up
/**
 * Sets the initial branch targets, which will be updated as the branch
 * methods of the branch unit are called.
 */
public void setTraceBranchTargets(InstructionOffsetValue branchTargets)
{
    this.traceBranchTargets = branchTargets;
}
 
Example #26
Source File: BasicBranchUnit.java    From bazel with Apache License 2.0 4 votes vote down vote up
public InstructionOffsetValue getTraceBranchTargets()
{
    return traceBranchTargets;
}
 
Example #27
Source File: BasicBranchUnit.java    From proguard with GNU General Public License v2.0 4 votes vote down vote up
public InstructionOffsetValue getTraceBranchTargets()
{
    return traceBranchTargets;
}
 
Example #28
Source File: BasicBranchUnit.java    From proguard with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Sets the initial branch targets, which will be updated as the branch
 * methods of the branch unit are called.
 */
public void setTraceBranchTargets(InstructionOffsetValue branchTargets)
{
    this.traceBranchTargets = branchTargets;
}
 
Example #29
Source File: PartialEvaluator.java    From java-n-IDE-for-Android with Apache License 2.0 4 votes vote down vote up
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
    {
//        DEBUG = DEBUG_RESULTS =
//            clazz.getName().equals("abc/Def") &&
//            method.getName(clazz).equals("abc");

        // TODO: Remove this when the partial evaluator has stabilized.
        // Catch any unexpected exceptions from the actual visiting method.
        try
        {
            // Process the code.
            visitCodeAttribute0(clazz, method, codeAttribute);
        }
        catch (RuntimeException ex)
        {
            System.err.println("Unexpected error while performing partial evaluation:");
            System.err.println("  Class       = ["+clazz.getName()+"]");
            System.err.println("  Method      = ["+method.getName(clazz)+method.getDescriptor(clazz)+"]");
            System.err.println("  Exception   = ["+ex.getClass().getName()+"] ("+ex.getMessage()+")");

            if (DEBUG)
            {
                method.accept(clazz, new ClassPrinter());

                System.out.println("Evaluation results:");

                int offset = 0;
                do
                {
                    if (isBranchOrExceptionTarget(offset))
                    {
                        System.out.println("Branch target from ["+branchOriginValues[offset]+"]:");
                        if (isTraced(offset))
                        {
                            System.out.println("  Vars:  "+variablesBefore[offset]);
                            System.out.println("  Stack: "+stacksBefore[offset]);
                        }
                    }

                    Instruction instruction = InstructionFactory.create(codeAttribute.code,
                                                                        offset);
                    System.out.println(instruction.toString(offset));

                    if (isTraced(offset))
                    {
                        int initializationOffset = branchTargetFinder.initializationOffset(offset);
                        if (initializationOffset != NONE)
                        {
                            System.out.println("     is to be initialized at ["+initializationOffset+"]");
                        }

                        InstructionOffsetValue branchTargets = branchTargets(offset);
                        if (branchTargets != null)
                        {
                            System.out.println("     has overall been branching to "+branchTargets);
                        }

                        System.out.println("  Vars:  "+variablesAfter[offset]);
                        System.out.println("  Stack: "+stacksAfter[offset]);
                    }

                    offset += instruction.length(offset);
                }
                while (offset < codeAttribute.u4codeLength);
            }

            throw ex;
        }
    }
 
Example #30
Source File: EvaluationSimplifier.java    From java-n-IDE-for-Android with Apache License 2.0 4 votes vote down vote up
/**
 * Makes sure all branch targets of the given switch instruction are valid.
 */
private void replaceSwitchInstruction(Clazz             clazz,
                                      int               offset,
                                      SwitchInstruction switchInstruction)
{
    // Get the actual branch targets.
    InstructionOffsetValue branchTargets = partialEvaluator.branchTargets(offset);

    // Get an offset that can serve as a valid default offset.
    int defaultOffset =
        branchTargets.instructionOffset(branchTargets.instructionOffsetCount()-1) -
        offset;

    Instruction replacementInstruction = null;

    // Check the jump offsets.
    int[] jumpOffsets = switchInstruction.jumpOffsets;
    for (int index = 0; index < jumpOffsets.length; index++)
    {
        if (!branchTargets.contains(offset + jumpOffsets[index]))
        {
            // Replace the unused offset.
            jumpOffsets[index] = defaultOffset;

            // Remember to replace the instruction.
            replacementInstruction = switchInstruction;
        }
    }

    // Check the default offset.
    if (!branchTargets.contains(offset + switchInstruction.defaultOffset))
    {
        // Replace the unused offset.
        switchInstruction.defaultOffset = defaultOffset;

        // Remember to replace the instruction.
        replacementInstruction = switchInstruction;
    }

    if (replacementInstruction != null)
    {
        replaceInstruction(clazz, offset, switchInstruction, replacementInstruction);
    }
}