Search in sources :

Example 6 with LocalVariableTable

use of org.apache.bcel.classfile.LocalVariableTable in project fb-contrib by mebigfatguy.

the class PoorlyDefinedParameter method sawOpcodeAfterCheckCast.

private void sawOpcodeAfterCheckCast(int seen) {
    state = State.SAW_NOTHING;
    if (!((seen == PUTFIELD) || (seen == ASTORE) || ((seen >= ASTORE_0) && (seen <= ASTORE_3)))) {
        return;
    }
    String parmName = null;
    LocalVariableTable lvt = getMethod().getLocalVariableTable();
    if (lvt != null) {
        LocalVariable lv = lvt.getLocalVariable(loadedReg, 1);
        if (lv != null) {
            parmName = lv.getName();
        }
    }
    if (parmName == null) {
        parmName = "(" + loadedReg + ')';
    }
    BugInstance bug = new BugInstance(this, BugType.PDP_POORLY_DEFINED_PARAMETER.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this).addString(parmName);
    Integer lr = Integer.valueOf(loadedReg);
    BugInfo bi = bugs.get(lr);
    if (bi == null) {
        bugs.put(lr, new BugInfo(castClass, bug));
    } else {
        // report it altho suspect
        if (!bi.castClass.equals(castClass)) {
            bugs.remove(lr);
        }
    }
}
Also used : LocalVariableTable(org.apache.bcel.classfile.LocalVariableTable) LocalVariable(org.apache.bcel.classfile.LocalVariable) BugInstance(edu.umd.cs.findbugs.BugInstance)

Example 7 with LocalVariableTable

use of org.apache.bcel.classfile.LocalVariableTable in project fb-contrib by mebigfatguy.

the class PossibleConstantAllocationInLoop method isFirstUse.

/**
 * looks to see if this register has already in scope or whether is a new assignment. return true if it's a new assignment. If you can't tell, return true
 * anyway. might want to change.
 *
 * @param reg
 *            the store register
 * @return whether this is a new register scope assignment
 */
private boolean isFirstUse(int reg) {
    LocalVariableTable lvt = getMethod().getLocalVariableTable();
    if (lvt == null) {
        return true;
    }
    LocalVariable lv = lvt.getLocalVariable(reg, getPC());
    return lv == null;
}
Also used : LocalVariableTable(org.apache.bcel.classfile.LocalVariableTable) LocalVariable(org.apache.bcel.classfile.LocalVariable)

Example 8 with LocalVariableTable

use of org.apache.bcel.classfile.LocalVariableTable in project commons-bcel by apache.

the class Pass3aVerifier method delayedPass2Checks.

/**
 * These are the checks that could be done in pass 2 but are delayed to pass 3
 * for performance reasons. Also, these checks need access to the code array
 * of the Code attribute of a Method so it's okay to perform them here.
 * Also see the description of the do_verify() method.
 *
 * @throws ClassConstraintException if the verification fails.
 * @see #do_verify()
 */
