Verified Software Toolchain [chapter]

Andrew W. Appel
2011 Lecture Notes in Computer Science  
The software toolchain includes static analyzers to check assertions about programs; optimizing compilers to translate programs to machine language; operating systems and libraries to supply context for programs. Our Verified Software Toolchain verifies with machine-checked proofs that the assertions claimed at the top of the toolchain really hold in the machine-language program, running in the operating-system context, on a weakly-consistent-shared-memory machine. Our verification approach is
more » ... odular, in that proofs about operating systems or concurrency libraries are oblivious of the programming language or machine language, proofs about compilers are oblivious of the program logic used to verify static analyzers, and so on. The approach is scalable, in that each component is verified in the semantic idiom most natural for that component. Finally, the verification is foundational: the trusted base for proofs of observable properties of the machine-language program includes only the operational semantics of the machine language, not the source language, the compiler, the program logic, or any other part of the toolchain-even when these proofs are carried out by source-level static analyzers. In this paper I explain some semantic techniques for building a verified toolchain. Consider a software toolchain comprising, A Static analyzer or program verifier that uses program invariants to check assertions about the behavior of the source program. A compiler that translates the source-language program to a machinelanguage (or other object-language) program. A runtime system (or operating system, or concurrency library) that serves as the runtime context for external function calls of the machinelanguage program. We want to construct a machine-checked proof, from the foundations of logic, that Any claims by the static analyzer about observations of the source-language program will also characterize the observations of the compiled program. We may want to attach several different static analyzers to the same compiler, or choose among several compilers beneath the same analyzer, or substitute one operating system for another. The construction and verification of just one component, such as a compiler or a static analyzer, may be as large as one project team or research group can reasonably accomplish. For both of these reasons, the interfaces between
doi:10.1007/978-3-642-19718-5_1 fatcat:4cxtdmcdfjbbfkhm7y376zkbu4