Java and the Java Virtual Machine - Extra ?· Java and the Java Virtual Machine De nition, Veri cation,…

  • Published on
    06-Aug-2018

  • View
    212

  • Download
    0

Transcript

  • Robert Stark, Joachim Schmid, Egon Borger

    Java and theJava Virtual Machine

    Definition, Verification, Validation

    May 8, 2001

    Springer-Verlag

    Berlin Heidelberg NewYorkLondon Paris TokyoHong Kong BarcelonaBudapest

  • Preface

    The origin of this book goes back to the Dagstuhl seminar on Logic for SystemEngineering, organized during the first week of March 1997 by S. Jahnichen,J. Loeckx, and M. Wirsing. During that seminar, after Egon Borgers talkon How to Use Abstract State Machines in Software Engineering, WolframSchulte, at the time a research assistant at the University of Ulm, Germany,questioned whether ASMs provide anything special as a scientifically well-founded and rigorous yet simple and industrially viable framework for high-level design and analysis of complex systems, and for natural refinements ofmodels to executable code. Wolfram Schulte argued, referring to his workwith K. Achatz on A Formal Object-Oriented Method Inspired by Fusionand Object-Z [1], that with current techniques of functional programmingand of axiomatic specification, one can achieve the same result. An intensiveand long debate arose from this discussion. At the end of the week, it ledEgon Borger to propose a collaboration on a real-life specification project ofWolfram Schultes choice, as a comparative field test of purely functional-declarative methods and of their enhancement within an integrated abstractstate-based operational (ASM) approach.

    After some hesitation, in May 1997 Wolfram Schulte accepted the offerand chose as the theme a high-level specification of Java and of the JavaVirtual Machine. What followed were two years of hard but enjoyable jointwork, resulting in a series of ASM models of the Java language, of the JVM,and of a provably correct compilation scheme for compiling Java programs toJVM code, which were published in [9, 8, 10, 11, 12]. When in the spring of1999, Wolfram Schulte put this work together for his Habilitationsschrift atthe University of Ulm, Egon Borger suggested completing and extending it toabadly neededfull-blown ASM case study book. The book should showthe ASM method at work, convincingly, for the practical design of a complexreal-life system, and for its rigorous mathematical and extensive experimentalanalysis.

    Robert Stark and Joachim Schmid accepted to join this book project.At that time, in his Fribourg lectures [33], Robert Stark had already elabo-rated part of the Java-to-JVM compilation correctness claim, namely, thatthe execution, on the ASM for the JVM, of every correctly compiled legalJava program is equivalent to the execution of the original Java program

  • VI Preface

    on the ASM for Java. In the spring of 1998, Egon Borger had proposed toJoachim Schmid a PhD thesis, hosted by Siemens Corporate Technology inMunich, on defining and implementing practically useful structuring and de-composition principles for large ASMs. It could be expected that for thiswork Wolfram Schultes suggestion to make our abstract Java/JVM mod-els executable would provide a rich test bed for validating the submachineconcepts we were looking for (see [7]). The realization of these ideas ledto a complete revision (completion, correction, and restructuring) of all theJava/JVM models and to their refinement by AsmGofer executable versions.The revision was triggered, not surprisingly, by three sources, namely:

    The needs of the proofs, in particular for the correctness and completenessof the verification of the bytecode resulting from the compilation, proofswhich have been worked out for this book by Robert Stark

    The needs of naturally detailing the abstractions to make them executablein AsmGofer, developed by Joachim Schmid building upon an extensionof the functional programming environment Gofer by graphical user inter-faces [36]

    An enhancement of the stepwise refined definition of the Java/JVM models,driven by the goal to create a compositional structure of submachines whichsupports incremental modularized proofs and component-wise validation(model-based testing)

    All this took much more time and energy, and made us aware of moreproblems with bytecode verification than we had expected in the spring of1999, and in retrospect we see that it was at the very beginning of this longjourney when we lost Wolfram Schulte as the fourth author. We regret this,it was painful for the four of us to eventually recognize and accept it. We hadto understand that since the moment when, just after having submitted hisHabilitationsschrift to the University of Ulm, Wolfram joined the Foundationsof Software Engineering group at Microsoft Research in Redmond, all hisenergy has been absorbed by Yuri Gurevichs challenging project to makeASMs relevant for software development at Microsoft.

    Egon Borger, Joachim Schmid, Robert StarkPisa, Munchen, Zurich, March 2001

  • Contents

    1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.1 The goals of the book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.2 The contents of the book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.3 Decomposing Java and the JVM . . . . . . . . . . . . . . . . . . . . . . . . . 71.4 Sources and literature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

    2. Abstract State Machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.1 ASMs in a nutshell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.2 Mathematical definition of ASMs . . . . . . . . . . . . . . . . . . . . . . . . . 182.3 Notational conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

    Part I. Java

    3. The imperative core JavaI of Java . . . . . . . . . . . . . . . . . . . . . . . . 333.1 Static semantics of JavaI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333.2 Transition rules for JavaI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

    4. The procedural extension JavaC of JavaI . . . . . . . . . . . . . . . . . 474.1 Static semantics of JavaC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474.2 Transition rules for JavaC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

    5. The object-oriented extension JavaO of JavaC . . . . . . . . . . . . . 715.1 Static semantics of JavaO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 715.2 Transition rules for JavaO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

    6. The exception-handling extension JavaE of JavaO . . . . . . . . . 876.1 Static semantics of JavaE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 876.2 Transition rules for JavaE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

    7. The concurrent extension JavaT of JavaE . . . . . . . . . . . . . . . . . 957.1 Static semantics of JavaT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 967.2 Transition rules for JavaT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 987.3 Thread invariants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

  • VIII Contents

    8. Java is type safe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1118.1 Structural properties of Java runs . . . . . . . . . . . . . . . . . . . . . . . . 1118.2 Unreachable statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1178.3 Rules of definite assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1218.4 Java is type safe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126

    Part II. Compilation of Java: The Trustful JVM

    9. The JVMI submachine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1399.1 Dynamic semantics of the JVMI . . . . . . . . . . . . . . . . . . . . . . . . . 1399.2 Compilation of JavaI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142

    10. The procedural extension JVMC of JVMI . . . . . . . . . . . . . . . . 14710.1 Dynamic semantics of the JVMC . . . . . . . . . . . . . . . . . . . . . . . . . 14710.2 Compilation of JavaC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153

    11. The object-oriented extension JVMO of JVMC . . . . . . . . . . . 15511.1 Dynamic semantics of the JVMO . . . . . . . . . . . . . . . . . . . . . . . . . 15511.2 Compilation of JavaO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

    12. The exception-handling extension JVME of JVMO . . . . . . . 15912.1 Dynamic semantics of the JVME . . . . . . . . . . . . . . . . . . . . . . . . . 15912.2 Compilation of JavaE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163

    13. Executing the JVMN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165

    14. Correctness of the compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16714.1 The correctness statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16714.2 The correctness proof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178

    Part III. Bytecode Verification: The Secure JVM

    15. The defensive virtual machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20915.1 Construction of the defensive JVM . . . . . . . . . . . . . . . . . . . . . . . 21015.2 Checking JVMI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21015.3 Checking JVMC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21315.4 Checking JVMO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21415.5 Checking JVME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21915.6 Checking JVMN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22115.7 Checks are monotonic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222

  • Contents IX

    16. Bytecode type assignments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22316.1 Problems of bytecode verification . . . . . . . . . . . . . . . . . . . . . . . . . 22416.2 Successors of bytecode instructions . . . . . . . . . . . . . . . . . . . . . . . 23116.3 Type assignments without subroutine call stacks . . . . . . . . . . . 23616.4 Soundness of bytecode type assignments . . . . . . . . . . . . . . . . . . . 24216.5 Certifying compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252

    17. The diligent virtual machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27317.1 Principal bytecode type assignments . . . . . . . . . . . . . . . . . . . . . . 27317.2 Verifying JVMI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27517.3 Verifying JVMC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27917.4 Verifying JVMO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28317.5 Verifying JVME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28317.6 Verifying JVMN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286

    18. The dynamic virtual machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28918.1 Initiating and defining loaders . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28918.2 Loading classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29018.3 Dynamic semantics of the JVMD . . . . . . . . . . . . . . . . . . . . . . . . . 291

    Appendix

    A. Executable Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305A.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305A.2 Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306A.3 Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312A.4 Java Virtual Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314

    B. Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323B.1 Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323B.2 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331

    C. JVM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335C.1 Trustful execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335C.2 Defensive execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343C.3 Diligent execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344C.4 Check functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347C.5 Successor functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348C.6 Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349C.7 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351C.8 Abstract versus real instructions . . . . . . . . . . . . . . . . . . . . . . . . . . 355

  • X Contents

    D. Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361D.1 Compilation functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361D.2 maxOpd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363D.3 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364

    References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365

    List of Figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367

    List of Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371

    Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373

  • 1. Introduction

    This book provides a structured and high-level description, together with amathematical and an experimental analysis, of Java and of the Java VirtualMachine (JVM), including the standard compilation of Java programs toJVM code and the security critical bytecode verifier component of the JVM.The description is structured into modules (language layers and machinecomponents), and its abstract character implies that it is truly platform-independent. It comes with a natural refinement to executable machines onwhich code can be tested, exploiting in particular the potential of model-based high-level testi...