private void delayedPass2Checks() {
    final int[] instructionPositions = instructionList.getInstructionPositions();
    final int codeLength = code.getCode().length;
    // ///////////////////
    // LineNumberTable //
    // ///////////////////
    final LineNumberTable lnt = code.getLineNumberTable();
    if (lnt != null) {
        final LineNumber[] lineNumbers = lnt.getLineNumberTable();
        final IntList offsets = new IntList();
        lineNumber_loop: for (final LineNumber lineNumber : lineNumbers) {
            // may appear in any order.
            for (final int instructionPosition : instructionPositions) {
                // TODO: Make this a binary search! The instructionPositions array is naturally ordered!
                final int offset = lineNumber.getStartPC();
                if (instructionPosition == offset) {
                    if (offsets.contains(offset)) {
                        addMessage("LineNumberTable attribute '" + code.getLineNumberTable() + "' refers to the same code offset ('" + offset + "') more than once" + " which is violating the semantics [but is sometimes produced by IBM's 'jikes' compiler].");
                    } else {
                        offsets.add(offset);
                    }
                    continue lineNumber_loop;
                }
            }
            throw new ClassConstraintException("Code attribute '" + code + "' has a LineNumberTable attribute '" + code.getLineNumberTable() + "' referring to a code offset ('" + lineNumber.getStartPC() + "') that does not exist.");
        }
    }
    // /////////////////////////
    // LocalVariableTable(s) //
    // /////////////////////////
    /* We cannot use code.getLocalVariableTable() because there could be more
           than only one. This is a bug in BCEL. */
    final Attribute[] atts = code.getAttributes();
    for (final Attribute att : atts) {
        if (att instanceof LocalVariableTable) {
            final LocalVariableTable lvt = (LocalVariableTable) att;
            final LocalVariable[] localVariables = lvt.getLocalVariableTable();
            for (final LocalVariable localVariable : localVariables) {
                final int startpc = localVariable.getStartPC();
                final int length = localVariable.getLength();
                if (!contains(instructionPositions, startpc)) {
                    throw new ClassConstraintException("Code attribute '" + code + "' has a LocalVariableTable attribute '" + code.getLocalVariableTable() + "' referring to a code offset ('" + startpc + "') that does not exist.");
                }
                if (!contains(instructionPositions, startpc + length) && startpc + length != codeLength) {
                    throw new ClassConstraintException("Code attribute '" + code + "' has a LocalVariableTable attribute '" + code.getLocalVariableTable() + "' referring to a code offset start_pc+length ('" + (startpc + length) + "') that does not exist.");
                }
            }
        }
    }
    // //////////////////
    // ExceptionTable //
    // //////////////////
    // In BCEL's "classfile" API, the startPC/endPC-notation is
    // inclusive/exclusive as in the Java Virtual Machine Specification.
    // WARNING: This is not true for BCEL's "generic" API.
    final CodeException[] exceptionTable = code.getExceptionTable();
    for (final CodeException element : exceptionTable) {
        final int startpc = element.getStartPC();
        final int endpc = element.getEndPC();
        final int handlerpc = element.getHandlerPC();
        if (startpc >= endpc) {
            throw new ClassConstraintException("Code attribute '" + code + "' has an exception_table entry '" + element + "' that has its start_pc ('" + startpc + "') not smaller than its end_pc ('" + endpc + "').");
        }
        if (!contains(instructionPositions, startpc)) {
            throw new ClassConstraintException("Code attribute '" + code + "' has an exception_table entry '" + element + "' that has a non-existant bytecode offset as its start_pc ('" + startpc + "').");
        }
        if (!contains(instructionPositions, endpc) && endpc != codeLength) {
            throw new ClassConstraintException("Code attribute '" + code + "' has an exception_table entry '" + element + "' that has a non-existant bytecode offset as its end_pc ('" + startpc + "') [that is also not equal to code_length ('" + codeLength + "')].");
        }
        if (!contains(instructionPositions, handlerpc)) {
            throw new ClassConstraintException("Code attribute '" + code + "' has an exception_table entry '" + element + "' that has a non-existant bytecode offset as its handler_pc ('" + handlerpc + "').");
        }
    }
}
Also used : LocalVariableTable(org.apache.bcel.classfile.LocalVariableTable) CodeException(org.apache.bcel.classfile.CodeException) Attribute(org.apache.bcel.classfile.Attribute) LocalVariable(org.apache.bcel.classfile.LocalVariable) LineNumberTable(org.apache.bcel.classfile.LineNumberTable) LineNumber(org.apache.bcel.classfile.LineNumber) ClassConstraintException(org.apache.bcel.verifier.exc.ClassConstraintException)

Example 9 with LocalVariableTable

use of org.apache.bcel.classfile.LocalVariableTable in project commons-bcel by apache.

the class CodeHTML method findGotos.

/**
 * Find all target addresses in code, so that they can be marked
 * with &lt;A NAME = ...&gt;. Target addresses are kept in an BitSet object.
 */
