Source Code Cross Referenced for ModifiedPass3bVerifier.java in  » Byte-Code » asm » org » apache » bcel » verifier » structurals » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Byte Code » asm » org.apache.bcel.verifier.structurals 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright  2000-2004 The Apache Software Foundation
003:         *
004:         *  Licensed under the Apache License, Version 2.0 (the "License"); 
005:         *  you may not use this file except in compliance with the License.
006:         *  You may obtain a copy of the License at
007:         *
008:         *      http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         *  Unless required by applicable law or agreed to in writing, software
011:         *  distributed under the License is distributed on an "AS IS" BASIS,
012:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         *  See the License for the specific language governing permissions and
014:         *  limitations under the License. 
015:         *
016:         */
017:        package org.apache.bcel.verifier.structurals;
018:
019:        import java.io.PrintWriter;
020:        import java.io.StringWriter;
021:        import java.util.ArrayList;
022:        import java.util.List;
023:        import java.util.Random;
024:        import java.util.Vector;
025:
026:        import org.apache.bcel.Constants;
027:        import org.apache.bcel.Repository;
028:        import org.apache.bcel.classfile.JavaClass;
029:        import org.apache.bcel.classfile.Method;
030:        import org.apache.bcel.generic.ConstantPoolGen;
031:        import org.apache.bcel.generic.GETFIELD;
032:        import org.apache.bcel.generic.InstructionHandle;
033:        import org.apache.bcel.generic.InvokeInstruction;
034:        import org.apache.bcel.generic.JsrInstruction;
035:        import org.apache.bcel.generic.LoadInstruction;
036:        import org.apache.bcel.generic.MethodGen;
037:        import org.apache.bcel.generic.ObjectType;
038:        import org.apache.bcel.generic.RET;
039:        import org.apache.bcel.generic.ReturnInstruction;
040:        import org.apache.bcel.generic.ReturnaddressType;
041:        import org.apache.bcel.generic.Type;
042:        import org.apache.bcel.verifier.PassVerifier;
043:        import org.apache.bcel.verifier.VerificationResult;
044:        import org.apache.bcel.verifier.Verifier;
045:        import org.apache.bcel.verifier.exc.AssertionViolatedException;
046:        import org.apache.bcel.verifier.exc.StructuralCodeConstraintException;
047:        import org.apache.bcel.verifier.exc.VerifierConstraintViolatedException;
048:
049:        /**
050:         * This PassVerifier verifies a method of class file according to pass 3,
051:         * so-called structural verification as described in The Java Virtual Machine
052:         * Specification, 2nd edition.
053:         * More detailed information is to be found at the do_verify() method's
054:         * documentation. 
055:         *
056:         * @version $Id: ModifiedPass3bVerifier.java,v 1.3 2007-11-08 17:22:56 ebruneton Exp $
057:         * @author Enver Haase
058:         * @see #do_verify()
059:         */
060:
061:        public final class ModifiedPass3bVerifier extends PassVerifier {
062:            /* TODO:    Throughout pass 3b, upper halves of LONG and DOUBLE
063:                                are represented by Type.UNKNOWN. This should be changed
064:                                in favour of LONG_Upper and DOUBLE_Upper as in pass 2. */
065:
066:            /**
067:             * An InstructionContextQueue is a utility class that holds
068:             * (InstructionContext, ArrayList) pairs in a Queue data structure.
069:             * This is used to hold information about InstructionContext objects
070:             * externally --- i.e. that information is not saved inside the
071:             * InstructionContext object itself. This is useful to save the
072:             * execution path of the symbolic execution of the
073:             * Pass3bVerifier - this is not information
074:             * that belongs into the InstructionContext object itself.
075:             * Only at "execute()"ing
076:             * time, an InstructionContext object will get the current information
077:             * we have about its symbolic execution predecessors.
078:             */
079:            private static final class InstructionContextQueue {
080:                private List ics = new Vector(); // Type: InstructionContext
081:                private List ecs = new Vector(); // Type: ArrayList (of InstructionContext)
082:
083:                public void add(InstructionContext ic, ArrayList executionChain) {
084:                    ics.add(ic);
085:                    ecs.add(executionChain);
086:                }
087:
088:                public boolean isEmpty() {
089:                    return ics.isEmpty();
090:                }
091:
092:                public void remove() {
093:                    this .remove(0);
094:                }
095:
096:                public void remove(int i) {
097:                    ics.remove(i);
098:                    ecs.remove(i);
099:                }
100:
101:                public InstructionContext getIC(int i) {
102:                    return (InstructionContext) ics.get(i);
103:                }
104:
105:                public ArrayList getEC(int i) {
106:                    return (ArrayList) ecs.get(i);
107:                }
108:
109:                public int size() {
110:                    return ics.size();
111:                }
112:            } // end Inner Class InstructionContextQueue
113:
114:            /** In DEBUG mode, the verification algorithm is not randomized. */
115:            private static final boolean DEBUG = true;
116:
117:            private JavaClass jc;
118:
119:            /** The method number to verify. */
120:            private int method_no;
121:
122:            /**
123:             * This class should only be instantiated by a Verifier.
124:             *
125:             * @see org.apache.bcel.verifier.Verifier
126:             */
127:            public ModifiedPass3bVerifier(JavaClass jc, int method_no) {
128:                this .jc = jc;
129:                this .method_no = method_no;
130:            }
131:
132:            /**
133:             * Whenever the outgoing frame
134:             * situation of an InstructionContext changes, all its successors are
135:             * put [back] into the queue [as if they were unvisited].
136:             * The proof of termination is about the existence of a
137:             * fix point of frame merging.
138:             */
139:            private void circulationPump(MethodGen m, ControlFlowGraph cfg,
140:                    InstructionContext start, Frame vanillaFrame,
141:                    InstConstraintVisitor icv, ExecutionVisitor ev) {
142:                final Random random = new Random();
143:                InstructionContextQueue icq = new InstructionContextQueue();
144:
145:                start.execute(vanillaFrame, new ArrayList(), icv, ev); // new ArrayList() <=>  no Instruction was executed before
146:                //                                  => Top-Level routine (no jsr call before)
147:                icq.add(start, new ArrayList());
148:
149:                // LOOP!
150:                while (!icq.isEmpty()) {
151:                    InstructionContext u;
152:                    ArrayList ec;
153:                    if (!DEBUG) {
154:                        int r = random.nextInt(icq.size());
155:                        u = icq.getIC(r);
156:                        ec = icq.getEC(r);
157:                        icq.remove(r);
158:                    } else {
159:                        u = icq.getIC(0);
160:                        ec = icq.getEC(0);
161:                        icq.remove(0);
162:                    }
163:
164:                    ArrayList oldchain = (ArrayList) (ec.clone());
165:                    ArrayList newchain = (ArrayList) (ec.clone());
166:                    newchain.add(u);
167:
168:                    if ((u.getInstruction().getInstruction()) instanceof  RET) {
169:                        //System.err.println(u);
170:                        // We can only follow _one_ successor, the one after the
171:                        // JSR that was recently executed.
172:                        RET ret = (RET) (u.getInstruction().getInstruction());
173:                        ReturnaddressType t = (ReturnaddressType) u
174:                                .getOutFrame(oldchain).getLocals().get(
175:                                        ret.getIndex());
176:                        InstructionContext theSuccessor = cfg.contextOf(t
177:                                .getTarget());
178:
179:                        // Sanity check
180:                        InstructionContext lastJSR = null;
181:                        int skip_jsr = 0;
182:                        for (int ss = oldchain.size() - 1; ss >= 0; ss--) {
183:                            if (skip_jsr < 0) {
184:                                throw new AssertionViolatedException(
185:                                        "More RET than JSR in execution chain?!");
186:                            }
187:                            //System.err.println("+"+oldchain.get(ss));
188:                            if (((InstructionContext) oldchain.get(ss))
189:                                    .getInstruction().getInstruction() instanceof  JsrInstruction) {
190:                                if (skip_jsr == 0) {
191:                                    lastJSR = (InstructionContext) oldchain
192:                                            .get(ss);
193:                                    break;
194:                                } else {
195:                                    skip_jsr--;
196:                                }
197:                            }
198:                            if (((InstructionContext) oldchain.get(ss))
199:                                    .getInstruction().getInstruction() instanceof  RET) {
200:                                skip_jsr++;
201:                            }
202:                        }
203:                        if (lastJSR == null) {
204:                            throw new AssertionViolatedException(
205:                                    "RET without a JSR before in ExecutionChain?! EC: '"
206:                                            + oldchain + "'.");
207:                        }
208:                        JsrInstruction jsr = (JsrInstruction) (lastJSR
209:                                .getInstruction().getInstruction());
210:                        if (theSuccessor != (cfg.contextOf(jsr
211:                                .physicalSuccessor()))) {
212:                            throw new AssertionViolatedException("RET '"
213:                                    + u.getInstruction()
214:                                    + "' info inconsistent: jump back to '"
215:                                    + theSuccessor + "' or '"
216:                                    + cfg.contextOf(jsr.physicalSuccessor())
217:                                    + "'?");
218:                        }
219:
220:                        if (theSuccessor.execute(u.getOutFrame(oldchain),
221:                                newchain, icv, ev)) {
222:                            icq.add(theSuccessor, (ArrayList) newchain.clone());
223:                        }
224:                    } else {// "not a ret"
225:
226:                        // Normal successors. Add them to the queue of successors.
227:                        InstructionContext[] succs = u.getSuccessors();
228:                        for (int s = 0; s < succs.length; s++) {
229:                            InstructionContext v = succs[s];
230:                            if (v.execute(u.getOutFrame(oldchain), newchain,
231:                                    icv, ev)) {
232:                                icq.add(v, (ArrayList) newchain.clone());
233:                            }
234:                        }
235:                    }// end "not a ret"
236:
237:                    // Exception Handlers. Add them to the queue of successors.
238:                    // [subroutines are never protected; mandated by JustIce]
239:                    ExceptionHandler[] exc_hds = u.getExceptionHandlers();
240:                    for (int s = 0; s < exc_hds.length; s++) {
241:                        InstructionContext v = cfg.contextOf(exc_hds[s]
242:                                .getHandlerStart());
243:                        // TODO: the "oldchain" and "newchain" is used to determine the subroutine
244:                        // we're in (by searching for the last JSR) by the InstructionContext
245:                        // implementation. Therefore, we should not use this chain mechanism
246:                        // when dealing with exception handlers.
247:                        // Example: a JSR with an exception handler as its successor does not
248:                        // mean we're in a subroutine if we go to the exception handler.
249:                        // We should address this problem later; by now we simply "cut" the chain
250:                        // by using an empty chain for the exception handlers.
251:                        //if (v.execute(new Frame(u.getOutFrame(oldchain).getLocals(), new OperandStack (u.getOutFrame().getStack().maxStack(), (exc_hds[s].getExceptionType()==null? Type.THROWABLE : exc_hds[s].getExceptionType())) ), newchain), icv, ev){
252:                        //icq.add(v, (ArrayList) newchain.clone());
253:                        if (v.execute(new Frame(u.getOutFrame(oldchain)
254:                                .getLocals(), new OperandStack(u.getOutFrame(
255:                                oldchain).getStack().maxStack(), (exc_hds[s]
256:                                .getExceptionType() == null ? Type.THROWABLE
257:                                : exc_hds[s].getExceptionType()))),
258:                                new ArrayList(), icv, ev)) {
259:                            icq.add(v, new ArrayList());
260:                        }
261:                    }
262:
263:                }// while (!icq.isEmpty()) END
264:
265:                InstructionHandle ih = start.getInstruction();
266:                do {
267:                    if ((ih.getInstruction() instanceof  ReturnInstruction)
268:                            && (!(cfg.isDead(ih)))) {
269:                        InstructionContext ic = cfg.contextOf(ih);
270:                        Frame f = ic.getOutFrame(new ArrayList()); // TODO: This is buggy, we check only the top-level return instructions this way. Maybe some maniac returns from a method when in a subroutine?
271:                        LocalVariables lvs = f.getLocals();
272:                        for (int i = 0; i < lvs.maxLocals(); i++) {
273:                            if (lvs.get(i) instanceof  UninitializedObjectType) {
274:                                this 
275:                                        .addMessage("Warning: ReturnInstruction '"
276:                                                + ic
277:                                                + "' may leave method with an uninitialized object in the local variables array '"
278:                                                + lvs + "'.");
279:                            }
280:                        }
281:                        OperandStack os = f.getStack();
282:                        for (int i = 0; i < os.size(); i++) {
283:                            if (os.peek(i) instanceof  UninitializedObjectType) {
284:                                this 
285:                                        .addMessage("Warning: ReturnInstruction '"
286:                                                + ic
287:                                                + "' may leave method with an uninitialized object on the operand stack '"
288:                                                + os + "'.");
289:                            }
290:                        }
291:                        //see JVM $4.8.2
292:                        //TODO implement all based on stack 
293:                        Type returnedType = null;
294:                        if (ih.getPrev().getInstruction() instanceof  InvokeInstruction) {
295:                            returnedType = ((InvokeInstruction) ih.getPrev()
296:                                    .getInstruction()).getType(m
297:                                    .getConstantPool());
298:                        }
299:                        if (ih.getPrev().getInstruction() instanceof  LoadInstruction) {
300:                            int index = ((LoadInstruction) ih.getPrev()
301:                                    .getInstruction()).getIndex();
302:                            returnedType = lvs.get(index);
303:                        }
304:                        if (ih.getPrev().getInstruction() instanceof  GETFIELD) {
305:                            returnedType = ((GETFIELD) ih.getPrev()
306:                                    .getInstruction()).getType(m
307:                                    .getConstantPool());
308:                        }
309:                        if (returnedType != null) {
310:                            if (returnedType instanceof  ObjectType) {
311:                                try {
312:                                    if (!((ObjectType) returnedType)
313:                                            .isAssignmentCompatibleWith(m
314:                                                    .getReturnType())) {
315:                                        throw new StructuralCodeConstraintException(
316:                                                "Returned type "
317:                                                        + returnedType
318:                                                        + " does not match Method's return type "
319:                                                        + m.getReturnType());
320:                                    }
321:                                } catch (ClassNotFoundException e) {
322:                                    //dont know what do do now, so raise RuntimeException
323:                                    throw new RuntimeException(e);
324:                                }
325:                            } else if (!returnedType.equals(m.getReturnType())) {
326:                                throw new StructuralCodeConstraintException(
327:                                        "Returned type "
328:                                                + returnedType
329:                                                + " does not match Method's return type "
330:                                                + m.getReturnType());
331:                            }
332:                        }
333:                    }
334:                } while ((ih = ih.getNext()) != null);
335:
336:            }
337:
338:            /**
339:             * Pass 3b implements the data flow analysis as described in the Java Virtual
340:             * Machine Specification, Second Edition.
341:             * Later versions will use LocalVariablesInfo objects to verify if the
342:             * verifier-inferred types and the class file's debug information (LocalVariables
343:             * attributes) match [TODO].
344:             *
345:             * @see org.apache.bcel.verifier.statics.LocalVariablesInfo
346:             * @see org.apache.bcel.verifier.statics.Pass2Verifier#getLocalVariablesInfo(int)
347:             */
348:            public VerificationResult do_verify() {
349:                /*if (! myOwner.doPass3a(method_no).equals(VerificationResult.VR_OK)){
350:                    return VerificationResult.VR_NOTYET;
351:                }
352:
353:                // Pass 3a ran before, so it's safe to assume the JavaClass object is
354:                // in the BCEL repository.
355:                JavaClass jc;
356:                try {
357:                    jc = Repository.lookupClass(myOwner.getClassName());
358:                } catch (ClassNotFoundException e) {
359:                    // FIXME: maybe not the best way to handle this
360:                    throw new AssertionViolatedException("Missing class: " + e.toString());
361:                }*/
362:
363:                ConstantPoolGen constantPoolGen = new ConstantPoolGen(jc
364:                        .getConstantPool());
365:                // Init Visitors
366:                InstConstraintVisitor icv = new InstConstraintVisitor();
367:                icv.setConstantPoolGen(constantPoolGen);
368:
369:                ExecutionVisitor ev = new ExecutionVisitor();
370:                ev.setConstantPoolGen(constantPoolGen);
371:
372:                Method[] methods = jc.getMethods(); // Method no "method_no" exists, we ran Pass3a before on it!
373:
374:                try {
375:
376:                    MethodGen mg = new MethodGen(methods[method_no], jc
377:                            .getClassName(), constantPoolGen);
378:
379:                    icv.setMethodGen(mg);
380:
381:                    ////////////// DFA BEGINS HERE ////////////////
382:                    if (!(mg.isAbstract() || mg.isNative())) { // IF mg HAS CODE (See pass 2)
383:
384:                        ControlFlowGraph cfg = new ControlFlowGraph(mg);
385:
386:                        // Build the initial frame situation for this method.
387:                        Frame f = new Frame(mg.getMaxLocals(), mg.getMaxStack());
388:                        if (!mg.isStatic()) {
389:                            if (mg.getName().equals(Constants.CONSTRUCTOR_NAME)) {
390:                                Frame._this  = new UninitializedObjectType(
391:                                        new ObjectType(jc.getClassName()));
392:                                f.getLocals().set(0, Frame._this );
393:                            } else {
394:                                Frame._this  = null;
395:                                f.getLocals().set(0,
396:                                        new ObjectType(jc.getClassName()));
397:                            }
398:                        }
399:                        Type[] argtypes = mg.getArgumentTypes();
400:                        int twoslotoffset = 0;
401:                        for (int j = 0; j < argtypes.length; j++) {
402:                            if (argtypes[j] == Type.SHORT
403:                                    || argtypes[j] == Type.BYTE
404:                                    || argtypes[j] == Type.CHAR
405:                                    || argtypes[j] == Type.BOOLEAN) {
406:                                argtypes[j] = Type.INT;
407:                            }
408:                            f.getLocals()
409:                                    .set(
410:                                            twoslotoffset + j
411:                                                    + (mg.isStatic() ? 0 : 1),
412:                                            argtypes[j]);
413:                            if (argtypes[j].getSize() == 2) {
414:                                twoslotoffset++;
415:                                f.getLocals().set(
416:                                        twoslotoffset + j
417:                                                + (mg.isStatic() ? 0 : 1),
418:                                        Type.UNKNOWN);
419:                            }
420:                        }
421:                        circulationPump(mg, cfg, cfg.contextOf(mg
422:                                .getInstructionList().getStart()), f, icv, ev);
423:                    }
424:                } catch (VerifierConstraintViolatedException ce) {
425:                    ce.extendMessage("Constraint violated in method '"
426:                            + methods[method_no] + "':\n", "");
427:                    return new VerificationResult(
428:                            VerificationResult.VERIFIED_REJECTED, ce
429:                                    .getMessage());
430:                } catch (RuntimeException re) {
431:                    // These are internal errors
432:
433:                    StringWriter sw = new StringWriter();
434:                    PrintWriter pw = new PrintWriter(sw);
435:                    re.printStackTrace(pw);
436:
437:                    throw new AssertionViolatedException(
438:                            "Some RuntimeException occured while verify()ing class '"
439:                                    + jc.getClassName()
440:                                    + "', method '"
441:                                    + methods[method_no]
442:                                    + "'. Original RuntimeException's stack trace:\n---\n"
443:                                    + sw + "---\n");
444:                }
445:                return VerificationResult.VR_OK;
446:            }
447:
448:            /** Returns the method number as supplied when instantiating. */
449:            public int getMethodNo() {
450:                return method_no;
451:            }
452:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.