Using Coq to generate and reason about x86 systems code Andrew Kennedy & Nick Benton (MSR Cambridge) Jonas Jensen (ITU Copenhagen)

Slides:



Advertisements
Similar presentations
Automated Theorem Proving Lecture 1. Program verification is undecidable! Given program P and specification S, does P satisfy S?
Advertisements

CPU Structure and Function
Target Code Generation
Comparing Semantic and Syntactic Methods in Mechanized Proof Frameworks C.J. Bell, Robert Dockins, Aquinas Hobor, Andrew W. Appel, David Walker 1.
Chapter 10- Instruction set architectures
Princess Sumaya Univ. Computer Engineering Dept. Chapter 2: IT Students.
Principles of programming languages 1: Introduction (with a simple language) Isao Sasano Department of Information Science and Engineering.
1 COMS 361 Computer Organization Title: Instructions Date: 9/28/2004 Lecture Number: 10.
CEN 226: Computer Organization & Assembly Language :CSC 225 (Lec#4)
ISBN Chapter 3 Describing Syntax and Semantics.
The Design and Implementation of a Certifying Compiler [Necula, Lee] A Certifying Compiler for Java [Necula, Lee et al] David W. Hill CSCI
TK 2633 Microprocessor & Interfacing
General information Course web page: html Office hours:- Prof. Eyal.
Execution of an instruction
1 ICS 51 Introductory Computer Organization Fall 2006 updated: Oct. 2, 2006.
CSCE 121, Sec 200, 507, 508 Fall 2010 Prof. Jennifer L. Welch.
Copyright © 2006 Addison-Wesley. All rights reserved.1-1 ICS 410: Programming Languages Chapter 3 : Describing Syntax and Semantics Operational Semantics.
Introduction to Computers and Programming. Some definitions Algorithm: –A procedure for solving a problem –A sequence of discrete steps that defines such.
Register Allocation (via graph coloring)
8/14/03ALADDIN REU Symposium Implementing TALT William Lovas with Karl Crary.
Recap – Our First Computer WR System Bus 8 ALU Carry output A B S C OUT F 8 8 To registers’ input/output and clock inputs Sequence of control signal combinations.
Register Allocation (via graph coloring). Lecture Outline Memory Hierarchy Management Register Allocation –Register interference graph –Graph coloring.
Microprocessors Introduction to ia32 Architecture Jan 31st, 2002.
Chapter 2: Impact of Machine Architectures What is the Relationship Between Programs, Programming Languages, and Computers.
Informationsteknologi Friday, November 16, 2007Computer Architecture I - Class 111 Today’s class Instruction set architecture.
Describing Syntax and Semantics
Extensible Untrusted Code Verification Robert Schneck with George Necula and Bor-Yuh Evan Chang May 14, 2003 OSQ Retreat.
Input, Output, and Automation in x86 Proved Jason Gross Hosted by Andrew Kennedy Summer 2014.
An Introduction Chapter Chapter 1 Introduction2 Computer Systems  Programmable machines  Hardware + Software (program) HardwareProgram.
IT253: Computer Organization Lecture 4: Instruction Set Architecture Tonga Institute of Higher Education.
Aquinas Hobor and Cristian Gherghina (National University of Singapore) TexPoint fonts used in EMF. Read the TexPoint manual before you delete this box.:
Low Level Programming Lecturer: Duncan Smeed Low Level Program Control Structures.
CS 147 June 13, 2001 Levels of Programming Languages Svetlana Velyutina.
Chapter 4 - Implementing Standard Program Structures in 8086 Assembly Language from Microprocessors and Interfacing by Douglas Hall.
The ISA Level The Instruction Set Architecture (ISA) is positioned between the microarchtecture level and the operating system level.  Historically, this.
Unit-1 Introduction Prepared by: Prof. Harish I Rathod
1 Instruction Set Architecture (ISA) Alexander Titov 10/20/2012.
Instruction Set Architecture The portion of the machine visible to the programmer Issues: Internal storage model Addressing modes Operations Operands Encoding.
Execution of an instruction
Module : Algorithmic state machines. Machine language Machine language is built up from discrete statements or instructions. On the processing architecture,
Microprocessors The ia32 User Instruction Set Jan 31st, 2002.
Lecture 5 1 CSP tools for verification of Sec Prot Overview of the lecture The Casper interface Refinement checking and FDR Model checking Theorem proving.
Processor Structure and Function Chapter8:. CPU Structure  CPU must:  Fetch instructions –Read instruction from memory  Interpret instructions –Instruction.
Digital Computer Concept and Practice Copyright ©2012 by Jaejin Lee Control Unit.
Simple ALU How to perform this C language integer operation in the computer C=A+B; ? The arithmetic/logic unit (ALU) of a processor performs integer arithmetic.
Programming Language Concepts (CIS 635) Elsa L Gunter 4303 GITC NJIT,
1 Basic Processor Architecture. 2 Building Blocks of Processor Systems CPU.
Control units In the last lecture, we introduced the basic structure of a control unit, and translated our assembly instructions into a binary representation.
Introduction to Intel IA-32 and IA-64 Instruction Set Architectures.
The Universal Machine (UM) Implementing the UM Noah Mendelsohn Tufts University Web:
Digital Computer Concept and Practice Copyright ©2012 by Jaejin Lee Control Unit.
Recap – Our First Computer WR System Bus 8 ALU Carry output A B S C OUT F 8 8 To registers’ read/write and clock inputs Sequence of control signal combinations.
7-Nov Fall 2001: copyright ©T. Pearce, D. Hutchinson, L. Marshall Oct lecture23-24-hll-interrupts 1 High Level Language vs. Assembly.
Mostly-Automated Verification of Low-Level Programs in Computational Separation Logic Adam Chlipala Harvard University PLDI 2011.
Information Science and Engineering
System Programming and administration
Introduction to Intel IA-32 and IA-64 Instruction Set Architectures
Branch instructions We’ll implement branch instructions for the eight different conditions shown here. Bits 11-9 of the opcode field will indicate the.
MARIE: An Introduction to a Simple Computer
COMS 361 Computer Organization
Mastering Memory Modes
Introduction to Microprocessor Programming
Control units In the last lecture, we introduced the basic structure of a control unit, and translated our assembly instructions into a binary representation.
Review: The whole processor
Other Processors Having learnt MIPS, we can learn other major processors. Not going to be able to cover everything; will pick on the interesting aspects.
Target Code Generation
Computer Architecture and System Programming Laboratory
Chapter 10 Instruction Sets: Characteristics and Functions
Chapter 4 The Von Neumann Model
Presentation transcript:

Using Coq to generate and reason about x86 systems code Andrew Kennedy & Nick Benton (MSR Cambridge) Jonas Jensen (ITU Copenhagen)

 Compositional specification and verification of high- level behavioural properties of low-level systems code  Previous work of Benton et al employed idealized machine code  Simple design  Infinite memory; pointers are natural numbers  It’s time to get real(ish): hence, x86 The big picture

 Modelling x86: bits, bytes, instructions, execution  Generating x86: assembling & compiling  Reasoning about x86: logic & proofs  Discussion Overview of talk

 Clean slate: trusted base is just hardware and its model in Coq. †  No dependencies on legacy code, languages, compilers, or software architectures  Verify everything – including (at some point) loader-verifier  Do everything in Coq, making effective use of computation, notation, type classes, tactics, etc.  No dependencies on external tools  Coq as “world’s best macro assembler” Our approach † And a small boot loader

Modelling x86

 x86 has a bad reputation  On first glance at manuals, wholly justified!  By picking a subset, we avoid most of the messiness  If we can do x86, we can do anything! Modelling x86

 We want to compute correctly and efficiently inside Coq  Proper modelling of n-bit words, arithmetic with carry, sign, overflow, rotates, shifts, padding, the lot, all O(n)  Generic over word-length, so index type by n : nat  We also want to reason soundly inside Coq  Associativity, commutativity, order properties, etc Bits, bytes and words Compute here: n-tuples of bools Compute here: n-tuples of bools Reason here: 'Z_(2^n) from ssreflect library, reuse lemmas

Example: definition of addition Effective use of dependent types Definition is very algorithmic: so we can compute! Performance inside Coq? On this machine, about 2000 additions a second

Example: proofs about addition 1. Deal with n=0 case 4. Apply ssreflect “ring” lemma for 'Z_(2^n) 2. Apply injectivity of toZp to work in 'Z_(2^n): forall x y, toZp x = toZp y -> x = y 3. Rewrite using homomorphism lemmas e.g. toZp (addB p1 p2) = (toZp p1 + toZp p2)%R

Machine state

 x86 is notoriously large and baroque (instruction set manual alone is 1640 pages long)  Subset only: no legacy 16-bit mode, flat memory model (no segment nonsense), no floating point, no SIMD instructions, no protected-mode instructions, no 64-bit mode (yet) Actually: not too bad, possible to factor so that Coq datatype is “total” (no junk) X86 instructions

Addressing modes e.g. ADD EBX, EDI + [EDX*4] + 12

 Manuals don’t reveal much “structure” – such as it is – in instruction format  But it can be discerned – and utilitised for concise decoding functions Instruction format

Instruction decoding Uses monadic syntax, reader reads from memory and advances pointer Note: there may be many instruction formats for the same instruction

 Currently, a partial function from State to State.  Implemented in monadic style, using “primitive” operations of r/w register, r/w flag, r/w memory, etc.  Factored to re-use common patterns e.g. evalMemSpec, evalSrc Instruction execution Example fragment: call and return

Non-determinism & under-specification

 For sequential x86, for the subset we care about, almost completely deterministic  Flags are the main issue.  Introduce “undefined” state for flags  Instructions that depend on a flag whose value is undefined (e.g. branch-on-carry) then has unspecified behaviour  An alternative would be to set flags non- deterministically (cf RockSalt) Representing non-determinism and under-specification

Generating x86: Assembling and Compiling

 Directly represent encoding by list of bytes  Note: encoding is position-dependent  In future we might mirror decoding using a monadic style Instruction encoding

 Targets of jumps and branches are just absolute addresses in the Instr type. To write assembler code we want labels – for this we use a kind of HOAS type: Jumps and labels

 Cute use of notation in Coq: can write assembler code more-or-less using syntax of real assemblers!  But also make use of Coq definitions, and “macros” Syntax matters While macro Label Label binding

 Given an assembler program and an address to locate it, we can produce a sequence of bytes in the usual “two- pass” way: Assembling

 Statement of correctness uses overloaded “points-to” predicate, to be described later Round-trip theorem Memory between offset and endpos contains bytes Memory between offset and endpos decodes to prog

 Instead of trusting – or modelling – existing languages such as C, we plan to develop little languages inside Coq.  We have experimented with a tiny imperative language and its “compiler”, proved correct in Coq Little languages

Code demo!

Reasoning about x86: Logic and Proof

 Assertion logic: predicate on partial states, usual connectives + separating conjunction  Specification logic over this, incorporates step-indexing and framing, with corresponding later and frame connectives  Safety specification used to give rules for instructions, in CPS style, packaged as Hoare-style triples for non-jumpy instructions  Treatment of labels makes for elegant definition and rules for macros (e.g. while, if) Big picture

 Partiality denotes partial description, as usual for separation logic  Not to be confused with use of partiality for flags (undefined state) and memory (un-mapped or inaccessible) Partial states

 Assertions (= SPred) are predicates on partial states Assertion logic  We define a separation logic of assertions, with usual connectives. Example rules:  Points-to predicate for memory is overloaded for different “decoders” of memory Core definition: memory from p to q “decodes” to value x x could be a BYTE, a DWORD, a seq BYTE or even an Instr

 Machine code does not “finish” and so standard Hoare triple does not suit; also, code is mixed up with store. So we define safe k P to mean “runs without faulting for k steps from any state satisfying P.” Safety  Example: tight loop  Example: jmp

Specification logic

Connectives for spec logic  It gives us a “frame rule” for specs, and distributes over other connectives

 Given our definitions of safety and points-to for instructions, we can mimic Hoare-style triples for basic blocks: Basic blocks  We can then derive familiar rules such as framing:  This is useful when proving straight-line machine code

Rules for instructions (I) No control flow Use Hoare-like triple

Rules for instructions (II) Control flow Explicit CPS-like use of safe Two possible continuations

 We overload “points-to” on assembler programs, so (roughly) Reasoning with labels

 Our representation of scoped labels makes it easy to define macros that make use of labels internally – and derive rules for them. Macros

Putting it together: A spec for a memory allocator

Trivial implementation of allocator

 Very painful to work with assertions and specs using only primitive rules  We have built Coq tactic support for  Basic simplification of formulae (AC of *, etc.)  Pulling out existential quantifiers automatically  Greatly simplifies proving! Proof support

Proof demo!

 We can generate and prove correct tiny programs written in “Coq” assembler and a small while-language  Binary generated by Coq can be run on “raw metal” (booted off a CD!)  Next steps  Model of I/O e.g. screen/keyboard; currently our “observable” is just “faulting”  High-level model of processes  Build and verify OS components such as scheduler, allocator, loaded  Eventual aim: process isolation theorem Status