private void findGotos(final ByteSequence bytes, final Code code) throws IOException {
    int index;
    gotoSet = new BitSet(bytes.available());
    int opcode;
    /* First get Code attribute from method and the exceptions handled
         * (try .. catch) in this method. We only need the line number here.
         */
    if (code != null) {
        final CodeException[] ce = code.getExceptionTable();
        for (final CodeException cex : ce) {
            gotoSet.set(cex.getStartPC());
            gotoSet.set(cex.getEndPC());
            gotoSet.set(cex.getHandlerPC());
        }
        // Look for local variables and their range
        final Attribute[] attributes = code.getAttributes();
        for (final Attribute attribute : attributes) {
            if (attribute.getTag() == Const.ATTR_LOCAL_VARIABLE_TABLE) {
                final LocalVariable[] vars = ((LocalVariableTable) attribute).getLocalVariableTable();
                for (final LocalVariable var : vars) {
                    final int start = var.getStartPC();
                    final int end = start + var.getLength();
                    gotoSet.set(start);
                    gotoSet.set(end);
                }
                break;
            }
        }
    }
    // Get target addresses from GOTO, JSR, TABLESWITCH, etc.
    for (; bytes.available() > 0; ) {
        opcode = bytes.readUnsignedByte();
        // System.out.println(getOpcodeName(opcode));
        switch(opcode) {
            case Const.TABLESWITCH:
            case Const.LOOKUPSWITCH:
                // bytes.readByte(); // Skip already read byte
                final int remainder = bytes.getIndex() % 4;
                final int no_pad_bytes = remainder == 0 ? 0 : 4 - remainder;
                int default_offset;
                int offset;
                for (int j = 0; j < no_pad_bytes; j++) {
                    bytes.readByte();
                }
                // Both cases have a field default_offset in common
                default_offset = bytes.readInt();
                if (opcode == Const.TABLESWITCH) {
                    final int low = bytes.readInt();
                    final int high = bytes.readInt();
                    offset = bytes.getIndex() - 12 - no_pad_bytes - 1;
                    default_offset += offset;
                    gotoSet.set(default_offset);
                    for (int j = 0; j < high - low + 1; j++) {
                        index = offset + bytes.readInt();
                        gotoSet.set(index);
                    }
                } else {
                    // LOOKUPSWITCH
                    final int npairs = bytes.readInt();
                    offset = bytes.getIndex() - 8 - no_pad_bytes - 1;
                    default_offset += offset;
                    gotoSet.set(default_offset);
                    for (int j = 0; j < npairs; j++) {
                        // int match = bytes.readInt();
                        bytes.readInt();
                        index = offset + bytes.readInt();
                        gotoSet.set(index);
                    }
                }
                break;
            case Const.GOTO:
            case Const.IFEQ:
            case Const.IFGE:
            case Const.IFGT:
            case Const.IFLE:
            case Const.IFLT:
            case Const.IFNE:
            case Const.IFNONNULL:
            case Const.IFNULL:
            case Const.IF_ACMPEQ:
            case Const.IF_ACMPNE:
            case Const.IF_ICMPEQ:
            case Const.IF_ICMPGE:
            case Const.IF_ICMPGT:
            case Const.IF_ICMPLE:
            case Const.IF_ICMPLT:
            case Const.IF_ICMPNE:
            case Const.JSR:
                // bytes.readByte(); // Skip already read byte
                index = bytes.getIndex() + bytes.readShort() - 1;
                gotoSet.set(index);
                break;
            case Const.GOTO_W:
            case Const.JSR_W:
                // bytes.readByte(); // Skip already read byte
                index = bytes.getIndex() + bytes.readInt() - 1;
                gotoSet.set(index);
                break;
            default:
                bytes.unreadByte();
                // Ignore output
                codeToHTML(bytes, 0);
        }
    }
}
Also used : CodeException(org.apache.bcel.classfile.CodeException) LocalVariableTable(org.apache.bcel.classfile.LocalVariableTable) Attribute(org.apache.bcel.classfile.Attribute) BitSet(java.util.BitSet) LocalVariable(org.apache.bcel.classfile.LocalVariable)

Example 10 with LocalVariableTable

use of org.apache.bcel.classfile.LocalVariableTable in project commons-bcel by apache.

the class AttributeHTML method writeAttribute.

void writeAttribute(final Attribute attribute, final String anchor, final int method_number) {
    final byte tag = attribute.getTag();
    int index;
    if (tag == Const.ATTR_UNKNOWN) {
        return;
    }
    // Increment number of attributes found so far
    attr_count++;
    if (attr_count % 2 == 0) {
        file.print("<TR BGCOLOR=\"#C0C0C0\"><TD>");
    } else {
        file.print("<TR BGCOLOR=\"#A0A0A0\"><TD>");
    }
    file.println("<H4><A NAME=\"" + anchor + "\">" + attr_count + " " + Const.getAttributeName(tag) + "</A></H4>");
    /* Handle different attributes
         */
    switch(tag) {
        case Const.ATTR_CODE:
            final Code c = (Code) attribute;
            // Some directly printable values
            file.print("<UL><LI>Maximum stack size = " + c.getMaxStack() + "</LI>\n<LI>Number of local variables = " + c.getMaxLocals() + "</LI>\n<LI><A HREF=\"" + class_name + "_code.html#method" + method_number + "\" TARGET=Code>Byte code</A></LI></UL>\n");
            // Get handled exceptions and list them
            final CodeException[] ce = c.getExceptionTable();
            final int len = ce.length;
            if (len > 0) {
                file.print("<P><B>Exceptions handled</B><UL>");
                for (final CodeException cex : ce) {
                    // Index in constant pool
                    final int catch_type = cex.getCatchType();
                    file.print("<LI>");
                    if (catch_type != 0) {
                        // Create Link to _cp.html
                        file.print(constant_html.referenceConstant(catch_type));
                    } else {
                        file.print("Any Exception");
                    }
                    file.print("<BR>(Ranging from lines " + codeLink(cex.getStartPC(), method_number) + " to " + codeLink(cex.getEndPC(), method_number) + ", handled at line " + codeLink(cex.getHandlerPC(), method_number) + ")</LI>");
                }
                file.print("</UL>");
            }
            break;
        case Const.ATTR_CONSTANT_VALUE:
            index = ((ConstantValue) attribute).getConstantValueIndex();
            // Reference _cp.html
            file.print("<UL><LI><A HREF=\"" + class_name + "_cp.html#cp" + index + "\" TARGET=\"ConstantPool\">Constant value index(" + index + ")</A></UL>\n");
            break;
        case Const.ATTR_SOURCE_FILE:
            index = ((SourceFile) attribute).getSourceFileIndex();
            // Reference _cp.html
            file.print("<UL><LI><A HREF=\"" + class_name + "_cp.html#cp" + index + "\" TARGET=\"ConstantPool\">Source file index(" + index + ")</A></UL>\n");
            break;
        case Const.ATTR_EXCEPTIONS:
            // List thrown exceptions
            final int[] indices = ((ExceptionTable) attribute).getExceptionIndexTable();
            file.print("<UL>");
            for (final int indice : indices) {
                file.print("<LI><A HREF=\"" + class_name + "_cp.html#cp" + indice + "\" TARGET=\"ConstantPool\">Exception class index(" + indice + ")</A>\n");
            }
            file.print("</UL>\n");
            break;
        case Const.ATTR_LINE_NUMBER_TABLE:
            final LineNumber[] line_numbers = ((LineNumberTable) attribute).getLineNumberTable();
            // List line number pairs
            file.print("<P>");
            for (int i = 0; i < line_numbers.length; i++) {
                file.print("(" + line_numbers[i].getStartPC() + ",&nbsp;" + line_numbers[i].getLineNumber() + ")");
                if (i < line_numbers.length - 1) {
                    // breakable
                    file.print(", ");
                }
            }
            break;
        case Const.ATTR_LOCAL_VARIABLE_TABLE:
            final LocalVariable[] vars = ((LocalVariableTable) attribute).getLocalVariableTable();
            // List name, range and type
            file.print("<UL>");
            for (final LocalVariable var : vars) {
                index = var.getSignatureIndex();
                String signature = ((ConstantUtf8) constant_pool.getConstant(index, Const.CONSTANT_Utf8)).getBytes();
                signature = Utility.signatureToString(signature, false);
                final int start = var.getStartPC();
                final int end = start + var.getLength();
                file.println("<LI>" + Class2HTML.referenceType(signature) + "&nbsp;<B>" + var.getName() + "</B> in slot %" + var.getIndex() + "<BR>Valid from lines " + "<A HREF=\"" + class_name + "_code.html#code" + method_number + "@" + start + "\" TARGET=Code>" + start + "</A> to " + "<A HREF=\"" + class_name + "_code.html#code" + method_number + "@" + end + "\" TARGET=Code>" + end + "</A></LI>");
            }
            file.print("</UL>\n");
            break;
        case Const.ATTR_INNER_CLASSES:
            final InnerClass[] classes = ((InnerClasses) attribute).getInnerClasses();
            // List inner classes
            file.print("<UL>");
            for (final InnerClass classe : classes) {
                final String name;
                final String access;
                index = classe.getInnerNameIndex();
                if (index > 0) {
                    name = ((ConstantUtf8) constant_pool.getConstant(index, Const.CONSTANT_Utf8)).getBytes();
                } else {
                    name = "&lt;anonymous&gt;";
                }
                access = Utility.accessToString(classe.getInnerAccessFlags());
                file.print("<LI><FONT COLOR=\"#FF0000\">" + access + "</FONT> " + constant_html.referenceConstant(classe.getInnerClassIndex()) + " in&nbsp;class " + constant_html.referenceConstant(classe.getOuterClassIndex()) + " named " + name + "</LI>\n");
            }
            file.print("</UL>\n");
            break;
        default:
            // Such as Unknown attribute or Deprecated
            file.print("<P>" + attribute);
    }
    file.println("</TD></TR>");
    file.flush();
}
Also used : CodeException(org.apache.bcel.classfile.CodeException) LocalVariableTable(org.apache.bcel.classfile.LocalVariableTable) LocalVariable(org.apache.bcel.classfile.LocalVariable) ExceptionTable(org.apache.bcel.classfile.ExceptionTable) InnerClasses(org.apache.bcel.classfile.InnerClasses) ConstantUtf8(org.apache.bcel.classfile.ConstantUtf8) Code(org.apache.bcel.classfile.Code) LineNumber(org.apache.bcel.classfile.LineNumber) LineNumberTable(org.apache.bcel.classfile.LineNumberTable) InnerClass(org.apache.bcel.classfile.InnerClass)

Aggregations

LocalVariableTable (org.apache.bcel.classfile.LocalVariableTable)32 LocalVariable (org.apache.bcel.classfile.LocalVariable)25 BugInstance (edu.umd.cs.findbugs.BugInstance)7 Method (org.apache.bcel.classfile.Method)7 Attribute (org.apache.bcel.classfile.Attribute)6 Code (org.apache.bcel.classfile.Code)5 ExceptionTable (org.apache.bcel.classfile.ExceptionTable)5 ArrayList (java.util.ArrayList)4 CodeException (org.apache.bcel.classfile.CodeException)4 ConstantString (org.apache.bcel.classfile.ConstantString)4 LineNumberTable (org.apache.bcel.classfile.LineNumberTable)4 Type (org.apache.bcel.generic.Type)4 XMethod (edu.umd.cs.findbugs.ba.XMethod)3 Constant (org.apache.bcel.classfile.Constant)3 ConstantPool (org.apache.bcel.classfile.ConstantPool)3 JavaClass (org.apache.bcel.classfile.JavaClass)3 ConstantPoolGen (org.apache.bcel.generic.ConstantPoolGen)3 ToString (com.mebigfatguy.fbcontrib.utils.ToString)2 SignatureParser (edu.umd.cs.findbugs.ba.SignatureParser)2 BitSet (java.util.BitSet)2