├── .gitignore ├── MIPSmodel ├── BiGrammar.v ├── Decode.v ├── Grammar.v ├── GrammarType.v ├── Int32.v ├── MIPSBG.v ├── MIPSSemantics.v ├── MIPSSyntax.v ├── Makefile ├── Parser.v ├── ParserArg.v ├── README.txt ├── RESet.v ├── Regexp.v ├── Xform.v └── extracted │ ├── Makefile │ ├── extractor.v │ └── tests │ ├── Makefile │ ├── Mars_4_1.jar │ ├── iPrinter.ml │ ├── test.asm │ ├── test.ml │ └── test.txt ├── README ├── shared ├── Bits.v ├── CommonTacs.v ├── Coqlib.v ├── FloatingAux.v ├── MSetsMore.v ├── Makefile ├── Maps.v ├── Monad.v ├── RTL.v └── Vector.v └── x86model ├── Makefile ├── Model ├── BiGrammar.v ├── CheckDeterministic.v ├── Decode.v ├── Encode.v ├── Grammar.v ├── GrammarType.v ├── Makefile ├── NewParser.v ├── Parser.v ├── ParserArg.v ├── ParserTest.v ├── RESet.v ├── Recognizer.v ├── Regexp.v ├── SemTests.v ├── X86BG.v ├── X86BG_ins.v ├── X86Semantics.v ├── X86Syntax.v ├── Xform.v └── decenc_tests │ ├── cat │ ├── extract.v │ ├── ls │ ├── pwd │ └── tailf ├── RockSalt ├── DFACorrectness.v ├── FastVerifier.v ├── Int32.v ├── Makefile ├── NACLjmp.v ├── VerifierCorrectness.v ├── VerifierDFA.v ├── X86Lemmas.v └── lia.cache ├── cdriver ├── Tables.v ├── dfa_export.ml ├── driver.h ├── mktables ├── naclsmith ├── ncval.c ├── tables.h └── test │ ├── aes.c │ ├── almabench.c │ ├── binarytrees.c │ ├── bisect.c │ ├── chomp.c │ ├── dummy.s │ ├── dummylm.s │ ├── fannkuch.c │ ├── fft.c │ ├── fib.c │ ├── integr.c │ ├── knucleotide.c │ ├── lists.c │ ├── mandelbrot.c │ ├── nbody.c │ ├── nsieve.c │ ├── nsievebits.c │ ├── perlin.c │ ├── qsort.c │ ├── script │ ├── sha1.c │ ├── spectral.c │ └── vmach.c ├── fuzz ├── Decode.ml ├── Fuzz.v ├── Makefile ├── Parser.ml_fastarray ├── README ├── big.ml ├── cZeven.ml ├── filter.c ├── fuzzer.sh ├── fuzzer64.sh ├── fuzzgen.ml ├── instr_fuzz │ ├── Makefile │ ├── PrettyPrinter.ml │ ├── README │ ├── abbrev.ml │ ├── enc_dec.ml │ ├── extract │ │ ├── Makefile │ │ ├── extract.v │ │ └── patch │ │ │ ├── Parser.ml │ │ │ ├── big.ml │ │ │ └── extrOcamlBigIntConv.ml │ ├── syntaxfuzzer.ml │ └── test.ml ├── run.sh └── test.c ├── gdb_smtrace ├── .gdbinit ├── Makefile ├── README ├── gdb.txt ├── gdb_init ├── instrs.txt ├── main ├── main.c ├── main.s └── tmp.txt └── semantics_trace ├── Makefile ├── README ├── elf.ml ├── examples ├── factorial │ ├── factorial.c │ ├── mem.txt │ └── regs.txt └── fib │ ├── fib.c │ ├── mem.txt │ └── regs.txt ├── john ├── run.sh ├── simulator ├── Makefile ├── Parser.ml_fastarray ├── big.ml ├── cZeven.ml ├── extrOcamlBigIntConv.ml ├── extract.v ├── test.ml ├── test2.ml └── testSFI.ml └── tracer ├── Makefile ├── gntrace.cpp ├── memlist.cpp └── tracer.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.v.d 2 | *.vo 3 | *.glob 4 | *.aux 5 | Makefile.coq 6 | *~ -------------------------------------------------------------------------------- /MIPSmodel/GrammarType.v: -------------------------------------------------------------------------------- 1 | Require Import ParserArg. 2 | 3 | (* Grammar should be parametrized by a PARSER_ARG module; however, that 4 | would impede code extraction because of a Coq bug. Instead, we 5 | introduce a bunch of definitions below to achieve some separation as 6 | long as we never directly use definitions in X86_PARSER_ARG *) 7 | Definition char_p := MIPS_PARSER_ARG.char_p. 8 | Definition char_dec := MIPS_PARSER_ARG.char_dec. 9 | Definition user_type := MIPS_PARSER_ARG.user_type. 10 | Definition user_type_dec := MIPS_PARSER_ARG.user_type_dec. 11 | Definition user_type_denote := MIPS_PARSER_ARG.user_type_denote. 12 | Definition token_id := MIPS_PARSER_ARG.token_id. 13 | Definition num_tokens := MIPS_PARSER_ARG.num_tokens. 14 | Definition token_id_to_chars := MIPS_PARSER_ARG.token_id_to_chars. 15 | 16 | (** The [type]s for our grammars. *) 17 | Inductive type : Type := 18 | | Unit_t : type 19 | | Char_t : type 20 | | Void_t : type 21 | | Pair_t : type -> type -> type 22 | | Sum_t : type -> type -> type 23 | | List_t : type -> type 24 | | Option_t : type -> type 25 | | User_t : user_type -> type. 26 | 27 | (** [void] is an empty type. *) 28 | Inductive void : Type := . 29 | 30 | (** The interpretation of [type]s as Coq [Type]s. *) 31 | Fixpoint interp (t:type) : Type := 32 | match t with 33 | | Unit_t => unit 34 | | Char_t => char_p 35 | | Void_t => void 36 | | Pair_t t1 t2 => (interp t1) * (interp t2) 37 | | Sum_t t1 t2 => (interp t1) + (interp t2) 38 | | List_t t => list (interp t) 39 | | Option_t t => option (interp t) 40 | | User_t t => user_type_denote t 41 | end%type. 42 | -------------------------------------------------------------------------------- /MIPSmodel/MIPSSyntax.v: -------------------------------------------------------------------------------- 1 | (* Copyright (c) 2011. Greg Morrisett, Gang Tan, Joseph Tassarotti, 2 | Jean-Baptiste Tristan, and Edward Gan. 3 | 4 | This file is part of RockSalt. 5 | 6 | This file is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License as 8 | published by the Free Software Foundation; either version 2 of 9 | the License, or (at your option) any later version. 10 | *) 11 | 12 | 13 | (* This file provides abstract syntax definitions for the MIPS32 14 | * instruction set architecture. *) 15 | Require Import List. 16 | Require Import ZArith. 17 | Set Implicit Arguments. 18 | Local Open Scope Z_scope. 19 | 20 | Require Import Shared.Bits. 21 | 22 | (********************************************) 23 | (* Type definitions for MIPS abstract syntax *) 24 | (********************************************) 25 | Definition zero_extend8_32(w:int8) : int32 := Word.repr (Word.unsigned w). 26 | Definition sign_extend8_32(w:int8) : int32 := Word.repr (Word.signed w). 27 | Definition zero_extend16_32(w:int16) : int32 := Word.repr (Word.unsigned w). 28 | Definition sign_extend16_32(w:int16) : int32 := Word.repr (Word.signed w). 29 | 30 | Inductive register : Set := 31 | | Reg : int5 -> register. 32 | 33 | Definition register_eq_dec : forall (x y:register), {x=y} + {x<>y}. 34 | intros. 35 | decide equality. 36 | apply Word.eq_dec. 37 | Defined. 38 | 39 | Inductive ioperand : Set := 40 | | Iop : register -> register -> int16 -> ioperand 41 | . 42 | Inductive joperand : Set := 43 | | Jop : int26 -> joperand 44 | . 45 | 46 | (* two-register operands *) 47 | Inductive reg2_operand : Set := 48 | | Reg2_op: register -> register -> reg2_operand. 49 | 50 | (* three-register operands *) 51 | Inductive reg3_operand : Set := 52 | | Reg3_op: register -> register -> register -> reg3_operand. 53 | 54 | 55 | (* operands with two registers and a shift amount *) 56 | Inductive reg2sh_operand : Set := 57 | | Reg2sh_op: register -> register -> int5 -> reg2sh_operand. 58 | 59 | (* Operands for bgez, bgezal, ...; they compare a register with zero 60 | and conditionally make a pc-relative jump based on an offset 61 | operand *) 62 | Inductive bz_operand : Set := 63 | | BZ_op : register -> int16 -> bz_operand. 64 | 65 | Inductive instr : Set := 66 | | ADD : reg3_operand -> instr 67 | | ADDI : ioperand -> instr 68 | | ADDIU : ioperand -> instr 69 | | ADDU : reg3_operand -> instr 70 | | AND : reg3_operand -> instr 71 | | ANDI : ioperand -> instr 72 | | BEQ : ioperand -> instr 73 | | BGEZ : bz_operand -> instr 74 | | BGEZAL : bz_operand -> instr 75 | | BGTZ : bz_operand -> instr 76 | | BLEZ : bz_operand -> instr 77 | | BLTZ : bz_operand -> instr 78 | | BLTZAL : bz_operand -> instr 79 | | BNE : ioperand -> instr 80 | | DIV : reg2_operand -> instr 81 | | DIVU : reg2_operand -> instr 82 | | J : joperand -> instr 83 | | JAL : joperand -> instr 84 | | JALR : reg2sh_operand -> instr 85 | | JR : register -> instr 86 | | LB : ioperand -> instr 87 | | LBU : ioperand -> instr 88 | | LH : ioperand -> instr 89 | | LHU : ioperand -> instr 90 | | LUI : ioperand -> instr 91 | | LW : ioperand -> instr 92 | | MFHI : register -> instr 93 | | MFLO : register -> instr 94 | | MUL : reg3_operand -> instr 95 | | MULT : reg2_operand -> instr 96 | | MULTU : reg2_operand -> instr 97 | | NOR : reg3_operand -> instr 98 | | OR : reg3_operand -> instr 99 | | ORI : ioperand -> instr 100 | | SB : ioperand -> instr 101 | | SEB : reg2_operand -> instr 102 | | SEH : reg2_operand -> instr 103 | | SH : ioperand -> instr 104 | | SLL : reg2sh_operand -> instr 105 | | SLLV : reg3_operand -> instr 106 | | SLT : reg3_operand -> instr 107 | | SLTI : ioperand -> instr 108 | | SLTIU : ioperand -> instr 109 | | SLTU : reg3_operand -> instr 110 | | SRA : reg2sh_operand -> instr 111 | | SRAV : reg3_operand -> instr 112 | | SRL : reg2sh_operand -> instr 113 | | SRLV : reg3_operand -> instr 114 | | SUB : reg3_operand -> instr 115 | | SUBU : reg3_operand -> instr 116 | | SW : ioperand -> instr 117 | | XOR : reg3_operand -> instr 118 | | XORI : ioperand -> instr. 119 | -------------------------------------------------------------------------------- /MIPSmodel/Makefile: -------------------------------------------------------------------------------- 1 | MODULES := MIPSSyntax ParserArg Xform Regexp RESet GrammarType Grammar BiGrammar Parser MIPSBG MIPSSemantics Decode 2 | VS := $(MODULES:%=%.v) 3 | 4 | .PHONY: coq clean 5 | 6 | coq: Makefile.coq 7 | $(MAKE) -C ../shared 8 | $(MAKE) -f Makefile.coq 9 | 10 | Makefile.coq: Makefile $(VS:%=%) 11 | echo $(VS) 12 | coq_makefile -R . MIPSModel -R ../shared Shared $(VS) -o Makefile.coq 13 | 14 | clean:: Makefile.coq 15 | $(MAKE) -f Makefile.coq clean 16 | rm -f Makefile.coq .depend 17 | -------------------------------------------------------------------------------- /MIPSmodel/ParserArg.v: -------------------------------------------------------------------------------- 1 | Require Export Coq.Bool.Bool. 2 | Require Export Coq.ZArith.ZArith. 3 | Require Export Coq.Lists.List. 4 | 5 | Require Import Coq.Strings.String. 6 | Require Import Coq.Structures.OrdersAlt. 7 | 8 | Module Type PARSER_ARG. 9 | (* the type of characters used in the grammar specifications *) 10 | Parameter char_p : Set. 11 | (* equality on characters -- should change this to a boolean function, 12 | paired with a proof that it's an equality so that 13 | we get faster symbolic computation. *) 14 | Parameter char_dec : forall (c1 c2:char_p), {c1=c2} + {c1<>c2}. 15 | 16 | (* compare two chars *) 17 | Parameter char_cmp : char_p -> char_p -> comparison. 18 | Parameter char_eq_leibniz : 19 | forall c1 c2, char_cmp c1 c2 = Eq -> c1 = c2. 20 | 21 | (* a name for user types embedded within our AST grammar types. *) 22 | Parameter user_type : Set. 23 | (* equality on user type names. *) 24 | Parameter user_type_dec : forall (t1 t2:user_type), {t1=t2} + {t1<>t2}. 25 | (* a semantic interpretation function for user type names. *) 26 | Parameter user_type_denote : user_type -> Set. 27 | 28 | (* when we parse, instead of working in terms of individual characters, 29 | we work in terms of tokens. For instance, the x86 grammar is specified 30 | with characters as bits, and tokens as bytes (8-bits). *) 31 | Definition token_id := nat. 32 | (* this is the total number of tokens that we can have -- e.g., for the 33 | x86 parser it is 256 because they have 8 bits. *) 34 | Variable num_tokens : nat. 35 | (* this converts tokens to a list of characters -- it's used only during 36 | the table construction for the parser. *) 37 | Variable token_id_to_chars : token_id -> list char_p. 38 | 39 | (* converts a char to a string *) 40 | Parameter show_char: char_p -> string. 41 | 42 | End PARSER_ARG. 43 | 44 | (* a module for generating the parser for MIPS instructions *) 45 | Module MIPS_PARSER_ARG. 46 | Require Import MIPSModel.MIPSSyntax. 47 | Require Import Shared.Bits. 48 | Local Open Scope Z_scope. 49 | 50 | Definition char_p : Set := bool. 51 | 52 | Definition char_dec : forall (c1 c2:char_p), {c1=c2}+{c1<>c2} := bool_dec. 53 | 54 | Definition char_cmp (c1 c2:char_p) : comparison := 55 | match c1, c2 with 56 | | false, true => Lt 57 | | true, false => Gt 58 | | _, _ => Eq 59 | end. 60 | 61 | Lemma char_eq_leibniz : 62 | forall c1 c2, char_cmp c1 c2 = Eq -> c1 = c2. 63 | Proof. 64 | destruct c1 ; destruct c2 ; intros ; auto ; discriminate. 65 | Qed. 66 | 67 | Inductive tipe : Set := 68 | | Int_t 69 | | Register_t 70 | | BitVector_t : nat -> tipe (* a bit vector of a certain width *) 71 | | Ioperand_t 72 | | Joperand_t 73 | | Reg2_operand_t 74 | | Reg3_operand_t 75 | | Reg2sh_operand_t 76 | | BZ_operand_t 77 | | Instruction_t 78 | | UPair_t: tipe -> tipe -> tipe. 79 | 80 | Definition tipe_eq : forall (t1 t2:tipe), {t1=t2} + {t1<>t2}. 81 | intros ; decide equality. 82 | apply eq_nat_dec. 83 | Defined. 84 | 85 | Definition Shamt5_t := BitVector_t size5. 86 | Definition Imm16_t := BitVector_t size16. 87 | Definition Target26_t := BitVector_t size26. 88 | 89 | Fixpoint tipe_m (t:tipe) := 90 | match t with 91 | | Int_t => Z 92 | | Register_t => register 93 | | BitVector_t n => Word.int n 94 | | Ioperand_t => ioperand 95 | | Joperand_t => joperand 96 | | Reg2_operand_t => reg2_operand 97 | | Reg3_operand_t => reg3_operand 98 | | Reg2sh_operand_t => reg2sh_operand 99 | | BZ_operand_t => bz_operand 100 | | Instruction_t => instr 101 | | UPair_t t1 t2 => (tipe_m t1 * (tipe_m t2))%type 102 | end. 103 | 104 | Definition user_type := tipe. 105 | Definition user_type_dec : forall (t1 t2:user_type), {t1=t2} + {t1<>t2} := 106 | tipe_eq. 107 | Definition user_type_denote := tipe_m. 108 | 109 | Definition byte_explode (b:int8) : list bool := 110 | let bs := Word.bits_of_Z 8 (Word.unsigned b) in 111 | (bs 7)::(bs 6)::(bs 5)::(bs 4)::(bs 3)::(bs 2)::(bs 1)::(bs 0)::nil. 112 | 113 | Definition nat_explode (n:nat) : list bool := 114 | byte_explode (Word.repr (Z_of_nat n)). 115 | 116 | Definition token_id := nat. 117 | Definition num_tokens : token_id := 256%nat. 118 | Definition token_id_to_chars : token_id -> list char_p := nat_explode. 119 | 120 | Open Scope string_scope. 121 | Definition show_char (c:char_p) : string := 122 | match c with 123 | | true => "1" 124 | | false => "0" 125 | end. 126 | 127 | End MIPS_PARSER_ARG. 128 | 129 | Require Import Coq.Structures.OrdersAlt. 130 | Module CharOrderedTypeAlt <: OrderedTypeAlt. 131 | Definition t : Type := MIPS_PARSER_ARG.char_p. 132 | Definition compare : t -> t -> comparison := MIPS_PARSER_ARG.char_cmp. 133 | 134 | Lemma compare_sym : forall (c1 c2 : t), compare c2 c1 = CompOpp (compare c1 c2). 135 | Proof. 136 | destruct c1 ; destruct c2 ; auto. 137 | Qed. 138 | 139 | Lemma compare_trans : 140 | forall cmp c1 c2 c3, compare c1 c2 = cmp -> compare c2 c3 = cmp -> compare c1 c3 = cmp. 141 | Proof. 142 | destruct c1 ; destruct c2 ; destruct c3 ; simpl ; intros ; subst ; auto ; discriminate. 143 | Qed. 144 | End CharOrderedTypeAlt. 145 | 146 | Module CharOrderedType := OT_from_Alt CharOrderedTypeAlt. 147 | 148 | 149 | 150 | (******************************************************************************) 151 | (* I would like to put this in a module but alas, the Extraction Implicit *) 152 | (* stuff breaks then. So I've had to break this out to top-level. *) 153 | (******************************************************************************) 154 | (* Module X86_BASE_PARSER(NewParser(PA : NEW_PARSER_ARG). *) 155 | -------------------------------------------------------------------------------- /MIPSmodel/README.txt: -------------------------------------------------------------------------------- 1 | MIPS Model: 2 | 3 | A model of ~50 instructions for a modern 32bit MIPS machine, with no coprocessor or floating point support. 4 | However, this model does take branch delays into account. 5 | 6 | Most of this was taken directly from the x86model directory. 7 | Changes were made in Decode.v, X86/MIPSSemantics.v, and X86/MIPSSyntax.v 8 | to adapt it to the MIPS processor. 9 | 10 | The extracted/ directory contains a MIPS testing framework, which currently 11 | allows for assembly code to be assembled and run on a blank machine, 12 | Harvard Architecture style, so the code is not actually in main memory. 13 | The test output can be compared against what MARS or SPIM would do. 14 | 15 | To do a test do the following: 16 | run "make" in the MIPSModel/ directory to compile the coq 17 | run "make extract" in the MIPSModel/extracted/ directory to extract ml 18 | run "make compile" in the MIPSModel/extracted/ directory to compile ml 19 | run "make" in MIPSModel/extracted/tests directory to assemble MARS MIPS asm code in "test.asm" into hex values 20 | run "make run" in MIPSModel/extracted to run the test 21 | -------------------------------------------------------------------------------- /MIPSmodel/extracted/Makefile: -------------------------------------------------------------------------------- 1 | extract: 2 | coqc extractor.v -I "../" 3 | compile: 4 | ocamlbuild tests/test.native -libs nums -I "libs" 5 | run: 6 | ./test.native < tests/test.txt 7 | clean: 8 | rm *.ml *.mli 9 | rm *.vo *.glob 10 | ocamlbuild -clean 11 | -------------------------------------------------------------------------------- /MIPSmodel/extracted/extractor.v: -------------------------------------------------------------------------------- 1 | Require Import Decode. 2 | Require Import MIPSSemantics. 3 | Extraction Blacklist String List. 4 | Recursive Extraction Library Decode. 5 | Recursive Extraction Library MIPSSemantics. 6 | -------------------------------------------------------------------------------- /MIPSmodel/extracted/tests/Makefile: -------------------------------------------------------------------------------- 1 | asm: 2 | java -jar MARS_4_1.jar a db dump .text HexText test.txt test.asm 3 | -------------------------------------------------------------------------------- /MIPSmodel/extracted/tests/Mars_4_1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gangtan/CPUmodels/a6decc3085e1f8d8d4875e67f9ad9c7663910f8a/MIPSmodel/extracted/tests/Mars_4_1.jar -------------------------------------------------------------------------------- /MIPSmodel/extracted/tests/iPrinter.ml: -------------------------------------------------------------------------------- 1 | open Unix 2 | open Peano 3 | open Char 4 | open BinInt 5 | open BinPos 6 | open Coqlib 7 | open Specif 8 | open Zdiv 9 | open Zpower 10 | open Big_int 11 | open Bits 12 | open Datatypes 13 | open Parser 14 | open Decode 15 | open Monad 16 | open Maps 17 | open ZArith_dec 18 | open String 19 | open List0 20 | open Zdiv 21 | open MIPSSyntax 22 | open MIPSSemantics 23 | open MIPS_RTL 24 | open MIPS_MACHINE 25 | open MIPS_PARSER 26 | 27 | let bii = big_int_of_int 28 | ;; 29 | let reg_to_str (r:register) = "R"^string_of_big_int r 30 | ;; 31 | 32 | let rop_to_str (r:roperand) = 33 | match r with 34 | | Rop (r1,r2,r3,i) -> "("^(reg_to_str r1)^","^(reg_to_str r2)^","^ 35 | (reg_to_str r3)^","^(string_of_big_int i)^")" 36 | ;; 37 | 38 | let iop_to_str (i:ioperand) = 39 | match i with 40 | | Iop (r1,r2,i) -> "("^(reg_to_str r1)^","^(reg_to_str r2)^","^ 41 | (string_of_big_int i)^")" 42 | ;; 43 | 44 | let jop_to_str (j:joperand) = "("^(string_of_big_int j)^")" 45 | ;; 46 | 47 | let instr_to_str (i:instr) = 48 | match i with 49 | | ADD roperand -> "ADD"^(rop_to_str roperand) 50 | | ADDI ioperand -> "ADDI"^(iop_to_str ioperand) 51 | | ADDIU ioperand -> "ADDIU"^(iop_to_str ioperand) 52 | | ADDU roperand -> "ADDU"^(rop_to_str roperand) 53 | | AND roperand -> "AND"^(rop_to_str roperand) 54 | | ANDI ioperand -> "ANDI"^(iop_to_str ioperand) 55 | | BEQ ioperand -> "BEQ"^(iop_to_str ioperand) 56 | | BGEZ ioperand -> "BGEZ"^(iop_to_str ioperand) 57 | | BGEZAL ioperand -> "BGEZAL"^(iop_to_str ioperand) 58 | | BGTZ ioperand -> "BGTZ"^(iop_to_str ioperand) 59 | | BLEZ ioperand -> "BLEZ"^(iop_to_str ioperand) 60 | | BLTZ ioperand -> "BLTZ"^(iop_to_str ioperand) 61 | | BLTZAL ioperand -> "BLTZAL"^(iop_to_str ioperand) 62 | | BNE ioperand -> "BNE"^(iop_to_str ioperand) 63 | | DIV roperand -> "DIV"^(rop_to_str roperand) 64 | | DIVU roperand -> "DIVU"^(rop_to_str roperand) 65 | | J joperand -> "J"^(jop_to_str joperand) 66 | | JAL joperand -> "JAL"^(jop_to_str joperand) 67 | | JALR roperand -> "JALR"^(rop_to_str roperand) 68 | | JR roperand -> "JR"^(rop_to_str roperand) 69 | | LB ioperand -> "LB"^(iop_to_str ioperand) 70 | | LBU ioperand -> "LBU"^(iop_to_str ioperand) 71 | | LH ioperand -> "LH"^(iop_to_str ioperand) 72 | | LHU ioperand -> "LHU"^(iop_to_str ioperand) 73 | | LUI ioperand -> "LUI"^(iop_to_str ioperand) 74 | | LW ioperand -> "LW"^(iop_to_str ioperand) 75 | | MFHI roperand -> "MFHI"^(rop_to_str roperand) 76 | | MFLO roperand -> "MFLO"^(rop_to_str roperand) 77 | | MUL roperand -> "MUL"^(rop_to_str roperand) 78 | | MULT roperand -> "MULT"^(rop_to_str roperand) 79 | | MULTU roperand -> "MULTU"^(rop_to_str roperand) 80 | | NOR roperand -> "NOR"^(rop_to_str roperand) 81 | | OR roperand -> "OR"^(rop_to_str roperand) 82 | | ORI ioperand -> "ORI"^(iop_to_str ioperand) 83 | | SB ioperand -> "SB"^(iop_to_str ioperand) 84 | | SEB roperand -> "SEB"^(rop_to_str roperand) 85 | | SEH roperand -> "SEH"^(rop_to_str roperand) 86 | | SH ioperand -> "SH"^(iop_to_str ioperand) 87 | | SLL roperand -> "SLL"^(rop_to_str roperand) 88 | | SLLV roperand -> "SLLV"^(rop_to_str roperand) 89 | | SLT roperand -> "SLT"^(rop_to_str roperand) 90 | | SLTI ioperand -> "SLTI"^(iop_to_str ioperand) 91 | | SLTIU ioperand -> "SLTIU"^(iop_to_str ioperand) 92 | | SLTU roperand -> "SLTU"^(rop_to_str roperand) 93 | | SRA roperand -> "SRA"^(rop_to_str roperand) 94 | | SRAV roperand -> "SRAV"^(rop_to_str roperand) 95 | | SRL roperand -> "SRL"^(rop_to_str roperand) 96 | | SRLV roperand -> "SRLV"^(rop_to_str roperand) 97 | | SUB roperand -> "SUB"^(rop_to_str roperand) 98 | | SUBU roperand -> "SUBU"^(rop_to_str roperand) 99 | | SW ioperand -> "SW"^(iop_to_str ioperand) 100 | | XOR roperand -> "XOR"^ (rop_to_str roperand) 101 | | XORI ioperand -> "XORI"^ (iop_to_str ioperand) 102 | 103 | let rec rmap_to_stri rm (i:int) = 104 | if(i>31) then "" else( 105 | "R"^(string_of_int i)^":"^(string_of_big_int(rm (bii i)))^ 106 | (if (i mod 10 = 0) then "\n" else ", ")^ 107 | (rmap_to_stri rm (i + 1))) 108 | ;; 109 | let rmap_to_str (rm: (register,int32) fmap) = 110 | rmap_to_stri rm 1;; 111 | 112 | let mach_to_str (m:mach) = 113 | "PC: "^(string_of_big_int (pc_reg m))^"\n"^ 114 | "REGS:\n"^(rmap_to_str (gp_regs m))^"\n"^ 115 | "HIREG: "^(string_of_big_int (hi_reg m))^", "^ 116 | "LOREG: "^(string_of_big_int (lo_reg m))^", "^ 117 | "BDF: "^(string_of_big_int (bdelay_active_f m))^", "^ 118 | "BDPC: "^(string_of_big_int (bdelay_pc_reg m))^"\n" 119 | 120 | -------------------------------------------------------------------------------- /MIPSmodel/extracted/tests/test.asm: -------------------------------------------------------------------------------- 1 | ori $s1,$0,999 2 | lui $s1,999 3 | add $s2,$s1,$s1 4 | subu $s3,$s2,$s1 5 | bgezal $s1, start 6 | start: 7 | nop 8 | bltz $s3, start 9 | and $t4,$s3,$s2 10 | addi $t4,$t4,1777 11 | andi $t4,$t4,0xFFFF 12 | mult $t4,$s3 13 | mflo $t1 14 | addi $t2,$t1,-100 15 | mfhi $t2 16 | li $t1,1774 17 | ori $t6,$t5,0xF0F0 18 | sllv $t1,$t6,$t2 19 | xor $t1,$t1,$s2 20 | test: 21 | j test 22 | nop 23 | -------------------------------------------------------------------------------- /MIPSmodel/extracted/tests/test.ml: -------------------------------------------------------------------------------- 1 | exception Fail;; 2 | exception FailSafe;; 3 | exception EndReg;; 4 | 5 | open Unix 6 | open Peano 7 | open Char 8 | open BinInt 9 | open BinPos 10 | open Coqlib 11 | open Specif 12 | open Zdiv 13 | open Zpower 14 | open Big_int 15 | open Bits 16 | open Datatypes 17 | open Parser 18 | open Decode 19 | open Monad 20 | open Maps 21 | open ZArith_dec 22 | open String 23 | open List0 24 | open Zdiv 25 | open MIPSSyntax 26 | open RTL 27 | open MIPSSemantics 28 | open MIPS_RTL 29 | open MIPS_MACHINE 30 | open MIPS_PARSER 31 | open IPrinter 32 | 33 | let bii = big_int_of_int 34 | let bzero = Word.zero (bii 31) 35 | let bfalse = Word.zero (bii 0) 36 | let unsigned1 = (Word.unsigned (bii 0)) 37 | let unsigned8 = (Word.unsigned (bii 7)) 38 | let unsigned32 = (Word.unsigned (bii 31)) 39 | let signed32 = (Word.signed (bii 31)) 40 | let print_hex h = Printf.printf "%LX" h 41 | let sprint_hex h = Printf.sprintf "%LX" h 42 | let print_bigint x = print_string (string_of_big_int x) 43 | let hex_of_big x = sprint_hex (int64_of_big_int x) 44 | 45 | let get_instr () = Scanf.scanf "%LX\n" (fun h -> h);; 46 | let s_instr (i:instr) = (instr_to_str i);; 47 | let p_instrn (i:instr) = print_string ((instr_to_str i)^"\n");; 48 | 49 | 50 | let empty_mem = 51 | (Word.zero (bii 7), PTree.empty);; 52 | let empty_oracle = 53 | { oracle_bits = (fun a b -> zero_big_int); oracle_offset = zero_big_int };; 54 | let empty_regs = (fun (reg:register) -> bzero);; 55 | let init_machine : mach= 56 | { gp_regs = empty_regs; 57 | hi_reg = bzero; 58 | lo_reg = bzero; 59 | pc_reg = bzero; 60 | bdelay_active_f = bfalse; 61 | bdelay_pc_reg = bzero 62 | };; 63 | let init_rtl_state : rtl_state= 64 | { rtl_oracle = empty_oracle; 65 | rtl_env = empty_env; 66 | rtl_mach_state = init_machine; 67 | rtl_memory = empty_mem};; 68 | 69 | 70 | 71 | let rec loop icnt rs= 72 | try( 73 | let (new_instr:Int64.t) = get_instr() in 74 | let (il:instr list) = parse_word (Word.repr (bii 31) 75 | (((*print_hex new_instr;*)big_int_of_int64 new_instr))) in 76 | match il with 77 | | [] -> print_string "Parse FAIL\n" 78 | | i::tl ->( 79 | let (rtl_ans,rstate_n) = (step_ins i) rs in 80 | print_endline ("Step "^(string_of_int icnt)); 81 | print_endline (s_instr i); 82 | match rtl_ans with 83 | | Fail_ans -> ( 84 | print_endline "Failed\n") 85 | | SafeFail_ans -> print_endline "Safe Failed\n" 86 | | Okay_ans _ -> 87 | print_endline (mach_to_str (rtl_mach_state rstate_n)); 88 | loop (icnt+1) (rstate_n) 89 | ) 90 | ) 91 | with 92 | | End_of_file|Scanf.Scan_failure _ -> print_string "EOF\n" 93 | ;; 94 | 95 | let _ = loop 0 init_rtl_state;; 96 | -------------------------------------------------------------------------------- /MIPSmodel/extracted/tests/test.txt: -------------------------------------------------------------------------------- 1 | 341103e7 2 | 3c1103e7 3 | 02319020 4 | 02519823 5 | 06310000 6 | 00000000 7 | 0660fffe 8 | 02726024 9 | 218c06f1 10 | 318cffff 11 | 01930018 12 | 00004812 13 | 212aff9c 14 | 00005010 15 | 240906ee 16 | 15400002 17 | 00000000 18 | 012a001b 19 | 00006812 20 | 35aef0f0 21 | 014e4804 22 | 01324826 23 | 08100017 24 | 00000000 25 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | The Model and RockSalt directories last checked in Coq 8.5pl2 2 | 3 | x86model/ 4 | A Coq formalization of x86-32 5 | 6 | x86model/Model 7 | An x86-32 model (up to date to Coq 8.5) 8 | 9 | x86model/RockSalt 10 | A formally verified SFI checker based on our model of x86 11 | (mostly up to date to Coq 8.5, except for NaclJmp and 12 | DFACorrectness; however, recent changes in x86Semantics.v made 13 | the proof broken; needs fix) 14 | 15 | x86model/fuzz 16 | A fuzz tester for the x86 model 17 | (sorry, but hasn't tested this for a while) 18 | 19 | x86model/cdriver 20 | A C implementation of an SFI checker using our certified DFAs 21 | (sorry, but hasn't tested this for a while) 22 | 23 | x86model/semantics_trace 24 | Simulation and instrumentation of x86 binaries 25 | (sorry, but hasn't tested this for a while) 26 | 27 | MIPSmodel/ 28 | A Coq formalization of a MIPS processor 29 | 30 | ------------------------------------------------------------ 31 | 32 | Installation: 33 | 34 | * How to build the CPU models? 35 | 36 | You will need Coq 8.5pl2. 37 | 38 | - install the ocaml package manager opam 39 | - opam repo add coq-released https://coq.inria.fr/opam/released 40 | - opam install coq-flocq-2.5.1 41 | - For x86, go to x86model and type make 42 | - For MIPS, go to MIPSmodel and type make 43 | 44 | * How to build the validation tools? (sorry, haven't checked this for a while; 45 | it may not working) 46 | 47 | First, build the x86 CPU model. Then, you will need OCaml 3.12 (or a more 48 | recent verison), and pin (http://www.pintool.org/). Please go to the 49 | x86model/semantics_trace directory and for further instructions. 50 | 51 | * How to build the RockSalt C driver? (sorry, haven't checked this for a while; 52 | it may not working) 53 | 54 | You will need to install the developer version of native client first. Then, 55 | replace the native_client/src/trustaed/validator_x86/ncval.c file with ours, 56 | make sure the include for tables.h and driver.h are properly set, and build 57 | native client as usual. The resulting ncval binary can run RockSalt by 58 | passing the command line ragument --dfa. 59 | 60 | ------------------------------------------------------------ 61 | 62 | Todo list: 63 | 64 | - To be fixed: The Rocksalt directory is broken after changes to 65 | x86Semantics.v 66 | 67 | - To be fixed: in x86Semantics.v, the flags are set 68 | nondeterministically in SHL/SHR, although the manual doesn't say so -------------------------------------------------------------------------------- /shared/FloatingAux.v: -------------------------------------------------------------------------------- 1 | (* 2 | Some Auxiliary definitions for Fappli_IEEE. 3 | *) 4 | 5 | Require Import Flocq.Appli.Fappli_IEEE_bits. 6 | Require Import Flocq.Core.Fcore. 7 | Require Import Flocq.Core.Fcore_digits. 8 | Require Import Flocq.Calc.Fcalc_digits. 9 | Require Import Flocq.Appli.Fappli_IEEE. 10 | 11 | Section DE_float. 12 | 13 | (* 79 bits binary floating point numbers; 14 | 1 bit sign; 15-bit exponent; 63-bit mantissa *) 15 | Definition binary79 := binary_float 64 16384. 16 | 17 | Let Hprec : (0 < 64)%Z. 18 | apply refl_equal. 19 | Qed. 20 | 21 | Let Hprec_emax : (64 < 16384)%Z. 22 | apply refl_equal. 23 | Qed. 24 | 25 | Definition b79_of_bits : Z -> binary79 := binary_float_of_bits 63 15 (refl_equal _) (refl_equal _) (refl_equal _). 26 | Definition bits_of_b79 : binary79 -> Z := bits_of_binary_float 63 15. 27 | 28 | Definition binary79_normalize := binary_normalize 64 16384 Hprec Hprec_emax. 29 | 30 | (* 80-bit doubled extended floating point format: 31 | * 1 bit for the sign of the significand 32 | * 15 bits for the exponent 33 | * 64 bits for the significand 34 | NOTE: in contrast to 32-bit single-precision and 64-bit double-precision 35 | floating-point numbers, binary80 does not include an implicit bit. 36 | Therefore, internally 80-bit extended precision numbers are represented as binary79 37 | *) 38 | Definition de_float := binary79. 39 | 40 | Definition de_float_of_bits (x: Z) : de_float := 41 | let '(sx, mx, ex) := split_bits 64 15 x in 42 | let mx' := Zmod mx (Zpower 2 63) in (* throw away the highest bit in mantissa *) 43 | b79_of_bits (join_bits 63 15 sx mx' ex). 44 | 45 | (* when converting a de_float to bits, add the highest bit *) 46 | Definition bits_of_de_float (f:de_float) : Z := 47 | let x := bits_of_b79 f in 48 | let '(sx, mx, ex) := split_bits 63 15 x in 49 | if Zeq_bool ex 0 then 50 | (* exponent=0, representing pos/neg zero or a small number close to zero *) 51 | join_bits 64 15 sx mx ex (* the highest bit is 0 *) 52 | else if Zeq_bool ex (Zpower 2 15 - 1) then 53 | (* exponent=max; either pos/neg infinity or nan *) 54 | join_bits 64 15 sx mx ex (* the highest bit is 0 *) 55 | else 56 | join_bits 64 15 sx (Zpower 2 63 + mx)%Z ex. (* the highest bit is 1 *) 57 | 58 | Definition de_float_opp := Bopp 64 16384. 59 | Definition de_float_plus := Bplus _ _ Hprec Hprec_emax. 60 | Definition de_float_minus := Bminus _ _ Hprec Hprec_emax. 61 | Definition de_float_mult := Bmult _ _ Hprec Hprec_emax. 62 | Definition de_float_div := Bdiv _ _ Hprec Hprec_emax. 63 | Definition de_float_sqrt := Bsqrt _ _ Hprec Hprec_emax. 64 | 65 | End DE_float. 66 | 67 | Section Float_conv. 68 | 69 | Let H32prec : (0 < 24)%Z. 70 | apply refl_equal. 71 | Qed. 72 | Let H32prec_emax : (24 < 128)%Z. 73 | apply refl_equal. 74 | Qed. 75 | Definition binary32_normalize := 76 | binary_normalize 24 128 H32prec H32prec_emax. 77 | 78 | Let H64prec : (0 < 53)%Z. 79 | apply refl_equal. 80 | Qed. 81 | Let H64prec_emax : (53 < 1024)%Z. 82 | apply refl_equal. 83 | Qed. 84 | Definition binary64_normalize := 85 | binary_normalize 53 1024 H64prec H64prec_emax. 86 | 87 | Definition nan_pl_mono (prec1 prec2:Z) (nan: nan_pl prec1) 88 | (pf: Z.lt prec1 prec2): nan_pl prec2. 89 | refine (match nan with 90 | | exist _ pl pf => exist _ pl _ 91 | end). 92 | rewrite Z.ltb_lt in *. omega. 93 | Defined. 94 | 95 | Definition nan_pl_24_to_53 (nan:nan_pl 24) : nan_pl 53. 96 | refine (nan_pl_mono _ _ nan _). omega. 97 | Defined. 98 | 99 | Definition nan_pl_24_to_64 (nan:nan_pl 24) : nan_pl 64. 100 | refine (nan_pl_mono _ _ nan _). omega. 101 | Defined. 102 | 103 | Definition nan_pl_53_to_64 (nan:nan_pl 53) : nan_pl 64. 104 | refine (nan_pl_mono _ _ nan _). omega. 105 | Defined. 106 | 107 | 108 | Definition b64_of_b32 (b:binary32) : binary64 := 109 | match b with 110 | | B754_nan _ _ b n => B754_nan 53 _ b (nan_pl_24_to_53 n) 111 | | B754_zero _ _ boole => B754_zero _ _ boole 112 | | B754_infinity _ _ boole => B754_infinity _ _ boole 113 | | B754_finite _ _ sign mant ep _ => 114 | binary64_normalize mode_NE (cond_Zopp sign (Zpos mant)) ep true 115 | end. 116 | 117 | (* Definition b64_of_b32 (b:binary32) : binary64 := match b with *) 118 | (* | B754_nan => B754_nan _ _ *) 119 | (* | B754_zero boole => B754_zero _ _ boole *) 120 | (* | B754_infinity boole => B754_infinity _ _ boole *) 121 | (* | B754_finite sign mant exp _ => *) 122 | (* let exp' := (exp * Zpower 2 29)%Z in *) 123 | (* let mant' := (Zpos mant + 1920)%Z in (* 1920 is 2^11 - 2^8; here we need to adjust the bias *) *) 124 | (* let joined := join_bits 52 11 sign mant' exp' in *) 125 | (* b64_of_bits joined *) 126 | (* end. *) 127 | 128 | Definition b32_of_b64 (b: binary64) : binary32 := 129 | match b with 130 | | B754_nan _ _ b n => 131 | (* using the default nan below; the real processor may behave differently *) 132 | let (b1,n1) := default_nan_pl32 in B754_nan _ _ b1 n1 133 | | B754_zero _ _ boole => B754_zero _ _ boole 134 | | B754_infinity _ _ boole => B754_infinity _ _ boole 135 | | B754_finite _ _ sign mant ep _ => 136 | binary32_normalize mode_NE 137 | (cond_Zopp sign (Zpos mant)) ep true 138 | end. 139 | 140 | Definition de_float_of_b32 (b:binary32) : de_float := 141 | match b with 142 | | B754_nan _ _ b n => B754_nan _ _ b (nan_pl_24_to_64 n) 143 | | B754_zero _ _ boole => B754_zero _ _ boole 144 | | B754_infinity _ _ boole => B754_infinity _ _ boole 145 | | B754_finite _ _ sign mant ep _ => 146 | binary79_normalize mode_NE 147 | (cond_Zopp sign (Zpos mant)) ep true 148 | end. 149 | 150 | Definition b32_of_de_float (b:de_float) : binary32 := 151 | match b with 152 | | B754_nan _ _ b n => 153 | (* using the default nan below; the real processor may behave differently *) 154 | let (b1,n1) := default_nan_pl32 in B754_nan _ _ b1 n1 155 | | B754_zero _ _ boole => B754_zero _ _ boole 156 | | B754_infinity _ _ boole => B754_infinity _ _ boole 157 | | B754_finite _ _ sign mant ep _ => 158 | binary32_normalize mode_NE 159 | (cond_Zopp sign (Zpos mant)) ep true 160 | end. 161 | 162 | Definition de_float_of_b64 (b:binary64) : de_float := 163 | match b with 164 | | B754_nan _ _ b n => B754_nan _ _ b (nan_pl_53_to_64 n) 165 | | B754_zero _ _ boole => B754_zero _ _ boole 166 | | B754_infinity _ _ boole => B754_infinity _ _ boole 167 | | B754_finite _ _ sign mant ep _ => 168 | binary79_normalize mode_NE 169 | (cond_Zopp sign (Zpos mant)) ep true 170 | end. 171 | 172 | Definition b64_of_de_float (b:de_float) : binary64 := 173 | match b with 174 | | B754_nan _ _ b n => 175 | (* using the default nan below; the real processor may behave differently *) 176 | let (b1,n1) := default_nan_pl64 in B754_nan _ _ b1 n1 177 | | B754_zero _ _ boole => B754_zero _ _ boole 178 | | B754_infinity _ _ boole => B754_infinity _ _ boole 179 | | B754_finite _ _ sign mant ep _ => 180 | binary64_normalize mode_NE 181 | (cond_Zopp sign (Zpos mant)) ep true 182 | end. 183 | 184 | End Float_conv. 185 | 186 | Section Comp_Tests. 187 | 188 | Local Open Scope positive_scope. 189 | 190 | (* number: 1.101 * 2^0 *) 191 | (* sign: 0; exponent: 01111111; fraction:10100000000000000000000 *) 192 | Definition f32_num1 := b32_of_bits 193 | (Zpos 1~1~1~1~1~1~1 194 | ~1~0~1~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0). 195 | 196 | (* number: -1.11 *) 197 | (* sign: 1; exponent: 01111111; fraction:11000000000000000000000 *) 198 | Definition f32_num2 := b32_of_bits 199 | (Zpos 1~ 200 | 0~1~1~1~1~1~1~1 201 | ~1~1~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0). 202 | 203 | (* positive zero *) 204 | Definition f32_pos0 := b32_of_bits 0%Z. 205 | 206 | (* Testing simple operations on b32 *) 207 | 208 | (* result should be: 1.101 * 2^1 *) 209 | (* sign: 0 exponent: 1000 0000; fraction: 10100000000000000000000 *) 210 | Eval compute in (bits_of_b32 (b32_plus mode_NE f32_num1 f32_num1)). 211 | 212 | (* result should be - 1.000 * 2^(-3) *) 213 | (* sign: 1 exponent: 0111 1100; fraction: 00000000000000000000000 *) 214 | Eval compute in (bits_of_b32 (b32_plus mode_NE f32_num1 f32_num2)). 215 | 216 | Eval compute in (bits_of_b32 (b32_plus mode_NE f32_pos0 f32_pos0)). 217 | Eval compute in (bits_of_b32 (b32_plus mode_NE f32_pos0 f32_num1)). 218 | 219 | (* Testing conversions *) 220 | Eval compute in (bits_of_b64 (b64_of_b32 f32_num1)). 221 | Eval compute in (bits_of_b64 (b64_of_b32 f32_pos0)). 222 | Eval compute in (bits_of_b32 f32_num1). 223 | Eval compute in (bits_of_b32 (b32_of_b64 (b64_of_b32 f32_num1))). 224 | Eval compute in (bits_of_b64 (b64_of_b32 f32_num2)). 225 | Eval compute in (bits_of_b32 f32_num2). 226 | Eval compute in (bits_of_b32 (b32_of_b64 (b64_of_b32 f32_num2))). 227 | 228 | (* result is 229 | 0 230 | 011111111111111 231 | 1101000000000000000000000000000000000000000000000000000000000000 232 | *) 233 | Eval compute in (bits_of_de_float (de_float_of_b32 f32_num1)). 234 | 235 | (* result is 236 | 1 237 | 011111111111111 238 | 1110000000000000000000000000000000000000000000000000000000000000 239 | *) 240 | Eval compute in (bits_of_de_float (de_float_of_b32 f32_num2)). 241 | Eval compute in (bits_of_b32 f32_num1). 242 | Eval compute in (bits_of_b32 (b32_of_de_float (de_float_of_b32 f32_num1))). 243 | Eval compute in (bits_of_b32 f32_num2). 244 | Eval compute in (bits_of_b32 (b32_of_de_float (de_float_of_b32 f32_num2))). 245 | 246 | End Comp_Tests. 247 | -------------------------------------------------------------------------------- /shared/Makefile: -------------------------------------------------------------------------------- 1 | 2 | MODULES := Coqlib CommonTacs Maps Bits Monad Vector MSetsMore RTL FloatingAux 3 | VS := $(MODULES:%=%.v) 4 | 5 | .PHONY: coq clean 6 | 7 | coq: Makefile.coq 8 | $(MAKE) -f Makefile.coq 9 | 10 | Makefile.coq: Makefile $(VS:%=%) 11 | coq_makefile -R . Shared $(VS) -o Makefile.coq 12 | 13 | clean:: Makefile.coq 14 | $(MAKE) -f Makefile.coq clean 15 | rm -f Makefile.coq .depend 16 | -------------------------------------------------------------------------------- /shared/Monad.v: -------------------------------------------------------------------------------- 1 | (* Copyright (c) 2011. Greg Morrisett, Gang Tan, Joseph Tassarotti, 2 | Jean-Baptiste Tristan, and Edward Gan. 3 | 4 | This file is part of RockSalt. 5 | 6 | This file is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License as 8 | published by the Free Software Foundation; either version 2 of 9 | the License, or (at your option) any later version. 10 | *) 11 | 12 | Require Import Coqlib. 13 | 14 | Set Implicit Arguments. 15 | 16 | Class Monad(M:Type->Type) : Type := { 17 | Return : forall (A:Type), A -> M A ; 18 | Bind : forall (A B:Type), M A -> (A -> M B) -> M B ; 19 | ret_left_unit : forall A B (x:A) (f:A -> M B), Bind (Return x) f = f x ; 20 | ret_right_unit : forall A (c:M A), Bind c (@Return _) = c ; 21 | bind_assoc : forall A B C (f:M A) (g:A -> M B) (h:B -> M C), 22 | Bind (Bind f g) h = Bind f (fun x => Bind (g x) h) 23 | }. 24 | 25 | Notation "'ret' x" := (Return x) (at level 75) : monad_scope. 26 | Notation "x <- c1 ; c2" := (Bind _ c1 (fun x => c2)) 27 | (right associativity, at level 84, c1 at next level) : monad_scope. 28 | Notation "c1 ;; c2" := (Bind _ c1 (fun _ => c2)) 29 | (right associativity, at level 84) : monad_scope. 30 | Notation "[ x , y ] <- c1 ; c2" := 31 | (Bind _ c1 (fun v => match v with | (x,y) => c2 end)) 32 | (right associativity, at level 84) : monad_scope. 33 | 34 | Instance OptionMonad : Monad option := { 35 | Return := fun A x => Some x ; 36 | Bind := fun A B c f => match c with | None => None | Some v => f v end 37 | }. 38 | auto. destruct c ; auto. intros. destruct f ; auto. 39 | Defined. 40 | 41 | Definition ST(S A:Type) := S -> S * A. 42 | 43 | Instance StateMonad(S:Type) : Monad (ST S) := { 44 | Return := fun A x s => (s,x) ; 45 | Bind := fun A B c f s => match c s with | (s',x) => f x s' end 46 | }. 47 | intros. apply extensionality ; auto. 48 | intros. apply extensionality. intro. destruct (c x) ; auto. 49 | intros. apply extensionality ; auto. intros. destruct (f x) ; auto. 50 | Defined. 51 | 52 | Instance ListMonad : Monad list := { 53 | Return := fun A x => x::nil ; 54 | Bind := fun A B c f => list_flatten (map f c) 55 | }. 56 | intros. simpl. rewrite app_nil_end. auto. 57 | intros. induction c ; auto. simpl. rewrite IHc ; auto. 58 | intros. induction f ; auto. simpl. rewrite map_app. 59 | rewrite <- flatten_distr. rewrite IHf. auto. 60 | Defined. 61 | 62 | -------------------------------------------------------------------------------- /shared/Vector.v: -------------------------------------------------------------------------------- 1 | Require Import Coq.Lists.List. 2 | 3 | Axiom vector : Type -> Type. 4 | Axiom length : forall {A}, vector A -> nat. 5 | Axiom get : forall {A} (v:vector A) (i:nat), (i < length v) -> A. 6 | Axiom of_list : forall {A}, list A -> vector A. 7 | 8 | Axiom get_of_list : 9 | forall A (l:list A) i (H:i < length (of_list l)), 10 | nth_error l i = Some (@get _ (of_list l) i H). 11 | Axiom length_of_list : 12 | forall A (l:list A), length (of_list l) = List.length l. 13 | 14 | Extract Constant vector "'a" => "'a array". 15 | Extract Constant length => "fun v -> Big.of_int (Array.length v)". 16 | Extract Constant get => "fun v i -> Array.unsafe_get v (Big.to_int i)". 17 | Extract Inlined Constant of_list => "Array.of_list". 18 | -------------------------------------------------------------------------------- /x86model/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all: 3 | $(MAKE) -C Model 4 | # commented out for now 5 | # $(MAKE) -C RockSalt 6 | -------------------------------------------------------------------------------- /x86model/Model/GrammarType.v: -------------------------------------------------------------------------------- 1 | Require Import ParserArg. 2 | 3 | (* Grammar should be parametrized by a PARSER_ARG module; however, that 4 | would impede code extraction because of a Coq bug. Instead, we 5 | introduce a bunch of definitions below to achieve some separation as 6 | long as we never directly use definitions in X86_PARSER_ARG *) 7 | Definition char_p := X86_PARSER_ARG.char_p. 8 | Definition char_dec := X86_PARSER_ARG.char_dec. 9 | Definition user_type := X86_PARSER_ARG.user_type. 10 | Definition user_type_dec := X86_PARSER_ARG.user_type_dec. 11 | Definition user_type_denote := X86_PARSER_ARG.user_type_denote. 12 | Definition token_id := X86_PARSER_ARG.token_id. 13 | Definition num_tokens := X86_PARSER_ARG.num_tokens. 14 | Definition token_id_to_chars := X86_PARSER_ARG.token_id_to_chars. 15 | 16 | (** The [type]s for our grammars. *) 17 | Inductive type : Type := 18 | | Unit_t : type 19 | | Char_t : type 20 | | Void_t : type 21 | | Pair_t : type -> type -> type 22 | | Sum_t : type -> type -> type 23 | | List_t : type -> type 24 | | Option_t : type -> type 25 | | User_t : user_type -> type. 26 | 27 | (** [void] is an empty type. *) 28 | Inductive void : Type := . 29 | 30 | (** The interpretation of [type]s as Coq [Type]s. *) 31 | Fixpoint interp (t:type) : Type := 32 | match t with 33 | | Unit_t => unit 34 | | Char_t => char_p 35 | | Void_t => void 36 | | Pair_t t1 t2 => (interp t1) * (interp t2) 37 | | Sum_t t1 t2 => (interp t1) + (interp t2) 38 | | List_t t => list (interp t) 39 | | Option_t t => option (interp t) 40 | | User_t t => user_type_denote t 41 | end%type. 42 | -------------------------------------------------------------------------------- /x86model/Model/Makefile: -------------------------------------------------------------------------------- 1 | MODULES := X86Syntax ParserArg Xform Regexp RESet GrammarType Grammar BiGrammar Parser Recognizer X86BG_ins X86BG Encode X86Semantics SemTests Decode 2 | # CheckDeterministic 3 | VS := $(MODULES:%=%.v) 4 | 5 | .PHONY: coq clean 6 | 7 | coq: Makefile.coq 8 | $(MAKE) -C ../../shared 9 | $(MAKE) -f Makefile.coq 10 | 11 | Makefile.coq: Makefile $(VS:%=%) 12 | coq_makefile -R . X86Model -R ../../shared Shared $(VS) -o Makefile.coq 13 | 14 | clean:: Makefile.coq 15 | $(MAKE) -f Makefile.coq clean 16 | rm -f Makefile.coq .depend 17 | -------------------------------------------------------------------------------- /x86model/Model/decenc_tests/cat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gangtan/CPUmodels/a6decc3085e1f8d8d4875e67f9ad9c7663910f8a/x86model/Model/decenc_tests/cat -------------------------------------------------------------------------------- /x86model/Model/decenc_tests/extract.v: -------------------------------------------------------------------------------- 1 | (* Extract an OCaml x86 model from the Coq x86 model *) 2 | 3 | Require ExtrOcamlString. 4 | 5 | (* Map nat to OCaml big_int *) 6 | Require ExtrOcamlNatBigInt. 7 | 8 | (* fix bug in Require ExtrOcamlNatBigInt: missing the outer parentheses *) 9 | Extract Constant minus => "(fun n m -> Big.max Big.zero (Big.sub n m))". 10 | 11 | (* Map Z and pos to OCaml big_int *) 12 | Require ExtrOcamlZBigInt. 13 | 14 | (* bypassing the extraction of opaque constants *) 15 | Set Extraction AccessOpaque. 16 | 17 | Extract Inductive sigT => "(*)" [ "(,)" ]. 18 | 19 | Require Import X86Model.X86BG. 20 | (* Require Import X86Model.Decode. *) 21 | Require Import X86Model.Parser. 22 | Require X86Model.X86Semantics. 23 | Extraction Blacklist String List. 24 | Require Encode. 25 | 26 | Set Extraction Optimize. 27 | Set Extraction AutoInline. 28 | 29 | (* without this, some files will use an extracted Nat module, which conflicts with 30 | Ocaml's default Nat module *) 31 | Extraction Blacklist Nat. 32 | 33 | (* Did not extract X86Semantics.step below since that would call 34 | build_dfa on the instruction grammar, which would take 35 | approximately 2 minutes. One way of avoiding this is to change the 36 | definition of X86Semantics.step to be parameterized by a dfa 37 | builder, similar to how initial_parse_state' does it; that way, the 38 | client can supply a dfa builder that just deserializes the dfa from 39 | a file, isntead of building it from scratch. *) 40 | 41 | Separate Extraction initial_parser_state parse_tokens 42 | vinitial_parser_state vparse_tokens 43 | initial_naive_parser_state naive_parse_token 44 | (* instruction_grammar *) 45 | instr_bigrammar BiGrammar.bigrammar_to_grammar 46 | X86Semantics.X86_Compile.instr_to_rtl 47 | Encode.x86_encode (* encoder from the bigrammar *) 48 | Encode.enc_pre_instr_bytes (* a manual encoder *) 49 | . 50 | 51 | (* Separate Extraction initial_parser_state parse_tokens *) 52 | (* vinitial_parser_state vparse_tokens *) 53 | (* initial_naive_parser_state naive_parse_token *) 54 | (* instruction_grammar X86Semantics.X86_Compile.instr_to_rtl. *) 55 | 56 | (* Separate Extraction build_dfa dfa_recognize par2rec X86_PARSER.instr_grammar. *) 57 | 58 | (* Extraction "recognizer.ml" build_dfa dfa_recognize par2rec . *) 59 | -------------------------------------------------------------------------------- /x86model/Model/decenc_tests/ls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gangtan/CPUmodels/a6decc3085e1f8d8d4875e67f9ad9c7663910f8a/x86model/Model/decenc_tests/ls -------------------------------------------------------------------------------- /x86model/Model/decenc_tests/pwd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gangtan/CPUmodels/a6decc3085e1f8d8d4875e67f9ad9c7663910f8a/x86model/Model/decenc_tests/pwd -------------------------------------------------------------------------------- /x86model/Model/decenc_tests/tailf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gangtan/CPUmodels/a6decc3085e1f8d8d4875e67f9ad9c7663910f8a/x86model/Model/decenc_tests/tailf -------------------------------------------------------------------------------- /x86model/RockSalt/FastVerifier.v: -------------------------------------------------------------------------------- 1 | (* Copyright (c) 2011. Greg Morrisett, Gang Tan, Joseph Tassarotti, 2 | Jean-Baptiste Tristan, and Edward Gan. 3 | 4 | This file is part of RockSalt. 5 | 6 | This file is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License as 8 | published by the Free Software Foundation; either version 2 of 9 | the License, or (at your option) any later version. 10 | *) 11 | 12 | 13 | Require Import Coqlib. 14 | Require Import Parser. 15 | Require Import Decode. 16 | Require Import X86Syntax. 17 | Require Import Recognizer. 18 | 19 | Require Import Int32. 20 | Require Import VerifierDFA. 21 | 22 | Import ParserArg.X86_PARSER_ARG. 23 | (* Import X86_PARSER. *) 24 | (* Import X86_BASE_PARSER. *) 25 | 26 | Require Coq.MSets.MSetAVL. 27 | Require Coq.Structures.OrdersAlt. 28 | Require Coq.MSets.MSetFacts. 29 | Module New_Int32_OT := (Coq.Structures.OrdersAlt.Update_OT Int32_OT). 30 | Module Int32Set := Coq.MSets.MSetAVL.Make New_Int32_OT. 31 | 32 | Definition n_shift_add (b: bool) (x: nat) := 33 | (if b then 2 * x + 1 else 2 * x)%nat. 34 | 35 | Open Scope Z_scope. 36 | 37 | Fixpoint n_of_bits (n: nat) (f: Z -> bool) {struct n}: nat := 38 | match n with 39 | | O => O 40 | | S m => n_shift_add (f 0) (n_of_bits m (fun i => f (i + 1))) 41 | end. 42 | 43 | Section BUILT_DFAS. 44 | 45 | (* In this section we will just assume the DFAs are all built; 46 | that is, non_cflow_dfa should be the result of "make_dfa non_cflow_parser" and 47 | similarly for dir_cflow_dfa and nacljmp_dfa *) 48 | Variable non_cflow_dfa : Recognizer.DFA. 49 | Variable dir_cflow_dfa : Recognizer.DFA. 50 | Variable nacljmp_dfa : Recognizer.DFA. 51 | 52 | Variable initial_state : ParseState_t. 53 | 54 | (* G.T.: may be a good idea to parametrize the DFA w.r.t. the ChunkSize; 55 | Google's verifier allows it either to be 16 or 32. 56 | Parameters logChunkSize:nat. 57 | Hypothesis logChunkSize_range : (0 < logChunkSize <= Word.wordsize 31)%nat. 58 | *) 59 | 60 | Fixpoint parseloop (ps: ParseState_t) (bytes:list int8) : 61 | option ((prefix * instr) * list int8) := 62 | match bytes with 63 | | nil => None 64 | | b::bs => match parse_byte ps b with 65 | | (ps',nil) => parseloop ps' bs 66 | | (_, v::_) => Some (v,bs) 67 | end 68 | end. 69 | 70 | Definition extract_disp (bytes: list int8) := 71 | match (parseloop initial_state bytes) with 72 | | Some ((_, JMP true false (Imm_op disp) None), _) => Some disp 73 | | Some ((_, Jcc ct disp), _) => Some disp 74 | | Some ((_, CALL true false (Imm_op disp) None), _) => Some disp 75 | | _ => None 76 | end. 77 | 78 | 79 | (* Note: it's important to specify the type of tokens as "list token_id", not 80 | "list nat", even though token_id is defined to be nat. If a proof environment 81 | has one value of type "list token_id" and the other of type "list nat", 82 | proof scripts such as rewrite or omega may fail since token_id needs to 83 | be unfolded. *) 84 | Fixpoint process_buffer_aux (loc: int32) (n: nat) (tokens:list token_id) 85 | (curr_res: Int32Set.t * Int32Set.t) := 86 | let (start_instrs, check_list) := curr_res in 87 | match tokens with 88 | | nil => Some curr_res 89 | | _ => (* There are left over bytes in the buffer *) 90 | match n with 91 | | O => None 92 | | S m => 93 | match (dfa_recognize non_cflow_dfa tokens, 94 | dfa_recognize dir_cflow_dfa tokens, 95 | dfa_recognize nacljmp_dfa tokens) with 96 | | (Some (len, remaining), None, None) => 97 | process_buffer_aux (loc +32_n len) m remaining 98 | (Int32Set.add loc start_instrs, check_list) 99 | 100 | | (None, Some (len, remaining), None) => 101 | match extract_disp (List.map token2byte (firstn len tokens)) with 102 | | None => None 103 | | Some disp => 104 | process_buffer_aux (loc +32_n len) m remaining 105 | (Int32Set.add loc start_instrs, 106 | Int32Set.add (loc +32_n len +32 disp) check_list) 107 | end 108 | | (Some res0, None, Some (len, remaining)) => 109 | process_buffer_aux (loc +32_n len) m remaining 110 | (Int32Set.add loc start_instrs, check_list) 111 | | _ => None (* None of the DFAs matched or too many DFAs matched *) 112 | end 113 | end 114 | end. 115 | 116 | (* The idea here is, given a list of int8s representing the code, 117 | we call process_buffer_aux with n := length of the list; 118 | since each instruction is at least one byte long, this should 119 | be enough calls to process_buffer_aux to process everything in 120 | the buffer, without us having to worry about termination proofs 121 | Note: one way to avoid the n is would be to show each dfa consumes 122 | at least one byte. 123 | *) 124 | Definition process_buffer (buffer: list int8) := 125 | process_buffer_aux (Word.repr 0) (length buffer) (List.map byte2token buffer) 126 | (Int32Set.empty, Int32Set.empty). 127 | 128 | Definition aligned_bool (a:int32):bool := 129 | Zeq_bool (Zmod (unsigned a) chunkSize) 0. 130 | Definition aligned (a:int32) := aligned_bool a = true. 131 | 132 | (* This calls process_buffer. If that returns a None, then the 133 | program is not safe. If process_buffer returns a set of start 134 | addresses and known jump addresses, then we need to check that 135 | any address in the jump addresses which is not in the start addresses 136 | is aligned. This is done by taking the set difference of check_addrs 137 | and start_addrs, filtering check_addrs for all of the aligned addresses 138 | and then checking that the filtering process doesn't remove anything 139 | (Perhaps it's faster to do a filter on the negation of aligned_bool 140 | and then check that the result is empty). 141 | 142 | We also check that the number of aligned start_addrs 143 | is equal to the number of aligned addresses we should have if 144 | this code segment is loaded at an aligned address. 145 | 146 | The count of the number of aligned addresses could be done in the 147 | process_buffer loop, but I didn't want to complicate the logic 148 | there any more. *) 149 | 150 | Require Import Coq.funind.Recdef. 151 | Function checkAligned_aux (p: Int32Set.t * Z * nat) {measure snd p} 152 | : bool := 153 | match p with 154 | | (_, 0%nat) => true 155 | | ((startAddrs, next), len) => 156 | (Int32Set.mem (repr next) startAddrs && 157 | checkAligned_aux (startAddrs, (next + chunkSize), 158 | (len - Zabs_nat chunkSize)%nat)) 159 | end. 160 | intros. simpl. omega. 161 | Defined. 162 | 163 | (* checking that all aligned addresses between 0 and len is in startAddrs *) 164 | Definition checkAligned (startAddrs:Int32Set.t) (len: nat) :bool := 165 | checkAligned_aux (startAddrs, 0, len). 166 | 167 | (* checking all jump targets are either in startAddrs or are aligned addresses *) 168 | Definition checkJmpTargets (jmpTargets startAddrs: Int32Set.t) := 169 | let check_start_diff := Int32Set.diff jmpTargets startAddrs in 170 | Int32Set.for_all aligned_bool check_start_diff. 171 | 172 | Definition checkProgram (buffer: list int8) : (bool * Int32Set.t) := 173 | match process_buffer buffer with 174 | | None => (false, Int32Set.empty) 175 | | Some (start_addrs, check_addrs) => 176 | let check_start_diff := Int32Set.diff check_addrs start_addrs in 177 | (andb (checkAligned start_addrs (length buffer)) 178 | (checkJmpTargets check_addrs start_addrs), 179 | start_addrs) 180 | end. 181 | 182 | End BUILT_DFAS. 183 | 184 | Definition ncflow := make_dfa non_cflow_grammar. 185 | Definition dbranch := make_dfa (alts dir_cflow). 186 | Definition ibranch := make_dfa (alts nacljmp_mask). 187 | 188 | (*Extraction "fastverif.ml" checkProgram ncflow dbranch ibranch.*) 189 | -------------------------------------------------------------------------------- /x86model/RockSalt/Makefile: -------------------------------------------------------------------------------- 1 | MODULES := VerifierDFA FastVerifier Int32 X86Lemmas VerifierCorrectness 2 | # NACLjmp DFACorrectness VerifierCorrectness 3 | 4 | VS := $(MODULES:%=%.v) 5 | 6 | .PHONY: coq clean 7 | 8 | coq: Makefile.coq 9 | $(MAKE) -f Makefile.coq 10 | 11 | Makefile.coq: Makefile $(VS:%=%) 12 | echo $(VS) 13 | coq_makefile -R . Rocksalt -R ../Model/ X86Model $(VS) -o Makefile.coq 14 | 15 | clean:: Makefile.coq 16 | $(MAKE) -f Makefile.coq clean 17 | rm -f Makefile.coq .depend 18 | -------------------------------------------------------------------------------- /x86model/RockSalt/lia.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gangtan/CPUmodels/a6decc3085e1f8d8d4875e67f9ad9c7663910f8a/x86model/RockSalt/lia.cache -------------------------------------------------------------------------------- /x86model/cdriver/Tables.v: -------------------------------------------------------------------------------- 1 | Add LoadPath "../". 2 | Require Import VerifierDFA. 3 | 4 | Extraction "tables.ml" dfas. -------------------------------------------------------------------------------- /x86model/cdriver/dfa_export.ml: -------------------------------------------------------------------------------- 1 | (* Copyright (c) 2011. Greg Morrisett, Gang Tan, Joseph Tassarotti, 2 | Jean-Baptiste Tristan, and Edward Gan. 3 | 4 | This file is part of RockSalt. 5 | 6 | This file is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License as 8 | published by the Free Software Foundation; either version 2 of 9 | the License, or (at your option) any later version. 10 | *) 11 | 12 | 13 | let print_bits max l s stab = 14 | Printf.printf "uint8_t %s_%s[%n] = {\n" stab s max; 15 | for i = 0 to (max - 1) do 16 | if i mod 10 = 0 then Printf.printf "\n"; 17 | Printf.printf "[%3n]=%n" i (if (List.nth l i) then 1 else 0); 18 | if (i <> (max - 1)) then Printf.printf " , "; 19 | done; 20 | Printf.printf "};\n" 21 | 22 | (* let print_line num l last = *) 23 | (* for i = 0 to 254 do *) 24 | (* if i mod 10 = 0 then Printf.printf "\n"; *) 25 | (* Printf.printf "[%3n][%3n]=%3n" num i (List.nth l i); *) 26 | (* if (i <> 254) || (not last) then Printf.printf " , " *) 27 | (* done; *) 28 | (* Printf.printf "\n" *) 29 | (* ;; *) 30 | 31 | (* let print_transition max l s = *) 32 | (* Printf.printf "uint8_t table_%s[%3n][255] = {\n" s max; *) 33 | (* for i = 0 to (max - 1) do *) 34 | (* let b = if i = (max-1) then true else false in *) 35 | (* print_line i (List.nth l i) b *) 36 | (* done; *) 37 | (* Printf.printf "};\n" *) 38 | (* ;; *) 39 | 40 | let print_line num l s = 41 | Printf.printf "uint8_t line_%s_%n[256] = { " s num; 42 | for i = 0 to 255 do 43 | if i mod 10 = 0 then Printf.printf "\n"; 44 | Printf.printf "%3n" (List.nth l i); 45 | if (i <> 255) then Printf.printf " , " 46 | done; 47 | Printf.printf "}; \n"; 48 | ;; 49 | 50 | let print_transition max l s = 51 | for i = 0 to (max - 1) do 52 | print_line i (List.nth l i) s 53 | done; 54 | Printf.printf "uint8_t *table_%s[%3n] = {\n" s max; 55 | for i = 0 to (max - 1) do 56 | Printf.printf "line_%s_%n" s i; 57 | if (i <> max) then Printf.printf " , " 58 | done; 59 | Printf.printf "};\n" 60 | ;; 61 | 62 | let print_dfa dfa s = 63 | match dfa with 64 | | None ->failwith "No DFA...\n" 65 | | Some dfa -> 66 | let max = X86_PARSER.X86_BASE_PARSER.dfa_num_states dfa in 67 | print_transition max (X86_PARSER.X86_BASE_PARSER.dfa_transition dfa) s; 68 | print_bits max (X86_PARSER.X86_BASE_PARSER.dfa_accepts dfa) s "accepts"; 69 | print_bits max (X86_PARSER.X86_BASE_PARSER.dfa_rejects dfa) s "rejects"; 70 | ;; 71 | 72 | print_dfa (fst (fst dfas)) "ncflow";; 73 | print_dfa (snd (fst dfas)) "dbranch";; 74 | print_dfa (snd dfas) "ibranch";; 75 | 76 | Printf.printf " 77 | typedef struct automaton {\n 78 | uint8_t **table;\n 79 | uint8_t *accepts;\n 80 | uint8_t *rejects;\n 81 | uint8_t start;\n 82 | } DFA;\n 83 | ";; 84 | 85 | let init_DFA s = 86 | Printf.printf "DFA %s = { .table = table_%s , .accepts = accepts_%s , .rejects = rejects_%s , .start = 0 };\n" s s s s 87 | ;; 88 | 89 | init_DFA "ncflow";; 90 | init_DFA "dbranch";; 91 | init_DFA "ibranch";; 92 | 93 | -------------------------------------------------------------------------------- /x86model/cdriver/driver.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2011. Greg Morrisett, Gang Tan, Joseph Tassarotti, 2 | Jean-Baptiste Tristan, and Edward Gan. 3 | 4 | This file is part of RockSalt. 5 | 6 | This file is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License as 8 | published by the Free Software Foundation; either version 2 of 9 | the License, or (at your option) any later version. 10 | */ 11 | 12 | 13 | #include 14 | #include 15 | 16 | uint8_t *valid; 17 | uint8_t *target; 18 | 19 | Bool match(DFA *A, uint8_t *code, uint *pos, uint size) { 20 | 21 | uint8_t state = A->start; 22 | uint off = 0; 23 | 24 | while (*pos + off < size) { 25 | 26 | state = A->table[state][code[*pos + off]]; 27 | off++; 28 | 29 | if (A->rejects[state]) break; 30 | 31 | if (A->accepts[state]) { 32 | *pos += off; 33 | return TRUE; 34 | } 35 | 36 | } 37 | 38 | return FALSE; 39 | } 40 | 41 | int compute_rel(uint8_t *code, uint nbytes) { 42 | uint i; 43 | uint32_t acc = 0; 44 | 45 | for (i = 0; i < nbytes; ++i) 46 | acc += (code[i] << (8 * i)); 47 | 48 | return acc; 49 | } 50 | 51 | Bool extract(uint8_t *code, uint start_pos, uint new_pos, uint size) { 52 | 53 | uint8_t b1, b2; 54 | Bool ok = FALSE; 55 | 56 | b1 = code[start_pos]; 57 | if (b1 != 0x0F) { 58 | if (((0x70 <= b1) && (b1 <= 0x7F)) || (b1 == 0xE3) || (b1 == 0xEB)) { 59 | if(new_pos + compute_rel(&code[start_pos+1], 1) < size) { 60 | target[new_pos+ (int8_t) compute_rel(&code[start_pos+1],1)] = 1; 61 | ok = TRUE; 62 | } 63 | else { 64 | ok = FALSE; 65 | } 66 | } 67 | if ((b1 == 0xE9) || (b1 == 0xE8)) { 68 | if (compute_rel(&code[start_pos+1],4) < 0) { 69 | if ((new_pos + compute_rel(&code[start_pos+1],4)) % 32 == 0) { 70 | ok = TRUE; 71 | } 72 | } 73 | else{ 74 | if ((new_pos + compute_rel(&code[start_pos+1],4) < size)) { 75 | target[new_pos+ compute_rel(&code[start_pos+1],4)] = 1; 76 | ok = TRUE; 77 | } 78 | else { 79 | ok = FALSE; 80 | } 81 | } 82 | } 83 | } 84 | else { 85 | b2 = code[start_pos+1]; 86 | 87 | if (((0x80 <= b2) && (b2 <= 0x8F))) { 88 | target[new_pos+ compute_rel(&code[start_pos+2],4)] = 1; 89 | ok = TRUE; 90 | } 91 | } 92 | 93 | return (ok?1:0); 94 | } 95 | 96 | Bool verifier(DFA *NonControlFlow, 97 | DFA *DirectJump, 98 | DFA *MaskedJump, 99 | uint8_t *code, uint size) { 100 | 101 | uint pos = 0, i, saved_pos; 102 | Bool b = TRUE; 103 | 104 | valid = (uint8_t *) calloc(size * sizeof(uint8_t),sizeof(uint8_t)); 105 | target = (uint8_t *) calloc(size * sizeof(uint8_t),sizeof(uint8_t)); 106 | 107 | while (pos < size) { 108 | valid[pos] = TRUE; 109 | saved_pos = pos; 110 | 111 | if (match(MaskedJump,code,&pos,size)) continue; 112 | 113 | if (match(NonControlFlow,code,&pos,size)) continue; 114 | 115 | if (match(DirectJump,code,&pos,size)) 116 | if (extract(code,saved_pos,pos,size)) continue; 117 | 118 | free(target); free(valid); 119 | return FALSE; 120 | } 121 | 122 | for (i = 0; i < size; ++i) 123 | b = b && 124 | ( !(target[i]) || valid[i] ) && 125 | ( i & 0x1F || valid[i] ); 126 | 127 | return b; 128 | } 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /x86model/cdriver/mktables: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "coqc Tables.v" 4 | coqc Tables.v 5 | rm tables.mli 6 | echo "cat dfa_export.ml >> tables.ml" 7 | cat dfa_export.ml >> tables.ml 8 | echo "ocamlopt tables.ml -o tables" 9 | ocamlopt tables.ml -o tables 10 | echo "./tables > tables.h" 11 | ./tables > tables.h 12 | rm tables.cmx tables.cmi Tables.glob tables.ml tables.o Tables.vo tables -------------------------------------------------------------------------------- /x86model/cdriver/naclsmith: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm log 4 | rm interesting_smith/*.nexe 5 | for i in {1..1000} 6 | do 7 | j=$[$i/10] 8 | printf "\r %d%%" $j 9 | echo Number $i >> log 10 | csmith --no-checksum > smith.c 11 | nacl-gcc -I/home/tristan/Code/csmith-2.0.0/runtime smith.c -o smith.nexe >& /dev/null 12 | cp smith.nexe interesting_smith/smith$i.nexe 13 | ncval smith.nexe | grep RESULT >> log 14 | ncval smith.nexe --dfa | grep RESULT >> log 15 | done -------------------------------------------------------------------------------- /x86model/cdriver/test/binarytrees.c: -------------------------------------------------------------------------------- 1 | /* The Computer Language Shootout Benchmarks 2 | http://shootout.alioth.debian.org/ 3 | 4 | contributed by Kevin Carson 5 | compilation: 6 | gcc -O3 -fomit-frame-pointer -funroll-loops -static binary-trees.c -lm 7 | icc -O3 -ip -unroll -static binary-trees.c -lm 8 | */ 9 | 10 | #include 11 | //#include 12 | #include 13 | 14 | 15 | typedef struct tn { 16 | struct tn* left; 17 | struct tn* right; 18 | long item; 19 | } treeNode; 20 | 21 | 22 | treeNode* NewTreeNode(treeNode* left, treeNode* right, long item) 23 | { 24 | treeNode* new; 25 | 26 | new = (treeNode*)malloc(sizeof(treeNode)); 27 | 28 | new->left = left; 29 | new->right = right; 30 | new->item = item; 31 | 32 | return new; 33 | } /* NewTreeNode() */ 34 | 35 | 36 | long ItemCheck(treeNode* tree) 37 | { 38 | if (tree->left == NULL) 39 | return tree->item; 40 | else 41 | return tree->item + ItemCheck(tree->left) - ItemCheck(tree->right); 42 | } /* ItemCheck() */ 43 | 44 | 45 | treeNode* BottomUpTree(long item, unsigned depth) 46 | { 47 | if (depth > 0) 48 | return NewTreeNode 49 | ( 50 | BottomUpTree(2 * item - 1, depth - 1), 51 | BottomUpTree(2 * item, depth - 1), 52 | item 53 | ); 54 | else 55 | return NewTreeNode(NULL, NULL, item); 56 | } /* BottomUpTree() */ 57 | 58 | 59 | void DeleteTree(treeNode* tree) 60 | { 61 | if (tree->left != NULL) 62 | { 63 | DeleteTree(tree->left); 64 | DeleteTree(tree->right); 65 | } 66 | 67 | free(tree); 68 | } /* DeleteTree() */ 69 | 70 | 71 | int main(int argc, char* argv[]) 72 | { 73 | unsigned N, depth, minDepth, maxDepth, stretchDepth; 74 | treeNode *stretchTree, *longLivedTree, *tempTree; 75 | 76 | N = argc < 2 ? 16 : atol(argv[1]); 77 | 78 | minDepth = 4; 79 | 80 | if ((minDepth + 2) > N) 81 | maxDepth = minDepth + 2; 82 | else 83 | maxDepth = N; 84 | 85 | stretchDepth = maxDepth + 1; 86 | 87 | stretchTree = BottomUpTree(0, stretchDepth); 88 | /* printf */ 89 | /* ( */ 90 | /* "stretch tree of depth %u\t check: %li\n", */ 91 | /* stretchDepth, */ 92 | /* ItemCheck(stretchTree) */ 93 | /* ); */ 94 | 95 | DeleteTree(stretchTree); 96 | 97 | longLivedTree = BottomUpTree(0, maxDepth); 98 | 99 | for (depth = minDepth; depth <= maxDepth; depth += 2) 100 | { 101 | long i, iterations, check; 102 | 103 | iterations = pow(2, maxDepth - depth + minDepth); 104 | 105 | check = 0; 106 | 107 | for (i = 1; i <= iterations; i++) 108 | { 109 | tempTree = BottomUpTree(i, depth); 110 | check += ItemCheck(tempTree); 111 | DeleteTree(tempTree); 112 | 113 | tempTree = BottomUpTree(-i, depth); 114 | check += ItemCheck(tempTree); 115 | DeleteTree(tempTree); 116 | } /* for(i = 1...) */ 117 | 118 | /* printf */ 119 | /* ( */ 120 | /* "%li\t trees of depth %u\t check: %li\n", */ 121 | /* iterations * 2, */ 122 | /* depth, */ 123 | /* check */ 124 | /* ); */ 125 | } /* for(depth = minDepth...) */ 126 | 127 | /* printf */ 128 | /* ( */ 129 | /* "long lived tree of depth %u\t check: %li\n", */ 130 | /* maxDepth, */ 131 | /* ItemCheck(longLivedTree) */ 132 | /* ); */ 133 | 134 | return 0; 135 | } /* main() */ 136 | 137 | /****** 138 | build & benchmark results 139 | 140 | BUILD COMMANDS FOR: binarytrees.gcc 141 | 142 | Thu Sep 14 00:25:13 PDT 2006 143 | 144 | /usr/bin/gcc -pipe -Wall -O3 -fomit-frame-pointer -funroll-loops -march=pentium4 -lm binarytrees.c -o binarytrees.gcc_run 145 | 146 | ================================================================= 147 | COMMAND LINE (%A is single numeric argument): 148 | 149 | binarytrees.gcc_run %A 150 | N=16 151 | 152 | PROGRAM OUTPUT 153 | ============== 154 | stretch tree of depth 17 check: -1 155 | 131072 trees of depth 4 check: -131072 156 | 32768 trees of depth 6 check: -32768 157 | 8192 trees of depth 8 check: -8192 158 | 2048 trees of depth 10 check: -2048 159 | 512 trees of depth 12 check: -512 160 | 128 trees of depth 14 check: -128 161 | 32 trees of depth 16 check: -32 162 | long lived tree of depth 16 check: -1 163 | skinny tree of depth 17 check: 17 164 | *********/ 165 | -------------------------------------------------------------------------------- /x86model/cdriver/test/dummylm.s: -------------------------------------------------------------------------------- 1 | .file "dummylm.c" 2 | .text 3 | .align 32 4 | .globl acos 5 | .type acos, @function 6 | acos: 7 | pushl %ebp 8 | movl %esp, %ebp 9 | subl $8, %esp 10 | movl 8(%ebp), %eax 11 | movl %eax, -8(%ebp) 12 | movl 12(%ebp), %eax 13 | movl %eax, -4(%ebp) 14 | movl %ebp, %esp 15 | popl %ebp 16 | popl %ecx 17 | nacljmp %ecx 18 | .size acos, .-acos 19 | .align 32 20 | .globl asin 21 | .type asin, @function 22 | asin: 23 | pushl %ebp 24 | movl %esp, %ebp 25 | subl $8, %esp 26 | movl 8(%ebp), %eax 27 | movl %eax, -8(%ebp) 28 | movl 12(%ebp), %eax 29 | movl %eax, -4(%ebp) 30 | movl %ebp, %esp 31 | popl %ebp 32 | popl %ecx 33 | nacljmp %ecx 34 | .size asin, .-asin 35 | .align 32 36 | .globl atan 37 | .type atan, @function 38 | atan: 39 | pushl %ebp 40 | movl %esp, %ebp 41 | subl $8, %esp 42 | movl 8(%ebp), %eax 43 | movl %eax, -8(%ebp) 44 | movl 12(%ebp), %eax 45 | movl %eax, -4(%ebp) 46 | movl %ebp, %esp 47 | popl %ebp 48 | popl %ecx 49 | nacljmp %ecx 50 | .size atan, .-atan 51 | .align 32 52 | .globl atan2 53 | .type atan2, @function 54 | atan2: 55 | pushl %ebp 56 | movl %esp, %ebp 57 | subl $16, %esp 58 | movl 8(%ebp), %eax 59 | movl %eax, -8(%ebp) 60 | movl 12(%ebp), %eax 61 | movl %eax, -4(%ebp) 62 | movl 16(%ebp), %eax 63 | movl %eax, -16(%ebp) 64 | movl 20(%ebp), %eax 65 | movl %eax, -12(%ebp) 66 | movl %ebp, %esp 67 | popl %ebp 68 | popl %ecx 69 | nacljmp %ecx 70 | .size atan2, .-atan2 71 | .align 32 72 | .globl ceil 73 | .type ceil, @function 74 | ceil: 75 | pushl %ebp 76 | movl %esp, %ebp 77 | subl $8, %esp 78 | movl 8(%ebp), %eax 79 | movl %eax, -8(%ebp) 80 | movl 12(%ebp), %eax 81 | movl %eax, -4(%ebp) 82 | movl %ebp, %esp 83 | popl %ebp 84 | popl %ecx 85 | nacljmp %ecx 86 | .size ceil, .-ceil 87 | .align 32 88 | .globl cos 89 | .type cos, @function 90 | cos: 91 | pushl %ebp 92 | movl %esp, %ebp 93 | subl $8, %esp 94 | movl 8(%ebp), %eax 95 | movl %eax, -8(%ebp) 96 | movl 12(%ebp), %eax 97 | movl %eax, -4(%ebp) 98 | movl %ebp, %esp 99 | popl %ebp 100 | popl %ecx 101 | nacljmp %ecx 102 | .size cos, .-cos 103 | .align 32 104 | .globl cosh 105 | .type cosh, @function 106 | cosh: 107 | pushl %ebp 108 | movl %esp, %ebp 109 | subl $8, %esp 110 | movl 8(%ebp), %eax 111 | movl %eax, -8(%ebp) 112 | movl 12(%ebp), %eax 113 | movl %eax, -4(%ebp) 114 | movl %ebp, %esp 115 | popl %ebp 116 | popl %ecx 117 | nacljmp %ecx 118 | .size cosh, .-cosh 119 | .align 32 120 | .globl exp 121 | .type exp, @function 122 | exp: 123 | pushl %ebp 124 | movl %esp, %ebp 125 | subl $8, %esp 126 | movl 8(%ebp), %eax 127 | movl %eax, -8(%ebp) 128 | movl 12(%ebp), %eax 129 | movl %eax, -4(%ebp) 130 | movl %ebp, %esp 131 | popl %ebp 132 | popl %ecx 133 | nacljmp %ecx 134 | .size exp, .-exp 135 | .align 32 136 | .globl fabs 137 | .type fabs, @function 138 | fabs: 139 | pushl %ebp 140 | movl %esp, %ebp 141 | subl $8, %esp 142 | movl 8(%ebp), %eax 143 | movl %eax, -8(%ebp) 144 | movl 12(%ebp), %eax 145 | movl %eax, -4(%ebp) 146 | movl %ebp, %esp 147 | popl %ebp 148 | popl %ecx 149 | nacljmp %ecx 150 | .size fabs, .-fabs 151 | .align 32 152 | .globl floor 153 | .type floor, @function 154 | floor: 155 | pushl %ebp 156 | movl %esp, %ebp 157 | subl $8, %esp 158 | movl 8(%ebp), %eax 159 | movl %eax, -8(%ebp) 160 | movl 12(%ebp), %eax 161 | movl %eax, -4(%ebp) 162 | movl %ebp, %esp 163 | popl %ebp 164 | popl %ecx 165 | nacljmp %ecx 166 | .size floor, .-floor 167 | .align 32 168 | .globl fmod 169 | .type fmod, @function 170 | fmod: 171 | pushl %ebp 172 | movl %esp, %ebp 173 | subl $16, %esp 174 | movl 8(%ebp), %eax 175 | movl %eax, -8(%ebp) 176 | movl 12(%ebp), %eax 177 | movl %eax, -4(%ebp) 178 | movl 16(%ebp), %eax 179 | movl %eax, -16(%ebp) 180 | movl 20(%ebp), %eax 181 | movl %eax, -12(%ebp) 182 | movl %ebp, %esp 183 | popl %ebp 184 | popl %ecx 185 | nacljmp %ecx 186 | .size fmod, .-fmod 187 | .align 32 188 | .globl frexp 189 | .type frexp, @function 190 | frexp: 191 | pushl %ebp 192 | movl %esp, %ebp 193 | subl $8, %esp 194 | movl 8(%ebp), %eax 195 | movl %eax, -8(%ebp) 196 | movl 12(%ebp), %eax 197 | movl %eax, -4(%ebp) 198 | movl %ebp, %esp 199 | popl %ebp 200 | popl %ecx 201 | nacljmp %ecx 202 | .size frexp, .-frexp 203 | .align 32 204 | .globl ldexp 205 | .type ldexp, @function 206 | ldexp: 207 | pushl %ebp 208 | movl %esp, %ebp 209 | subl $8, %esp 210 | movl 8(%ebp), %eax 211 | movl %eax, -8(%ebp) 212 | movl 12(%ebp), %eax 213 | movl %eax, -4(%ebp) 214 | movl %ebp, %esp 215 | popl %ebp 216 | popl %ecx 217 | nacljmp %ecx 218 | .size ldexp, .-ldexp 219 | .align 32 220 | .globl log 221 | .type log, @function 222 | log: 223 | pushl %ebp 224 | movl %esp, %ebp 225 | subl $8, %esp 226 | movl 8(%ebp), %eax 227 | movl %eax, -8(%ebp) 228 | movl 12(%ebp), %eax 229 | movl %eax, -4(%ebp) 230 | movl %ebp, %esp 231 | popl %ebp 232 | popl %ecx 233 | nacljmp %ecx 234 | .size log, .-log 235 | .align 32 236 | .globl log10 237 | .type log10, @function 238 | log10: 239 | pushl %ebp 240 | movl %esp, %ebp 241 | subl $8, %esp 242 | movl 8(%ebp), %eax 243 | movl %eax, -8(%ebp) 244 | movl 12(%ebp), %eax 245 | movl %eax, -4(%ebp) 246 | movl %ebp, %esp 247 | popl %ebp 248 | popl %ecx 249 | nacljmp %ecx 250 | .size log10, .-log10 251 | .align 32 252 | .globl modf 253 | .type modf, @function 254 | modf: 255 | pushl %ebp 256 | movl %esp, %ebp 257 | subl $8, %esp 258 | movl 8(%ebp), %eax 259 | movl %eax, -8(%ebp) 260 | movl 12(%ebp), %eax 261 | movl %eax, -4(%ebp) 262 | movl %ebp, %esp 263 | popl %ebp 264 | popl %ecx 265 | nacljmp %ecx 266 | .size modf, .-modf 267 | .align 32 268 | .globl pow 269 | .type pow, @function 270 | pow: 271 | pushl %ebp 272 | movl %esp, %ebp 273 | subl $16, %esp 274 | movl 8(%ebp), %eax 275 | movl %eax, -8(%ebp) 276 | movl 12(%ebp), %eax 277 | movl %eax, -4(%ebp) 278 | movl 16(%ebp), %eax 279 | movl %eax, -16(%ebp) 280 | movl 20(%ebp), %eax 281 | movl %eax, -12(%ebp) 282 | movl %ebp, %esp 283 | popl %ebp 284 | popl %ecx 285 | nacljmp %ecx 286 | .size pow, .-pow 287 | .align 32 288 | .globl sin 289 | .type sin, @function 290 | sin: 291 | pushl %ebp 292 | movl %esp, %ebp 293 | subl $8, %esp 294 | movl 8(%ebp), %eax 295 | movl %eax, -8(%ebp) 296 | movl 12(%ebp), %eax 297 | movl %eax, -4(%ebp) 298 | movl %ebp, %esp 299 | popl %ebp 300 | popl %ecx 301 | nacljmp %ecx 302 | .size sin, .-sin 303 | .align 32 304 | .globl sinh 305 | .type sinh, @function 306 | sinh: 307 | pushl %ebp 308 | movl %esp, %ebp 309 | subl $8, %esp 310 | movl 8(%ebp), %eax 311 | movl %eax, -8(%ebp) 312 | movl 12(%ebp), %eax 313 | movl %eax, -4(%ebp) 314 | movl %ebp, %esp 315 | popl %ebp 316 | popl %ecx 317 | nacljmp %ecx 318 | .size sinh, .-sinh 319 | .align 32 320 | .globl sqrt 321 | .type sqrt, @function 322 | sqrt: 323 | pushl %ebp 324 | movl %esp, %ebp 325 | subl $8, %esp 326 | movl 8(%ebp), %eax 327 | movl %eax, -8(%ebp) 328 | movl 12(%ebp), %eax 329 | movl %eax, -4(%ebp) 330 | movl %ebp, %esp 331 | popl %ebp 332 | popl %ecx 333 | nacljmp %ecx 334 | .size sqrt, .-sqrt 335 | .align 32 336 | .globl tan 337 | .type tan, @function 338 | tan: 339 | pushl %ebp 340 | movl %esp, %ebp 341 | subl $8, %esp 342 | movl 8(%ebp), %eax 343 | movl %eax, -8(%ebp) 344 | movl 12(%ebp), %eax 345 | movl %eax, -4(%ebp) 346 | movl %ebp, %esp 347 | popl %ebp 348 | popl %ecx 349 | nacljmp %ecx 350 | .size tan, .-tan 351 | .align 32 352 | .globl tanh 353 | .type tanh, @function 354 | tanh: 355 | pushl %ebp 356 | movl %esp, %ebp 357 | subl $8, %esp 358 | movl 8(%ebp), %eax 359 | movl %eax, -8(%ebp) 360 | movl 12(%ebp), %eax 361 | movl %eax, -4(%ebp) 362 | movl %ebp, %esp 363 | popl %ebp 364 | popl %ecx 365 | nacljmp %ecx 366 | .size tanh, .-tanh 367 | .section .rodata 368 | .align 4 369 | .LC0: 370 | .long 2143289344 371 | .ident "GCC: (GNU) 4.4.3 2011-05-27 (Native Client r5492, Git Commit 2ad889d442a4c40d2682f32738dca56a5a087605)" 372 | .section .note.GNU-stack,"",@progbits 373 | -------------------------------------------------------------------------------- /x86model/cdriver/test/fannkuch.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The Computer Lannguage Shootout 3 | * http://shootout.alioth.debian.org/ 4 | * Contributed by Heiner Marxen 5 | * 6 | * "fannkuch" for C gcc 7 | * 8 | * $Id: fannkuch-gcc.code,v 1.33 2006/02/25 16:38:58 igouy-guest Exp $ 9 | */ 10 | 11 | //#include 12 | #include 13 | 14 | #define Int int 15 | #define Aint int 16 | 17 | static long 18 | fannkuch( int n ) 19 | { 20 | Aint* perm; 21 | Aint* perm1; 22 | Aint* count; 23 | long flips; 24 | long flipsMax; 25 | Int r; 26 | Int i; 27 | Int k; 28 | Int didpr; 29 | const Int n1 = n - 1; 30 | 31 | if( n < 1 ) return 0; 32 | 33 | perm = calloc(n, sizeof(*perm )); 34 | perm1 = calloc(n, sizeof(*perm1)); 35 | count = calloc(n, sizeof(*count)); 36 | 37 | for( i=0 ; i k>0 */ 59 | Int j; 60 | for( i=1, j=k-1 ; i 0 ) { 91 | break; 92 | } 93 | ++r; 94 | } 95 | } 96 | } 97 | 98 | int 99 | main( int argc, char* argv[] ) 100 | { 101 | int n = (argc>1) ? atoi(argv[1]) : 10; 102 | 103 | //printf("Pfannkuchen(%d) = %ld\n", n, fannkuch(n)); 104 | return 0; 105 | } 106 | /***** 107 | build & benchmark results 108 | 109 | BUILD COMMANDS FOR: fannkuch.gcc 110 | 111 | Thu Sep 14 17:44:44 PDT 2006 112 | 113 | /usr/bin/gcc -pipe -Wall -O3 -fomit-frame-pointer -funroll-loops -march=pentium4 fannkuch.c -o fannkuch.gcc_run 114 | 115 | ================================================================= 116 | COMMAND LINE (%A is single numeric argument): 117 | 118 | fannkuch.gcc_run %A 119 | N=10 120 | 121 | PROGRAM OUTPUT 122 | ============== 123 | 12345678910 124 | 21345678910 125 | 23145678910 126 | 32145678910 127 | 31245678910 128 | 13245678910 129 | 23415678910 130 | 32415678910 131 | 34215678910 132 | 43215678910 133 | 42315678910 134 | 24315678910 135 | 34125678910 136 | 43125678910 137 | 41325678910 138 | 14325678910 139 | 13425678910 140 | 31425678910 141 | 41235678910 142 | 14235678910 143 | 12435678910 144 | 21435678910 145 | 24135678910 146 | 42135678910 147 | 23451678910 148 | 32451678910 149 | 34251678910 150 | 43251678910 151 | 42351678910 152 | 24351678910 153 | Pfannkuchen(10) = 38 154 | *****/ 155 | -------------------------------------------------------------------------------- /x86model/cdriver/test/fft.c: -------------------------------------------------------------------------------- 1 | /* 2 | C Program: Test_Fast_Fourier_Transform_in_Double_Precision (TFFTDP.c) 3 | by: Dave Edelblute, edelblut@cod.nosc.mil, 05 Jan 1993 4 | */ 5 | 6 | //#include 7 | #include 8 | //#include 9 | 10 | #ifndef PI 11 | #define PI 3.14159265358979323846 12 | #endif 13 | 14 | /********************************************************/ 15 | /* A Duhamel-Hollman split-radix dif fft */ 16 | /* Ref: Electronics Letters, Jan. 5, 1984 */ 17 | /* Complex input and output data in arrays x and y */ 18 | /* Length is n. */ 19 | /********************************************************/ 20 | 21 | int dfft(double x[], double y[], int np) 22 | { 23 | double *px,*py; 24 | int i,j,k,m,n,i0,i1,i2,i3,is,id,n1,n2,n4; 25 | double a,e,a3,cc1,ss1,cc3,ss3,r1,r2,s1,s2,s3,xt,tpi; 26 | 27 | px = x - 1; 28 | py = y - 1; 29 | i = 2; 30 | m = 1; 31 | 32 | while (i < np) 33 | { 34 | i = i+i; 35 | m = m+1; 36 | } 37 | 38 | n = i; 39 | 40 | if (n != np) { 41 | for (i = np+1; i <= n; i++) { 42 | px[i] = 0.0; 43 | py[i] = 0.0; 44 | } 45 | /*printf("nuse %d point fft",n); */ 46 | } 47 | 48 | n2 = n+n; 49 | tpi = 2.0 * PI; 50 | for (k = 1; k <= m-1; k++ ) { 51 | n2 = n2 / 2; 52 | n4 = n2 / 4; 53 | e = tpi / (double)n2; 54 | a = 0.0; 55 | 56 | for (j = 1; j<= n4 ; j++) { 57 | a3 = 3.0 * a; 58 | cc1 = cos(a); 59 | ss1 = sin(a); 60 | 61 | cc3 = cos(a3); 62 | ss3 = sin(a3); 63 | a = e * (double)j; 64 | is = j; 65 | id = 2 * n2; 66 | 67 | while ( is < n ) { 68 | for (i0 = is; i0 <= n-1; i0 = i0 + id) { 69 | i1 = i0 + n4; 70 | i2 = i1 + n4; 71 | i3 = i2 + n4; 72 | r1 = px[i0] - px[i2]; 73 | px[i0] = px[i0] + px[i2]; 74 | r2 = px[i1] - px[i3]; 75 | px[i1] = px[i1] + px[i3]; 76 | s1 = py[i0] - py[i2]; 77 | py[i0] = py[i0] + py[i2]; 78 | s2 = py[i1] - py[i3]; 79 | py[i1] = py[i1] + py[i3]; 80 | s3 = r1 - s2; r1 = r1 + s2; 81 | s2 = r2 - s1; r2 = r2 + s1; 82 | px[i2] = r1*cc1 - s2*ss1; 83 | py[i2] = -s2*cc1 - r1*ss1; 84 | px[i3] = s3*cc3 + r2*ss3; 85 | py[i3] = r2*cc3 - s3*ss3; 86 | } 87 | is = 2 * id - n2 + j; 88 | id = 4 * id; 89 | } 90 | } 91 | } 92 | 93 | /************************************/ 94 | /* Last stage, length=2 butterfly */ 95 | /************************************/ 96 | is = 1; 97 | id = 4; 98 | 99 | while ( is < n) { 100 | for (i0 = is; i0 <= n; i0 = i0 + id) { 101 | i1 = i0 + 1; 102 | r1 = px[i0]; 103 | px[i0] = r1 + px[i1]; 104 | px[i1] = r1 - px[i1]; 105 | r1 = py[i0]; 106 | py[i0] = r1 + py[i1]; 107 | py[i1] = r1 - py[i1]; 108 | } 109 | is = 2*id - 1; 110 | id = 4 * id; 111 | } 112 | 113 | /*************************/ 114 | /* Bit reverse counter */ 115 | /*************************/ 116 | j = 1; 117 | n1 = n - 1; 118 | 119 | for (i = 1; i <= n1; i++) { 120 | if (i < j) { 121 | xt = px[j]; 122 | px[j] = px[i]; 123 | px[i] = xt; 124 | xt = py[j]; 125 | py[j] = py[i]; 126 | py[i] = xt; 127 | } 128 | 129 | k = n / 2; 130 | while (k < j) { 131 | j = j - k; 132 | k = k / 2; 133 | } 134 | j = j + k; 135 | } 136 | 137 | /* 138 | for (i = 1; i<=16; i++) printf("%d %g %gn",i,px[i],py[i]); 139 | */ 140 | 141 | return(n); 142 | } 143 | 144 | /* Test harness */ 145 | 146 | double * xr, * xi; 147 | 148 | int main(int argc, char ** argv) 149 | { 150 | int n, np, npm, n2, i, j; 151 | double enp, t, y, z, zr, zi, zm, a; 152 | double * pxr, * pxi; 153 | 154 | if (argc >= 2) n = atoi(argv[1]); else n = 18; 155 | np = 1 << n; 156 | enp = np; 157 | npm = np / 2 - 1; 158 | t = PI / enp; 159 | xr = calloc(np, sizeof(double)); 160 | xi = calloc(np, sizeof(double)); 161 | pxr = xr; 162 | pxi = xi; 163 | *pxr = (enp - 1.0) * 0.5; 164 | *pxi = 0.0; 165 | n2 = np / 2; 166 | *(pxr+n2) = -0.5; 167 | *(pxi+n2) = 0.0; 168 | for (i = 1; i <= npm; i++) { 169 | j = np - i; 170 | *(pxr+i) = -0.5; 171 | *(pxr+j) = -0.5; 172 | z = t * (double)i; 173 | y = -0.5*(cos(z)/sin(z)); 174 | *(pxi+i) = y; 175 | *(pxi+j) = -y; 176 | } 177 | dfft(xr,xi,np); 178 | zr = 0.0; 179 | zi = 0.0; 180 | npm = np-1; 181 | for (i = 0; i <= npm; i++ ) { 182 | a = fabs(pxr[i] - i); 183 | if (zr < a) zr = a; 184 | a = fabs(pxi[i]); 185 | if (zi < a) zi = a; 186 | } 187 | zm = zr; 188 | if (zr < zi) zm = zi; 189 | //printf("%d points, %s\n", np, zm < 1e-9 ? "result OK" : "WRONG result"); 190 | return 0; 191 | } 192 | -------------------------------------------------------------------------------- /x86model/cdriver/test/fib.c: -------------------------------------------------------------------------------- 1 | #include 2 | //#include 3 | 4 | int fib(int n) 5 | { 6 | if (n < 2) 7 | return 1; 8 | else 9 | return fib(n-1) + fib(n-2); 10 | } 11 | 12 | int blob() { return 0; } 13 | 14 | int main(int argc, char ** argv) 15 | { 16 | int n, r; 17 | //if (argc >= 2) n = atoi(argv[1]); else n = 36; 18 | r = fib(8); 19 | //printf("fib(%d) = %d\n", n, r); 20 | return blob(); 21 | } 22 | -------------------------------------------------------------------------------- /x86model/cdriver/test/integr.c: -------------------------------------------------------------------------------- 1 | #include 2 | //#include 3 | 4 | static double square(double x) 5 | { 6 | return x * x; 7 | } 8 | 9 | static double integr(double (*f)(double), double low, double high, int n) 10 | { 11 | double h, x, s; 12 | int i; 13 | 14 | h = (high - low) / n; 15 | s = 0; 16 | for (i = n, x = low; i > 0; i--, x += h) s += f(x); 17 | return s * h; 18 | } 19 | 20 | double test(int n) 21 | { 22 | return integr(square, 0.0, 1.0, n); 23 | } 24 | 25 | int main(int argc, char ** argv) 26 | { 27 | int n; double r; 28 | if (argc >= 2) n = atoi(argv[1]); else n = 10000000; 29 | r = test(n); 30 | //printf("integr(square, 0.0, 1.0, %d) = %g\n", n, r); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /x86model/cdriver/test/lists.c: -------------------------------------------------------------------------------- 1 | /* List manipulations */ 2 | 3 | //#include 4 | #include 5 | #include 6 | 7 | struct list { int hd; struct list * tl; }; 8 | 9 | struct list * buildlist(int n) 10 | { 11 | struct list * r; 12 | if (n < 0) return NULL; 13 | r = malloc(sizeof(struct list)); 14 | r->hd = n; 15 | r->tl = buildlist(n - 1); 16 | return r; 17 | } 18 | 19 | struct list * reverselist (struct list * l) 20 | { 21 | struct list * r, * r2; 22 | for (r = NULL; l != NULL; l = l->tl) { 23 | r2 = malloc(sizeof(struct list)); 24 | r2->hd = l->hd; 25 | r2->tl = r; 26 | r = r2; 27 | } 28 | return r; 29 | } 30 | 31 | struct list * reverse_inplace(struct list * l) 32 | { 33 | struct list * prev, * next; 34 | 35 | prev = NULL; 36 | while (l != NULL) { 37 | next = l->tl; 38 | l->tl = prev; 39 | prev = l; 40 | l = next; 41 | } 42 | return prev; 43 | } 44 | 45 | int checklist(int n, struct list * l) 46 | { 47 | int i; 48 | for (i = 0; i <= n; i++) { 49 | if (l == NULL) return 0; 50 | if (l->hd != i) return 0; 51 | l = l->tl; 52 | } 53 | return (l == NULL); 54 | } 55 | 56 | int main(int argc, char ** argv) 57 | { 58 | int n, niter, i; 59 | struct list * l; 60 | 61 | if (argc >= 2) n = atoi(argv[1]); else n = 1000; 62 | if (argc >= 3) niter = atoi(argv[1]); else niter = 100000; 63 | l = buildlist(n); 64 | if (checklist(n, reverselist(l))) { 65 | //printf("OK\n"); 66 | } else { 67 | //printf("Bug!\n"); 68 | return 2; 69 | } 70 | for (i = 0; i < 2*niter + 1; i++) { 71 | l = reverse_inplace(l); 72 | } 73 | if (checklist(n, l)) { 74 | //printf("OK\n"); 75 | } else { 76 | //printf("Bug!\n"); 77 | return 2; 78 | } 79 | return 0; 80 | } 81 | 82 | -------------------------------------------------------------------------------- /x86model/cdriver/test/mandelbrot.c: -------------------------------------------------------------------------------- 1 | /* The Computer Language Shootout 2 | http://shootout.alioth.debian.org/ 3 | 4 | contributed by Greg Buchholz 5 | 6 | for the debian (AMD) machine... 7 | compile flags: -O3 -ffast-math -march=athlon-xp -funroll-loops 8 | 9 | for the gp4 (Intel) machine... 10 | compile flags: -O3 -ffast-math -march=pentium4 -funroll-loops 11 | */ 12 | 13 | //#include 14 | #include 15 | 16 | int main (int argc, char **argv) 17 | { 18 | int w, h, bit_num = 0; 19 | char byte_acc = 0; 20 | int i, iter = 50; 21 | double x, y, limit = 2.0; 22 | double Zr, Zi, Cr, Ci, Tr, Ti; 23 | 24 | if (argc < 2) { 25 | w = h = 3000; 26 | } else { 27 | w = h = atoi(argv[1]); 28 | } 29 | 30 | //printf("P4\n%d %d\n",w,h); 31 | 32 | for(y=0;y 10 | //#include 11 | #include 12 | 13 | #define pi 3.141592653589793 14 | #define solar_mass (4 * pi * pi) 15 | #define days_per_year 365.24 16 | 17 | struct planet { 18 | double x, y, z; 19 | double vx, vy, vz; 20 | double mass; 21 | }; 22 | 23 | void advance(int nbodies, struct planet * bodies, double dt) 24 | { 25 | int i, j; 26 | 27 | for (i = 0; i < nbodies; i++) { 28 | struct planet * b = &(bodies[i]); 29 | for (j = i + 1; j < nbodies; j++) { 30 | struct planet * b2 = &(bodies[j]); 31 | double dx = b->x - b2->x; 32 | double dy = b->y - b2->y; 33 | double dz = b->z - b2->z; 34 | double distance = sqrt(dx * dx + dy * dy + dz * dz); 35 | double mag = dt / (distance * distance * distance); 36 | b->vx -= dx * b2->mass * mag; 37 | b->vy -= dy * b2->mass * mag; 38 | b->vz -= dz * b2->mass * mag; 39 | b2->vx += dx * b->mass * mag; 40 | b2->vy += dy * b->mass * mag; 41 | b2->vz += dz * b->mass * mag; 42 | } 43 | } 44 | for (i = 0; i < nbodies; i++) { 45 | struct planet * b = &(bodies[i]); 46 | b->x += dt * b->vx; 47 | b->y += dt * b->vy; 48 | b->z += dt * b->vz; 49 | } 50 | } 51 | 52 | double energy(int nbodies, struct planet * bodies) 53 | { 54 | double e; 55 | int i, j; 56 | 57 | e = 0.0; 58 | for (i = 0; i < nbodies; i++) { 59 | struct planet * b = &(bodies[i]); 60 | e += 0.5 * b->mass * (b->vx * b->vx + b->vy * b->vy + b->vz * b->vz); 61 | for (j = i + 1; j < nbodies; j++) { 62 | struct planet * b2 = &(bodies[j]); 63 | double dx = b->x - b2->x; 64 | double dy = b->y - b2->y; 65 | double dz = b->z - b2->z; 66 | double distance = sqrt(dx * dx + dy * dy + dz * dz); 67 | e -= (b->mass * b2->mass) / distance; 68 | } 69 | } 70 | return e; 71 | } 72 | 73 | void offset_momentum(int nbodies, struct planet * bodies) 74 | { 75 | double px = 0.0, py = 0.0, pz = 0.0; 76 | int i; 77 | for (i = 0; i < nbodies; i++) { 78 | px += bodies[i].vx * bodies[i].mass; 79 | py += bodies[i].vy * bodies[i].mass; 80 | pz += bodies[i].vz * bodies[i].mass; 81 | } 82 | bodies[0].vx = - px / solar_mass; 83 | bodies[0].vy = - py / solar_mass; 84 | bodies[0].vz = - pz / solar_mass; 85 | } 86 | 87 | #define NBODIES 5 88 | struct planet bodies[NBODIES] = { 89 | { /* sun */ 90 | 0, 0, 0, 0, 0, 0, 1.0 /*solar_mass*/ 91 | }, 92 | { /* jupiter */ 93 | 4.84143144246472090e+00, 94 | -1.16032004402742839e+00, 95 | -1.03622044471123109e-01, 96 | 1.66007664274403694e-03 /* * days_per_year */, 97 | 7.69901118419740425e-03 /* * days_per_year */, 98 | -6.90460016972063023e-05 /* * days_per_year */, 99 | 9.54791938424326609e-04 /* * solar_mass */ 100 | }, 101 | { /* saturn */ 102 | 8.34336671824457987e+00, 103 | 4.12479856412430479e+00, 104 | -4.03523417114321381e-01, 105 | -2.76742510726862411e-03 /* * days_per_year */, 106 | 4.99852801234917238e-03 /* * days_per_year */, 107 | 2.30417297573763929e-05 /* * days_per_year */, 108 | 2.85885980666130812e-04 /* * solar_mass */ 109 | }, 110 | { /* uranus */ 111 | 1.28943695621391310e+01, 112 | -1.51111514016986312e+01, 113 | -2.23307578892655734e-01, 114 | 2.96460137564761618e-03 /* * days_per_year */, 115 | 2.37847173959480950e-03 /* * days_per_year */, 116 | -2.96589568540237556e-05 /* * days_per_year */, 117 | 4.36624404335156298e-05 /* * solar_mass */ 118 | }, 119 | { /* neptune */ 120 | 1.53796971148509165e+01, 121 | -2.59193146099879641e+01, 122 | 1.79258772950371181e-01, 123 | 2.68067772490389322e-03 /* * days_per_year */, 124 | 1.62824170038242295e-03 /* * days_per_year */, 125 | -9.51592254519715870e-05 /* * days_per_year */, 126 | 5.15138902046611451e-05 /* * solar_mass */ 127 | } 128 | }; 129 | 130 | void setup_bodies(void) 131 | { 132 | int i; 133 | for (i = 0; i < NBODIES; i++) { 134 | bodies[i].vx *= days_per_year; 135 | bodies[i].vy *= days_per_year; 136 | bodies[i].vz *= days_per_year; 137 | bodies[i].mass *= solar_mass; 138 | } 139 | } 140 | 141 | int main(int argc, char ** argv) 142 | { 143 | int n = argc < 2 ? 20000000 : atoi(argv[1]); 144 | int i; 145 | 146 | setup_bodies(); 147 | offset_momentum(NBODIES, bodies); 148 | //printf ("%.9f\n", energy(NBODIES, bodies)); 149 | for (i = 1; i <= n; i++) 150 | advance(NBODIES, bodies, 0.01); 151 | //printf ("%.9f\n", energy(NBODIES, bodies)); 152 | return 0; 153 | } 154 | 155 | /*** 156 | build & benchmark results 157 | 158 | BUILD COMMANDS FOR: nbody.gcc 159 | 160 | Thu Jul 27 22:22:05 PDT 2006 161 | 162 | /usr/bin/gcc -pipe -Wall -O3 -fomit-frame-pointer -funroll-loops -march=pentium4 -lm nbody.c -o nbody.gcc_run 163 | 164 | ================================================================= 165 | COMMAND LINE (%A is single numeric argument): 166 | 167 | nbody.gcc_run %A 168 | 169 | N=200000 2000000 20000000 170 | PROGRAM OUTPUT 171 | ============== 172 | -0.169075164 173 | -0.169031665 174 | ***/ 175 | -------------------------------------------------------------------------------- /x86model/cdriver/test/nsieve.c: -------------------------------------------------------------------------------- 1 | // The Computer Language Shootout 2 | // http://shootout.alioth.debian.org/ 3 | // Precedent C entry modified by bearophile for speed and size, 31 Jan 2006 4 | // Compile with: -O3 -s -std=c99 -fomit-frame-pointer 5 | 6 | //#include 7 | #include 8 | #include 9 | 10 | typedef unsigned char boolean; 11 | 12 | 13 | static void nsieve(int m) { 14 | unsigned int count = 0, i, j; 15 | boolean * flags = (boolean *) malloc(m * sizeof(boolean)); 16 | memset(flags, 1, m); 17 | 18 | for (i = 2; i < m; ++i) 19 | if (flags[i]) { 20 | ++count; 21 | for (j = i << 1; j < m; j += i) 22 | if (flags[j]) flags[j] = 0; 23 | } 24 | 25 | free(flags); 26 | //printf("Primes up to %8u %8u\n", m, count); 27 | } 28 | 29 | int main(int argc, char * argv[]) { 30 | int m = argc < 2 ? 9 : atoi(argv[1]); 31 | int i; 32 | for (i = 0; i < 3; i++) 33 | nsieve(10000 << (m-i)); 34 | return 0; 35 | } 36 | 37 | /******** 38 | build & benchmark results 39 | 40 | BUILD COMMANDS FOR: nsieve.gcc 41 | 42 | Thu Sep 14 20:51:46 PDT 2006 43 | 44 | /usr/bin/gcc -pipe -Wall -O3 -fomit-frame-pointer -funroll-loops -march=pentium4 -s -std=c99 nsieve.c -o nsieve.gcc_run 45 | 46 | ================================================================= 47 | COMMAND LINE (%A is single numeric argument): 48 | 49 | nsieve.gcc_run %A 50 | N=9 51 | 52 | PROGRAM OUTPUT 53 | ============== 54 | Primes up to 5120000 356244 55 | Primes up to 2560000 187134 56 | Primes up to 1280000 98610 57 | *******/ 58 | -------------------------------------------------------------------------------- /x86model/cdriver/test/nsievebits.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The Great Computer Language Shootout 3 | * http://shootout.alioth.debian.org/ 4 | * 5 | * Written by Dima Dorfman, 2004 6 | * Compile: gcc -std=c99 -O2 -o nsieve_bits_gcc nsieve_bits.c 7 | */ 8 | 9 | //#include 10 | #include 11 | #include 12 | 13 | typedef unsigned int bits; 14 | #define NBITS (8 * sizeof(bits)) 15 | 16 | static unsigned int 17 | nsieve(unsigned int m) 18 | { 19 | unsigned int count, i, j; 20 | bits * a; 21 | a = malloc((m / NBITS) * sizeof(bits)); 22 | memset(a, (1 << 8) - 1, (m / NBITS) * sizeof(bits)); 23 | count = 0; 24 | for (i = 2; i < m; ++i) 25 | if (a[i / NBITS] & (1 << i % NBITS)) { 26 | for (j = i + i; j < m; j += i) 27 | a[j / NBITS] &= ~(1 << j % NBITS); 28 | ++count; 29 | } 30 | return (count); 31 | } 32 | 33 | static void 34 | test(unsigned int n) 35 | { 36 | unsigned int count, m; 37 | 38 | m = (1 << n) * 10000; 39 | count = nsieve(m); 40 | //printf("Primes up to %8u %8u\n", m, count); 41 | } 42 | 43 | int 44 | main(int ac, char **av) 45 | { 46 | unsigned int n; 47 | 48 | n = ac < 2 ? 9 : atoi(av[1]); 49 | test(n); 50 | if (n >= 1) 51 | test(n - 1); 52 | if (n >= 2) 53 | test(n - 2); 54 | exit(0); 55 | } 56 | /**** 57 | build & benchmark results 58 | 59 | BUILD COMMANDS FOR: nsievebits.gcc 60 | 61 | Fri Sep 15 06:30:15 PDT 2006 62 | 63 | /usr/bin/gcc -pipe -Wall -O3 -fomit-frame-pointer -funroll-loops -march=pentium4 nsievebits.c -o nsievebits.gcc_run 64 | 65 | ================================================================= 66 | COMMAND LINE (%A is single numeric argument): 67 | 68 | nsievebits.gcc_run %A 69 | 70 | 71 | PROGRAM OUTPUT 72 | ============== 73 | Primes up to 5120000 356244 74 | Primes up to 2560000 187134 75 | Primes up to 1280000 98610 76 | *****/ 77 | -------------------------------------------------------------------------------- /x86model/cdriver/test/perlin.c: -------------------------------------------------------------------------------- 1 | // perlin noise, derived from the Java reference implementation at 2 | // http://mrl.nyu.edu/~perlin/noise/ 3 | 4 | //#include 5 | //#include 6 | 7 | static int p[512]; 8 | 9 | static int permutation[256] = { 151,160,137,91,90,15, 10 | 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, 11 | 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, 12 | 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, 13 | 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, 14 | 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, 15 | 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, 16 | 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, 17 | 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, 18 | 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, 19 | 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, 20 | 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, 21 | 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 22 | }; 23 | 24 | static double fade(double t) { return t * t * t * (t * (t * 6 - 15) + 10); } 25 | 26 | static double lerp(double t, double a, double b) { return a + t * (b - a); } 27 | 28 | static double grad(int hash, double x, double y, double z) { 29 | int h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE 30 | double u = h<8 ? x : y, // INTO 12 GRADIENT DIRECTIONS. 31 | v = h<4 ? y : h==12||h==14 ? x : z; 32 | return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v); 33 | } 34 | 35 | static double noise(double x, double y, double z) { 36 | int X = (int)floor(x) & 255, // FIND UNIT CUBE THAT 37 | Y = (int)floor(y) & 255, // CONTAINS POINT. 38 | Z = (int)floor(z) & 255; 39 | x -= floor(x); // FIND RELATIVE X,Y,Z 40 | y -= floor(y); // OF POINT IN CUBE. 41 | z -= floor(z); 42 | double u = fade(x), // COMPUTE FADE CURVES 43 | v = fade(y), // FOR EACH OF X,Y,Z. 44 | w = fade(z); 45 | int A = p[X ]+Y, AA = p[A]+Z, AB = p[A+1]+Z, // HASH COORDINATES OF 46 | B = p[X+1]+Y, BA = p[B]+Z, BB = p[B+1]+Z; // THE 8 CUBE CORNERS, 47 | 48 | return lerp(w, lerp(v, lerp(u, grad(p[AA ], x , y , z ), // AND ADD 49 | grad(p[BA ], x-1, y , z )), // BLENDED 50 | lerp(u, grad(p[AB ], x , y-1, z ), // RESULTS 51 | grad(p[BB ], x-1, y-1, z ))),// FROM 8 52 | lerp(v, lerp(u, grad(p[AA+1], x , y , z-1 ), // CORNERS 53 | grad(p[BA+1], x-1, y , z-1 )), // OF CUBE 54 | lerp(u, grad(p[AB+1], x , y-1, z-1 ), 55 | grad(p[BB+1], x-1, y-1, z-1 )))); 56 | } 57 | 58 | static void init(void) { 59 | int i = 0; 60 | for (i=0; i < 256 ; i++) 61 | p[256+i] = p[i] = permutation[i]; 62 | } 63 | 64 | int main(int argc, char ** argv) { 65 | init(); 66 | 67 | double x, y, z, sum = 0.0; 68 | for (x = -11352.57; x < 23561.57; x += .1235) 69 | for (y = -346.1235; y < 124.124; y += 1.4325) 70 | for (z = -156.235; y < 23.2345; y += 2.45) 71 | sum += noise(x, y, z); 72 | 73 | //printf("%.4e\n", sum); 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /x86model/cdriver/test/qsort.c: -------------------------------------------------------------------------------- 1 | //#include 2 | //#include 3 | //#include 4 | 5 | void quicksort(int lo, int hi, int base[]) 6 | { 7 | int i,j; 8 | int pivot,temp; 9 | 10 | if (lolo && base[j]>=pivot) j--; 14 | if (i& /dev/null 8 | if test -e `basename $i .c`.nexe 9 | then 10 | echo $i: compilation successfull 11 | ncval `basename $i .c`.nexe | grep RESULT 12 | ncval `basename $i .c`.nexe --dfa | grep RESULT 13 | else echo $i: failure to compile 14 | fi 15 | echo 16 | done 17 | 18 | -------------------------------------------------------------------------------- /x86model/cdriver/test/sha1.c: -------------------------------------------------------------------------------- 1 | /* SHA-1 cryptographic hash function */ 2 | /* Ref: Handbook of Applied Cryptography, section 9.4.2, algorithm 9.53 */ 3 | 4 | #include 5 | //#include 6 | #include 7 | 8 | typedef unsigned int u32; 9 | 10 | struct SHA1Context { 11 | u32 state[5]; 12 | u32 length[2]; 13 | int numbytes; 14 | unsigned char buffer[64]; 15 | }; 16 | 17 | #define rol1(x) (((x) << 1) | ((x) >> 31)) 18 | #define rol5(x) (((x) << 5) | ((x) >> 27)) 19 | #define rol30(x) (((x) << 30) | ((x) >> 2)) 20 | 21 | static int arch_big_endian; 22 | 23 | static void SHA1_copy_and_swap(void * src, void * dst, int numwords) 24 | { 25 | if (arch_big_endian) { 26 | memcpy(dst, src, numwords * sizeof(u32)); 27 | } else { 28 | unsigned char * s, * d; 29 | unsigned char a, b; 30 | for (s = src, d = dst; numwords > 0; s += 4, d += 4, numwords--) { 31 | a = s[0]; 32 | b = s[1]; 33 | d[0] = s[3]; 34 | d[1] = s[2]; 35 | d[2] = b; 36 | d[3] = a; 37 | } 38 | } 39 | } 40 | 41 | #define F(x,y,z) ( z ^ (x & (y ^ z) ) ) 42 | #define G(x,y,z) ( (x & y) | (z & (x | y) ) ) 43 | #define H(x,y,z) ( x ^ y ^ z ) 44 | 45 | #define Y1 0x5A827999U 46 | #define Y2 0x6ED9EBA1U 47 | #define Y3 0x8F1BBCDCU 48 | #define Y4 0xCA62C1D6U 49 | 50 | static void SHA1_transform(struct SHA1Context * ctx) 51 | { 52 | int i; 53 | register u32 a, b, c, d, e, t; 54 | u32 data[80]; 55 | 56 | /* Convert buffer data to 16 big-endian integers */ 57 | SHA1_copy_and_swap(ctx->buffer, data, 16); 58 | 59 | /* Expand into 80 integers */ 60 | for (i = 16; i < 80; i++) { 61 | t = data[i-3] ^ data[i-8] ^ data[i-14] ^ data[i-16]; 62 | data[i] = rol1(t); 63 | } 64 | 65 | /* Initialize working variables */ 66 | a = ctx->state[0]; 67 | b = ctx->state[1]; 68 | c = ctx->state[2]; 69 | d = ctx->state[3]; 70 | e = ctx->state[4]; 71 | 72 | /* Perform rounds */ 73 | for (i = 0; i < 20; i++) { 74 | t = F(b, c, d) + Y1 + rol5(a) + e + data[i]; 75 | e = d; d = c; c = rol30(b); b = a; a = t; 76 | } 77 | for (/*nothing*/; i < 40; i++) { 78 | t = H(b, c, d) + Y2 + rol5(a) + e + data[i]; 79 | e = d; d = c; c = rol30(b); b = a; a = t; 80 | } 81 | for (/*nothing*/; i < 60; i++) { 82 | t = G(b, c, d) + Y3 + rol5(a) + e + data[i]; 83 | e = d; d = c; c = rol30(b); b = a; a = t; 84 | } 85 | for (/*nothing*/; i < 80; i++) { 86 | t = H(b, c, d) + Y4 + rol5(a) + e + data[i]; 87 | e = d; d = c; c = rol30(b); b = a; a = t; 88 | } 89 | 90 | /* Update chaining values */ 91 | ctx->state[0] += a; 92 | ctx->state[1] += b; 93 | ctx->state[2] += c; 94 | ctx->state[3] += d; 95 | ctx->state[4] += e; 96 | } 97 | 98 | void SHA1_init(struct SHA1Context * ctx) 99 | { 100 | ctx->state[0] = 0x67452301U; 101 | ctx->state[1] = 0xEFCDAB89U; 102 | ctx->state[2] = 0x98BADCFEU; 103 | ctx->state[3] = 0x10325476U; 104 | ctx->state[4] = 0xC3D2E1F0U; 105 | ctx->numbytes = 0; 106 | ctx->length[0] = 0; 107 | ctx->length[1] = 0; 108 | } 109 | 110 | void SHA1_add_data(struct SHA1Context * ctx, unsigned char * data, 111 | unsigned long len) 112 | { 113 | u32 t; 114 | 115 | /* Update length */ 116 | t = ctx->length[1]; 117 | if ((ctx->length[1] = t + (u32) (len << 3)) < t) 118 | ctx->length[0]++; /* carry from low 32 bits to high 32 bits */ 119 | ctx->length[0] += (u32) (len >> 29); 120 | 121 | /* If data was left in buffer, pad it with fresh data and munge block */ 122 | if (ctx->numbytes != 0) { 123 | t = 64 - ctx->numbytes; 124 | if (len < t) { 125 | memcpy(ctx->buffer + ctx->numbytes, data, len); 126 | ctx->numbytes += len; 127 | return; 128 | } 129 | memcpy(ctx->buffer + ctx->numbytes, data, t); 130 | SHA1_transform(ctx); 131 | data += t; 132 | len -= t; 133 | } 134 | /* Munge data in 64-byte chunks */ 135 | while (len >= 64) { 136 | memcpy(ctx->buffer, data, 64); 137 | SHA1_transform(ctx); 138 | data += 64; 139 | len -= 64; 140 | } 141 | /* Save remaining data */ 142 | memcpy(ctx->buffer, data, len); 143 | ctx->numbytes = len; 144 | } 145 | 146 | void SHA1_finish(struct SHA1Context * ctx, unsigned char output[20]) 147 | { 148 | int i = ctx->numbytes; 149 | 150 | /* Set first char of padding to 0x80. There is always room. */ 151 | ctx->buffer[i++] = 0x80; 152 | /* If we do not have room for the length (8 bytes), pad to 64 bytes 153 | with zeroes and munge the data block */ 154 | if (i > 56) { 155 | memset(ctx->buffer + i, 0, 64 - i); 156 | SHA1_transform(ctx); 157 | i = 0; 158 | } 159 | /* Pad to byte 56 with zeroes */ 160 | memset(ctx->buffer + i, 0, 56 - i); 161 | /* Add length in big-endian */ 162 | SHA1_copy_and_swap(ctx->length, ctx->buffer + 56, 2); 163 | /* Munge the final block */ 164 | SHA1_transform(ctx); 165 | /* Final hash value is in ctx->state modulo big-endian conversion */ 166 | SHA1_copy_and_swap(ctx->state, output, 5); 167 | } 168 | 169 | /* Test harness */ 170 | 171 | static void do_test(unsigned char * txt, unsigned char * expected_output) 172 | { 173 | struct SHA1Context ctx; 174 | unsigned char output[20]; 175 | int ok; 176 | 177 | SHA1_init(&ctx); 178 | SHA1_add_data(&ctx, txt, strlen((char *) txt)); 179 | SHA1_finish(&ctx, output); 180 | ok = memcmp(output, expected_output, 20) == 0; 181 | //printf("Test `%s': %s\n", 182 | // (char *) txt, (ok ? "passed" : "FAILED")); 183 | } 184 | 185 | /* Test vectors: 186 | * 187 | * "abc" 188 | * A999 3E36 4706 816A BA3E 2571 7850 C26C 9CD0 D89D 189 | * 190 | * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 191 | * 8498 3E44 1C3B D26E BAAE 4AA1 F951 29E5 E546 70F1 192 | */ 193 | 194 | unsigned char test_input_1[] = "abc"; 195 | 196 | unsigned char test_output_1[20] = 197 | { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E , 198 | 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }; 199 | 200 | unsigned char test_input_2[] = 201 | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; 202 | 203 | unsigned char test_output_2[20] = 204 | { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, 205 | 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }; 206 | 207 | 208 | static void do_bench(int nblocks) 209 | { 210 | struct SHA1Context ctx; 211 | unsigned char output[20]; 212 | unsigned char data[64]; 213 | 214 | SHA1_init(&ctx); 215 | for (; nblocks > 0; nblocks--) 216 | SHA1_add_data(&ctx, data, 64); 217 | SHA1_finish(&ctx, output); 218 | } 219 | 220 | int main(int argc, char ** argv) 221 | { 222 | /* Determine endianness */ 223 | union { int i; unsigned char b[4]; } u; 224 | u.i = 0x12345678; 225 | switch (u.b[0]) { 226 | case 0x12: arch_big_endian = 1; break; 227 | case 0x78: arch_big_endian = 0; break; 228 | default: return 2; 229 | } 230 | do_test(test_input_1, test_output_1); 231 | do_test(test_input_2, test_output_2); 232 | do_bench(1000000); 233 | return 0; 234 | } 235 | -------------------------------------------------------------------------------- /x86model/cdriver/test/spectral.c: -------------------------------------------------------------------------------- 1 | /* -*- mode: c -*- 2 | * 3 | * The Great Computer Language Shootout 4 | * http://shootout.alioth.debian.org/ 5 | * 6 | * Contributed by Sebastien Loisel 7 | */ 8 | 9 | //#include 10 | #include 11 | //#include 12 | 13 | double eval_A(int i, int j) { return 1.0/((i+j)*(i+j+1)/2+i+1); } 14 | 15 | void eval_A_times_u(int N, const double u[], double Au[]) 16 | { 17 | int i,j; 18 | for(i=0;i 4 | #include 5 | 6 | #define STACKSIZE 256 7 | 8 | enum wordcode_instruct { 9 | WCALL1, WCALL1_pop1, WCONST, WCONST_pop1, WBRANCHIF, WBRANCHIF_pop1, 10 | WCALL3, WRETURN, WBRANCH, WLTINT, WADDINT, WOFFSETINT, WDUP, WGRAB, WSTOP 11 | }; 12 | 13 | #define Opcode (instr & 0xFF) 14 | #define Byte1 ((instr >> 8) & 0xFF) 15 | #define Byte2 ((instr >> 16) & 0xFF) 16 | #define Byte3 (instr >> 24) 17 | #define Op1 sp[Byte1] 18 | #define Op2 sp[Byte2] 19 | #define Op3 sp[Byte3] 20 | #define Imm8s ((int)instr >> 24) 21 | #define Imm16u (instr >> 16) 22 | #define Imm16s ((int)instr >> 16) 23 | #define Imm24u (instr >> 8) 24 | #define Imm24s ((int)instr >> 8) 25 | #define Adjust1 (sp += instr & 1) 26 | #define Adjust2 (sp += instr & 3) 27 | #define Adjustbyte1 (sp += Byte1) 28 | #define Adjustbyte2 (sp += Byte2) 29 | #define Adjustbyte3 (sp += Byte3) 30 | #define Extrabyte1(w) (w & 0xFF) 31 | #define Extrabyte2(w) ((w >> 8) & 0xFF) 32 | #define Extrabyte3(w) ((w >> 16) & 0xFF) 33 | #define Extrabyte4(w) (w >> 24) 34 | #define Extraop1(w) sp[Extrabyte1(w)] 35 | #define Extraop2(w) sp[Extrabyte2(w)] 36 | #define Extraop3(w) sp[Extrabyte3(w)] 37 | #define Extraop4(w) sp[Extrabyte4(w)] 38 | #define Push1(x) \ 39 | sp-=1, sp[0]=x 40 | #define Push2(x,y) \ 41 | sp-=2, sp[1]=x, sp[0]=y 42 | #define Push3(x,y,z) \ 43 | sp-=3, sp[2]=x, sp[1]=y, sp[0]=z 44 | #define Push4(x,y,z,t) \ 45 | sp-=4, sp[3]=x, sp[2]=y, sp[1]=z, sp[0]=t 46 | #define Push5(x,y,z,t,u) \ 47 | sp-=5, sp[4]=x, sp[3]=y, sp[2]=z, sp[1]=t, sp[0]=u 48 | #define Push6(x,y,z,t,u,v) \ 49 | sp-=6, sp[5]=x, sp[4]=y, sp[3]=z, sp[2]=t, sp[1]=u, sp[0]=v 50 | #define Push7(x,y,z,t,u,v,w) \ 51 | sp-=7, sp[6]=x, sp[5]=y, sp[4]=z, sp[3]=t, sp[2]=u, sp[1]=v, sp[0]=w 52 | 53 | long stack[STACKSIZE]; 54 | 55 | long wordcode_interp(code) 56 | unsigned int * code; 57 | { 58 | long * sp; 59 | unsigned int * pc; 60 | unsigned int instr; 61 | int extra_args = 0; 62 | 63 | sp = stack + STACKSIZE; 64 | pc = code; 65 | while (1) { 66 | instr = *pc++; 67 | switch (Opcode) { 68 | 69 | case WCALL1: case WCALL1_pop1: { 70 | long arg = Op1; 71 | Adjust1; 72 | Push3((long)pc, extra_args, arg); 73 | pc += Imm16s; 74 | extra_args = 0; 75 | break; 76 | } 77 | case WCONST: case WCONST_pop1: { 78 | Adjust1; 79 | Push1(Imm24s); 80 | break; 81 | } 82 | case WBRANCHIF: case WBRANCHIF_pop1: { 83 | long arg = Op1; 84 | Adjust1; 85 | if (arg) pc += Imm16s; 86 | break; 87 | } 88 | case WCALL3: { 89 | unsigned int ext = *pc++; 90 | long arg1 = Extraop1(ext); 91 | long arg2 = Extraop2(ext); 92 | long arg3 = Extraop3(ext); 93 | Adjustbyte1; 94 | Push5((long)pc, extra_args, arg3, arg2, arg1); 95 | pc += Imm16s; 96 | extra_args = 2; 97 | break; 98 | } 99 | case WRETURN: { 100 | long res = Op1; 101 | Adjustbyte2; 102 | if (extra_args > 0) { 103 | //printf("Over-application.\n"); 104 | exit(2); 105 | } else { 106 | extra_args = sp[0]; 107 | pc = (unsigned int *) sp[1]; 108 | sp += 1; 109 | *sp = res; 110 | } 111 | break; 112 | } 113 | case WBRANCH: { 114 | Adjustbyte1; 115 | pc += Imm16s; 116 | break; 117 | } 118 | case WLTINT: { 119 | long arg1 = Op1, arg2 = Op2; 120 | Adjustbyte3; 121 | Push1(arg1 < arg2); 122 | break; 123 | } 124 | case WADDINT: { 125 | long arg1 = Op1, arg2 = Op2; 126 | Adjustbyte3; 127 | Push1(arg1 + arg2); 128 | break; 129 | } 130 | case WOFFSETINT: { 131 | long arg = Op1; 132 | Adjustbyte2; 133 | Push1(arg + Imm8s); 134 | break; 135 | } 136 | case WDUP: { 137 | long arg = Op1; 138 | Push1(arg); 139 | break; 140 | } 141 | case WGRAB: { 142 | int required = Byte1; 143 | if (extra_args >= required) { 144 | extra_args -= required; 145 | } else { 146 | //printf("Partial application.\n"); 147 | exit(2); 148 | } 149 | break; 150 | } 151 | case WSTOP: { 152 | long res = Op1; 153 | Adjustbyte2; 154 | return res; 155 | break; 156 | } 157 | } 158 | } 159 | } 160 | 161 | #define I(a,b,c,d) ((a) + ((b) << 8) + ((c) << 16) + ((d) << 24)) 162 | 163 | unsigned int wordcode_fib[] = { 164 | /* 0 */ I(WCONST, 30, 0, 0), 165 | /* 1 */ I(WCALL1_pop1, 0, 3-1-1, 0), 166 | /* 2 */ I(WSTOP, 0, 1, 0), 167 | /* 3 */ I(WCONST, 2, 0, 0), 168 | /* 4 */ I(WLTINT, 1, 0, 1), 169 | /* 5 */ I(WBRANCHIF_pop1, 0, 12-5-1, 0), 170 | /* 6 */ I(WOFFSETINT, 0, 0, -1), 171 | /* 7 */ I(WCALL1_pop1, 0, 3-7-1, 0), 172 | /* 8 */ I(WOFFSETINT, 1, 0, -2), 173 | /* 9 */ I(WCALL1_pop1, 0, 3-9-1, 0), 174 | /* 10 */ I(WADDINT, 0, 1, 2), 175 | /* 11 */ I(WRETURN, 0, 2, 0), 176 | /* 12 */ I(WCONST, 1, 0, 0), 177 | /* 13 */ I(WRETURN, 0, 2, 0) 178 | }; 179 | unsigned int wordcode_tak[] = { 180 | /* 0 */ I(WCONST, 6, 0, 0), 181 | /* 1 */ I(WCONST, 12, 0, 0), 182 | /* 2 */ I(WCONST, 18, 0, 0), 183 | /* 3 */ I(WCALL3, 3, 6-3-2, 0), 184 | /* 4 */ I(0, 1, 2, 0), 185 | /* 5 */ I(WSTOP, 0, 1, 0), 186 | /* 6 */ I(WGRAB, 2, 0, 0), /* z y x */ 187 | /* 7 */ I(WLTINT, 1, 0, 0), /* z y x (y tmp1.v 9 | coqc Fuzz.v -I "../Model/" 10 | coqc tmp1.v -I "../Model/" 11 | cp Parser.ml_fastarray Parser.ml 12 | rm Parser.mli 13 | rm *.mli 14 | cp cZeven.ml Zeven.ml 15 | 16 | extraction:: 17 | echo 'Require Import Fuzz. Extraction Blacklist String List. Recursive Extraction Library Fuzz.' > tmp1.v 18 | make -C "../Model/" 19 | coqc Fuzz.v -I "../Model/" 20 | coqc tmp1.v -I "../Model/" 21 | cp Parser.ml_fastarray Parser.ml 22 | rm Parser.mli 23 | rm *.mli 24 | cp cZeven.ml Zeven.ml 25 | 26 | clean:: 27 | rm -rf _build/ 28 | -------------------------------------------------------------------------------- /x86model/fuzz/README: -------------------------------------------------------------------------------- 1 | To get started, you must do: 2 | 3 | make extraction (run make extract-nob if you want to extract without first attempting 4 | to build the Coq files in the Model directory) 5 | make 6 | 7 | This directory contains a fuzzer for x86 byte code. The extracted code, 8 | Fuzz.ml, takes parsers, as defined in Decode.v or elsewhere, and generates 9 | byte code that is in the language recognized by these parsers. 10 | 11 | The file fuzzgen.ml is a driver script for this. It emits the ascii 12 | for the hex code corresponding to the generated byte code. It pads these 13 | instructions with NOPS in between (this is used by filter.c - see that for 14 | details) 15 | 16 | The script ./fuzzer.sh glues everything together. Here's what it does 17 | - Calls fuzzgen.ml and dumps the result in fuzz.ascii 18 | - Calls xxd -r -p on fuzz.ascii to produce fuzz.hex (xxd -r -p takes 19 | ascii values for hex and converts it into the corresponding binary) 20 | - Then runs ld on fuzz.hex to produce fuzz.obj - the result is an elf 21 | file that defines symbols called _binary_fuzz_hex_start/end/size. 22 | - Runs gcc on filter.c, linking it with the fuzz.obj file to produce filter.out 23 | - Runs filter.out. Filter.out remits the ascii corresponding to fuzz.ascii 24 | with instructions that triggered segfaults stripped out (to the best 25 | of its ability) 26 | - Repeat the above process of xxd and ld on the output of filter.out 27 | - Runs gcc on test.c, linking it with this fuzz.obj file, to produce 28 | test.out 29 | 30 | NOTE: If you are using an x86-64 environment, use ./fuzzer64.sh instead. 31 | 32 | The behavior of filter.c is a little subtle and is documented in the source for 33 | it. test.c is a little C program that has a declared external function pointer 34 | _binary_fuzz_hex_start. All it does in main() is just call this function 35 | pointer. Which, after linking with fuzz.obj, will be the generated code we want 36 | to run! 37 | 38 | The result is test.out, which you can trace using ./run.sh. You will want to 39 | stop at the symbol "_binary_fuzz_hex_end". Then you can load the emitted 40 | mem0.txt, regs0.txt, mem1.txt trace files using the simulator as described in 41 | ../semantics_test/ 42 | -------------------------------------------------------------------------------- /x86model/fuzz/big.ml: -------------------------------------------------------------------------------- 1 | (************************************************************************) 2 | (* v * The Coq Proof Assistant / The Coq Development Team *) 3 | (* 0 then fp z else fn (opp z) 137 | 138 | let compare_case e l g x y = 139 | let s = compare x y in if s = 0 then e else if s<0 then l else g 140 | 141 | let nat_rec fO fS = 142 | let rec loop acc n = 143 | if sign n <= 0 then acc else loop (fS acc) (pred n) 144 | in loop fO 145 | 146 | let positive_rec f2p1 f2p f1 = 147 | let rec loop n = 148 | if le n one then f1 149 | else 150 | let (q,r) = quomod n two in 151 | if eq r zero then f2p (loop q) else f2p1 (loop q) 152 | in loop 153 | 154 | let z_rec fO fp fn = z_case (fun _ -> fO) fp fn 155 | -------------------------------------------------------------------------------- /x86model/fuzz/cZeven.ml: -------------------------------------------------------------------------------- 1 | open BinInt 2 | open BinPos 3 | open Datatypes 4 | 5 | (** val coq_Zeven_bool : Big.big_int -> bool **) 6 | 7 | let coq_Zeven_bool z = 8 | Big.z_case 9 | (fun _ -> true) 10 | (fun p -> 11 | Big.positive_case 12 | (fun p0 -> false) 13 | (fun p0 -> true) 14 | (fun _ -> false) 15 | p) 16 | (fun p -> 17 | Big.positive_case 18 | (fun p0 -> false) 19 | (fun p0 -> true) 20 | (fun _ -> false) 21 | p) 22 | z 23 | 24 | (** val coq_Zodd_bool : Big.big_int -> bool **) 25 | 26 | let coq_Zodd_bool z = 27 | Big.z_case 28 | (fun _ -> false) 29 | (fun p -> 30 | Big.positive_case 31 | (fun p0 -> true) 32 | (fun p0 -> false) 33 | (fun _ -> true) 34 | p) 35 | (fun p -> 36 | Big.positive_case 37 | (fun p0 -> true) 38 | (fun p0 -> false) 39 | (fun _ -> true) 40 | p) 41 | z 42 | 43 | (** val coq_Zeven_odd_dec : Big.big_int -> bool **) 44 | 45 | let coq_Zeven_odd_dec z = 46 | Big.z_case 47 | (fun _ -> true) 48 | (fun p -> 49 | Big.positive_case 50 | (fun p0 -> false) 51 | (fun p0 -> true) 52 | (fun _ -> false) 53 | p) 54 | (fun p -> 55 | Big.positive_case 56 | (fun p0 -> false) 57 | (fun p0 -> true) 58 | (fun _ -> false) 59 | p) 60 | z 61 | 62 | (** val coq_Zeven_dec : Big.big_int -> bool **) 63 | 64 | let coq_Zeven_dec z = 65 | Big.z_case 66 | (fun _ -> true) 67 | (fun p -> 68 | Big.positive_case 69 | (fun p0 -> false) 70 | (fun p0 -> true) 71 | (fun _ -> false) 72 | p) 73 | (fun p -> 74 | Big.positive_case 75 | (fun p0 -> false) 76 | (fun p0 -> true) 77 | (fun _ -> false) 78 | p) 79 | z 80 | 81 | (** val coq_Zodd_dec : Big.big_int -> bool **) 82 | 83 | let coq_Zodd_dec z = 84 | Big.z_case 85 | (fun _ -> false) 86 | (fun p -> 87 | Big.positive_case 88 | (fun p0 -> true) 89 | (fun p0 -> false) 90 | (fun _ -> true) 91 | p) 92 | (fun p -> 93 | Big.positive_case 94 | (fun p0 -> true) 95 | (fun p0 -> false) 96 | (fun _ -> true) 97 | p) 98 | z 99 | 100 | (** val coq_Zdiv2 : Big.big_int -> Big.big_int **) 101 | 102 | let coq_Zdiv2 z = 103 | Big.z_case 104 | (fun _ -> Big.zero) 105 | (fun p -> 106 | Big.positive_case 107 | (fun p0 -> (coq_Pdiv2 p)) 108 | (fun p0 -> (coq_Pdiv2 p)) 109 | (fun _ -> Big.zero) 110 | p) 111 | (fun p -> 112 | Big.positive_case 113 | (fun p0 -> Big.opp (coq_Pdiv2 p)) 114 | (fun p0 -> Big.opp (coq_Pdiv2 p)) 115 | (fun _ -> Big.zero) 116 | p) 117 | z 118 | 119 | (** val coq_Z_modulo_2 : Big.big_int -> (Big.big_int, Big.big_int) sum **) 120 | 121 | let coq_Z_modulo_2 x = 122 | if coq_Zeven_odd_dec x 123 | then Coq_inl (coq_Zdiv2 x) 124 | else Coq_inr 125 | (Big.z_case 126 | (fun _ -> assert false (* absurd case *)) 127 | (fun p -> coq_Zdiv2 p) 128 | (fun p -> coq_Zdiv2 (coq_Zpred (Big.opp p))) 129 | x) 130 | 131 | (** val coq_Zsplit2 : Big.big_int -> (Big.big_int * Big.big_int) **) 132 | 133 | let coq_Zsplit2 x = 134 | match coq_Z_modulo_2 x with 135 | | Coq_inl x0 -> (x0, x0) 136 | | Coq_inr x0 -> (x0, (coq_Zplus x0 Big.one)) 137 | 138 | -------------------------------------------------------------------------------- /x86model/fuzz/filter.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2011. Greg Morrisett, Gang Tan, Joseph Tassarotti, 2 | Jean-Baptiste Tristan, and Edward Gan. 3 | 4 | This file is part of RockSalt. 5 | 6 | This file is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License as 8 | published by the Free Software Foundation; either version 2 of 9 | the License, or (at your option) any later version. 10 | */ 11 | 12 | 13 | /* 14 | This file contains C code that, when linked with a binary produced from 15 | the output of fuzzgen.ml, will run the instructions outputted by fuzzgen.ml 16 | and attempt to strip out any instructions that cause a SIGSEGV. 17 | 18 | What happens is that the initial output of fuzzgen.ml has been padded with 19 | NOPS in between instructions. This C file registers a signal handler for 20 | SIGSEGV before jumping to the output of fuzzgen. The signal handler 21 | bumps the EIP of the context in which the segfault happened by 15, which 22 | will push us past the instruction that caused the segfault and into the 23 | NOPs. Because instruction lengths vary, the place we end up in the NOPs will 24 | vary, but that is ok, because they will just act like a sled. 25 | 26 | Before doing this, the signal handler prints out all the instructions from 27 | the last time we did this up until the current SEGFault causing-offender. 28 | 29 | The result is that we output a file which contains only the instructions 30 | that did not trigger a segfault. The NOPs are also filtered out. This 31 | output is then ready to be converted to a binary and linked with another 32 | test driver. 33 | 34 | Granted, it is possible for an instruction that did not trigger a segfault 35 | here to trigger a segfault when loaded with different code and in a different 36 | position, but in practice this actually tends to work pretty well. Also, the stuff 37 | we do in the handler is NOT allowed in good C code (ie: doing file io). But hey, 38 | we're also about to transfer control to a randomly generated binary, so we've 39 | already thrown caution to the wind. Also, this is all highly Linux specific 40 | as best I can tell. 41 | */ 42 | 43 | #include 44 | #include 45 | #include 46 | /* If you include this #define statement you get nice macros/names for 47 | * modifying ucontext_t data structure, which we will be doing here 48 | */ 49 | #define __USE_GNU 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | struct sigaction action; 56 | 57 | /* These are symbols that will be added when we link against the 58 | binary created from the fuzzgen.ml output 59 | 60 | _binary_fuzz_hex_start is the symbol that marks the beginning 61 | of the fuzz generated code. We will call it as a function in order 62 | to jump to it. 63 | 64 | _binary_data_hex_start is an array that indicates which of the generated 65 | bytes from fuzzgen.ml output are just NOPs, we will filter these out 66 | so that we don't waste our time simulating NOPS. 67 | */ 68 | void _binary_fuzz_hex_start(); 69 | 70 | extern char _binary_data_hex_start[]; 71 | 72 | // This will keep track of the last EIP that we printed a dump from 73 | unsigned int * last_good = _binary_fuzz_hex_start; 74 | 75 | void test(int sig, siginfo_t * info, ucontext_t * context) 76 | { 77 | unsigned int i = 0; 78 | unsigned int tmp = 0; 79 | 80 | /* Loop through reading out all of the byte code for the instructions in between 81 | the last time we did such a dump and the current offending instruction */ 82 | for(i = 0; i < (context->uc_mcontext.gregs[REG_EIP] - (unsigned int) last_good); i++) { 83 | 84 | // Only print it out if it isn't a nop (ie _binary_data_hex_start for this EIP value isn't 0 85 | if(_binary_data_hex_start[(unsigned int) last_good + i - (unsigned int)_binary_fuzz_hex_start]) { 86 | tmp = *((unsigned int *) ( (unsigned int) last_good + i)); 87 | tmp &= 0x000000FF; 88 | printf("%02x\n", tmp); 89 | } 90 | 91 | } 92 | 93 | // Always good to flush this. 94 | fflush(stdout); 95 | 96 | // Bump EIP by 15 so that when we return we will have moved past the 97 | // offending instruction 98 | context->uc_mcontext.gregs[REG_EIP] += 15; 99 | last_good = context->uc_mcontext.gregs[REG_EIP]; 100 | } 101 | 102 | 103 | int main() 104 | { 105 | // Register the signal handler. We're using sigaction instead of the 106 | // simpler sighandler stuff because we need access to context 107 | action.sa_flags = SA_SIGINFO; 108 | action.sa_sigaction = test; 109 | sigaction(SIGSEGV, &action, NULL); 110 | 111 | // Transfer control to the fuzz generated code 112 | _binary_fuzz_hex_start(); 113 | } 114 | -------------------------------------------------------------------------------- /x86model/fuzz/fuzzer.sh: -------------------------------------------------------------------------------- 1 | ./fuzzgen.native > fuzz.ascii 2 | # This is move 0x0, eax, which will trigger segfault 3 | # that's critical to cause the instructions after the 4 | # move recent seg fault to print out 5 | echo "a100000000" >> fuzz.ascii 6 | echo "9090909090" >> fuzz.ascii 7 | echo "9090909090" >> fuzz.ascii 8 | echo "9090909090" >> fuzz.ascii 9 | echo "9090909090" >> fuzz.ascii 10 | echo "9090909090" >> fuzz.ascii 11 | echo "9090909090" >> fuzz.ascii 12 | echo "9090909090" >> fuzz.ascii 13 | echo "9090909090" >> fuzz.ascii 14 | echo "9090909090" >> fuzz.ascii 15 | echo "9090909090" >> fuzz.ascii 16 | echo "9090909090" >> fuzz.ascii 17 | echo "9090909090" >> fuzz.ascii 18 | echo "9090909090" >> fuzz.ascii 19 | # this is mov $0x1, %eax; int 0x80 which causes 20 | # the program to exit 21 | echo "b801000000" >> fuzz.ascii 22 | echo "cd80" >> fuzz.ascii 23 | 24 | echo "00000000" >> data.ascii 25 | echo "00000000" >> data.ascii 26 | echo "00000000" >> data.ascii 27 | echo "00000000" >> data.ascii 28 | echo "00000000" >> data.ascii 29 | echo "00000000" >> data.ascii 30 | echo "00000000" >> data.ascii 31 | 32 | xxd -r -p fuzz.ascii > fuzz.hex 33 | ld -r -b binary -o fuzz.eobj fuzz.hex 34 | objcopy --rename-section .data=.text,contents,alloc,load,code fuzz.eobj 35 | objcopy fuzz.eobj --globalize-symbol=_binary_fuzz_hex_start 36 | 37 | xxd -r -p data.ascii > data.hex 38 | ld -r -b binary -o data.eobj data.hex 39 | objcopy --rename-section .data=.text,contents,alloc,load,code data.eobj 40 | objcopy data.eobj --globalize-symbol=_binary_data_hex_start 41 | gcc -o filter.out filter.c fuzz.eobj data.eobj 42 | 43 | setarch i386 -R ./filter.out > fuzz.ascii.filtered 44 | xxd -r -p fuzz.ascii.filtered > fuzz.hex 45 | ld -r -b binary -o fuzz.eobj fuzz.hex 46 | objcopy --rename-section .data=.text,contents,alloc,load,code fuzz.eobj 47 | objcopy fuzz.eobj --globalize-symbol=_binary_fuzz_hex_start 48 | gcc -o test.out test.c fuzz.eobj 49 | -------------------------------------------------------------------------------- /x86model/fuzz/fuzzer64.sh: -------------------------------------------------------------------------------- 1 | ./fuzzgen.native > fuzz.ascii 2 | # This is move 0x0, eax, which will trigger segfault 3 | # that's critical to cause the instructions after the 4 | # move recent seg fault to print out 5 | echo "a100000000" >> fuzz.ascii 6 | echo "9090909090" >> fuzz.ascii 7 | echo "9090909090" >> fuzz.ascii 8 | echo "9090909090" >> fuzz.ascii 9 | echo "9090909090" >> fuzz.ascii 10 | echo "9090909090" >> fuzz.ascii 11 | echo "9090909090" >> fuzz.ascii 12 | echo "9090909090" >> fuzz.ascii 13 | echo "9090909090" >> fuzz.ascii 14 | echo "9090909090" >> fuzz.ascii 15 | echo "9090909090" >> fuzz.ascii 16 | echo "9090909090" >> fuzz.ascii 17 | echo "9090909090" >> fuzz.ascii 18 | echo "9090909090" >> fuzz.ascii 19 | # this is mov $0x1, %eax; int 0x80 which causes 20 | # the program to exit 21 | echo "b801000000" >> fuzz.ascii 22 | echo "cd80" >> fuzz.ascii 23 | 24 | echo "00000000" >> data.ascii 25 | echo "00000000" >> data.ascii 26 | echo "00000000" >> data.ascii 27 | echo "00000000" >> data.ascii 28 | echo "00000000" >> data.ascii 29 | echo "00000000" >> data.ascii 30 | echo "00000000" >> data.ascii 31 | 32 | xxd -r -p fuzz.ascii > fuzz.hex 33 | ld -m elf_i386 -r -b binary -o fuzz.eobj fuzz.hex 34 | objcopy --rename-section .data=.text,contents,alloc,load,code fuzz.eobj 35 | objcopy fuzz.eobj --globalize-symbol=_binary_fuzz_hex_start 36 | 37 | xxd -r -p data.ascii > data.hex 38 | ld -m elf_i386 -r -b binary -o data.eobj data.hex 39 | objcopy --rename-section .data=.text,contents,alloc,load,code data.eobj 40 | objcopy data.eobj --globalize-symbol=_binary_data_hex_start 41 | gcc -m32 -o filter.out filter.c fuzz.eobj data.eobj 42 | 43 | setarch i386 -R ./filter.out > fuzz.ascii.filtered 44 | xxd -r -p fuzz.ascii.filtered > fuzz.hex 45 | ld -m elf_i386 -r -b binary -o fuzz.eobj fuzz.hex 46 | objcopy --rename-section .data=.text,contents,alloc,load,code fuzz.eobj 47 | objcopy fuzz.eobj --globalize-symbol=_binary_fuzz_hex_start 48 | gcc -m32 -o test.out test.c fuzz.eobj 49 | -------------------------------------------------------------------------------- /x86model/fuzz/fuzzgen.ml: -------------------------------------------------------------------------------- 1 | exception Fail;; 2 | exception FailSafe;; 3 | exception EndReg;; 4 | 5 | open Unix 6 | open Peano 7 | open Char 8 | open BinInt 9 | open BinPos 10 | open Coqlib 11 | open Specif 12 | open Zdiv 13 | open Zpower 14 | open Big_int 15 | open Bits 16 | open Datatypes 17 | open Parser 18 | open Monad 19 | open ZArith_dec 20 | open String 21 | open List0 22 | open Zdiv 23 | open Fuzz 24 | open Random 25 | open X86Syntax 26 | open X86_PARSER_ARG 27 | open X86_PARSER 28 | open X86_BASE_PARSER 29 | open Decode 30 | 31 | let out_code = open_out "fuzz.ascii" 32 | let out_data = open_out "data.ascii" 33 | 34 | 35 | let rec myalts l = 36 | match l with 37 | | x :: y :: [] -> alt instruction_t x y 38 | | x :: [] -> x 39 | | x :: l' -> alt instruction_t x (myalts l') 40 | 41 | 42 | (*let parser_to_fuzz = myalts [coq_ADC_p false; coq_ADD_p false; coq_AND_p false; coq_CMP_p false; 43 | coq_OR_p false; coq_SBB_p false; coq_SUB_p false; coq_XOR_p false]*) 44 | (* Skip over div/idiv because of exceptions in the fuzzed code *) 45 | (* 46 | let parser_to_fuzz1 = Cat_p (Obj.magic(), Obj.magic(), coq_SAHF_p, 47 | myalts [ coq_AND_p false; coq_OR_p false; coq_XOR_p false; coq_TEST_p false; 48 | coq_NOT_p; coq_INC_p; coq_ADD_p false; coq_ADC_p false; coq_CMP_p false; coq_SUB_p false; 49 | coq_SBB_p false; coq_NEG_p; coq_HLT_p; coq_IMUL_p false ; coq_MUL_p; 50 | coq_SHL_p; coq_SHR_p; coq_SHRD_p; coq_SAR_p; coq_BSR_p; coq_BSF_p; coq_BT_p; coq_BTC_p; 51 | coq_BTS_p; coq_BTR_p; coq_BSWAP_p; coq_CWDE_p; coq_CDQ_p; coq_MOV_p false; coq_CMOVcc_p; 52 | coq_MOVZX_p; coq_MOVSX_p; coq_CWDE_p; coq_CDQ_p; coq_MOV_p false; 53 | coq_CMOVcc_p; coq_MOVZX_p; coq_MOVSX_p; coq_XCHG_p; coq_CLC_p; coq_CLD_p; coq_STD_p; coq_STC_p; 54 | coq_MOVS_p; coq_CMPXCHG_p; coq_CMPS_p; coq_STOS_p; coq_LEA_p; coq_SETcc_p; coq_POP_p; coq_PUSH_p; 55 | coq_ROL_p; coq_ROR_p; coq_RCL_p; coq_RCR_p; coq_LAHF_p; coq_CMC_p]) 56 | *) 57 | let parser_to_fuzz1 = Cat_p (Obj.magic(), Obj.magic(), coq_SAHF_p, 58 | myalts [ coq_AND_p false; coq_OR_p false; coq_XOR_p false; coq_TEST_p false; 59 | coq_NOT_p; coq_DEC_p; coq_INC_p; coq_ADD_p false; coq_ADC_p false; coq_CMP_p false; coq_SUB_p false; 60 | coq_SBB_p false; coq_NEG_p; coq_HLT_p; coq_IMUL_p false ; coq_MUL_p; 61 | coq_AAA_p; coq_AAS_p; coq_AAD_p; coq_AAM_p; (* coq_DAA_p; coq_DAS_p; *) 62 | coq_SHL_p; coq_SHR_p; coq_SHLD_p; coq_SHRD_p; coq_SAR_p; (*coq_BSR_p; coq_BSF_p;*) coq_BT_p; coq_BTC_p; 63 | coq_BTS_p; coq_BTR_p; coq_BSWAP_p; coq_CWDE_p; coq_CDQ_p; coq_MOV_p false; coq_CMOVcc_p; 64 | coq_CMOVcc_p; coq_MOVZX_p; coq_MOVSX_p; coq_XCHG_p; coq_CLC_p; coq_CLD_p; coq_STD_p; coq_STC_p; 65 | coq_MOVS_p; coq_CMPXCHG_p; coq_CMPS_p; coq_STOS_p; coq_LEA_p; coq_SETcc_p; coq_POP_p; coq_PUSH_p; 66 | coq_ROL_p; coq_ROR_p; coq_RCL_p; coq_RCR_p; coq_LAHF_p; coq_CMC_p]) 67 | 68 | 69 | let instr_parsers_opsize_pre_nodiv = 70 | (coq_ADC_p 71 | true) :: ((coq_ADD_p 72 | true) :: ((coq_AND_p 73 | true) :: ((coq_CMP_p 74 | true) :: ((coq_OR_p 75 | true) :: ((coq_SBB_p 76 | true) :: ( 77 | (coq_SUB_p 78 | true) :: (coq_SHL_p :: (coq_SHR_p :: (coq_SAR_p :: ( 79 | (coq_XOR_p 80 | true) :: ((coq_IMUL_p 81 | true) :: ((coq_MOV_p 82 | true) :: (coq_MOVSX_p :: (coq_MOVZX_p :: (coq_NEG_p :: (coq_NOT_p :: ( 83 | (coq_TEST_p 84 | true) :: (coq_CDQ_p :: (coq_CWDE_p :: (coq_MUL_p :: (coq_XCHG_p :: []))))))))))))))))))))) 85 | 86 | 87 | let parser_to_fuzz2 = Cat_p (Obj.magic(), Obj.magic(), coq_SAHF_p, Cat_p (Obj.magic(), Obj.magic(), op_override_p, myalts instr_parsers_opsize_pre_nodiv)) 88 | 89 | let parser_to_fuzz = parser_to_fuzz1 90 | 91 | let () = Random.self_init () 92 | 93 | let mytestempty_oracle : oracle = {oracle_num = (fun x -> big_int_of_int (Random.int 2000)); oracle_offset = Big.zero};; 94 | 95 | let print_bool b = 96 | match b with 97 | | false -> "0" 98 | | true -> "1" 99 | 100 | let rec conv_byte_aux bs res count = 101 | match count with 102 | | 0 -> (bs, res) 103 | | count2 -> 104 | (match bs with 105 | | h :: tl -> (match h with 106 | | true -> conv_byte_aux tl (2*res +1) (count2 -1) 107 | | false -> conv_byte_aux tl (2*res) (count2 - 1)) 108 | | [] -> conv_byte_aux [] (2*res) (count2 - 1));; 109 | 110 | let rec conv_total bs = 111 | match bs with 112 | | [] -> [] 113 | | h :: tl' -> let (rem, res) = (conv_byte_aux bs 0 4) in 114 | res :: (conv_total rem) 115 | 116 | let rec print_list l = 117 | match l with 118 | | [] -> print_string "" 119 | | h :: tl -> print_string (print_bool h); print_string ""; print_list tl 120 | 121 | let rec print_hex_list l = 122 | match l with 123 | | [] -> print_string "" 124 | | h :: h' :: tl -> Printf.fprintf out_code "%x%x\n" h h'; 125 | Printf.fprintf out_data "01\n"; 126 | print_hex_list tl 127 | 128 | (* This takes in a parser (that's p) and an int (i) 129 | * and generates that many instances of instructions in 130 | * the language of p *) 131 | (* 132 | let rec generate p i = 133 | match i with 134 | | 0 -> () 135 | | x -> print_hex_list (conv_total (snd (fuzz_p (Obj.magic()) p 136 | mytestempty_oracle))); generate p (x - 1);; 137 | 138 | let rec generate_withnop p i = 139 | match i with 140 | | 0 -> () 141 | | x -> print_hex_list (conv_total (snd (fuzz_p (Obj.magic()) p 142 | mytestempty_oracle))); print_string "\n"; generate coq_NOP 16; 143 | generate_withnop p (x - 1);; 144 | *) 145 | 146 | let rec print_nops i = 147 | match i with 148 | | 0 -> () 149 | | x -> Printf.fprintf out_code "90\n"; 150 | Printf.fprintf out_data "00\n"; 151 | print_nops (x -1);; 152 | 153 | let rec generate p i = 154 | match i with 155 | | 0 -> () 156 | | x -> print_hex_list (conv_total (snd (fuzz_p (Obj.magic()) p 157 | mytestempty_oracle))); 158 | print_nops 16; 159 | generate p (x - 1);; 160 | 161 | let () = generate (coq_MOV_ESP_to_EBX) 1;; 162 | let () = generate (parser_to_fuzz) 100;; 163 | -------------------------------------------------------------------------------- /x86model/fuzz/instr_fuzz/Makefile: -------------------------------------------------------------------------------- 1 | syntaxfuzzer.native: syntaxfuzzer.ml PrettyPrinter.ml enc_dec.ml 2 | ocamlbuild -verbose 1 -cflag -g -lflag -g syntaxfuzzer.native -lib unix -lib nums -Is extract 3 | 4 | deriving:: 5 | cd camlp4_fuzz/deriving-master; make; make tests; make install; cd ..; cd .. 6 | 7 | debugging: extraction 8 | ocamlbuild -use-ocamlfind -Is ocamlutil,extract -cflag -g -lflag -g main.native 9 | 10 | profiling: extraction 11 | ocamlbuild -use-ocamlfind -Is ocamlutil,extract -cflag -g -lflag -g main.p.native 12 | 13 | extraction:: 14 | cd extract; make extraction; cd .. 15 | 16 | clean:: 17 | ocamlbuild -clean 18 | cd extract; make clean; cd .. 19 | rm -f *.glob *.vo 20 | -------------------------------------------------------------------------------- /x86model/fuzz/instr_fuzz/README: -------------------------------------------------------------------------------- 1 | To make the syntax fuzzer, just do: 2 | 3 | (1) make extraction 4 | (2) make syntaxfuzzer.native 5 | 6 | Then you can run it. Here's how to run: 7 | 8 | ./syntaxfuzzer.native [type string] [lb int] [ub int] [n int] 9 | 10 | -type : specify instruction set to fuzz (gp or fp) 11 | -lb : set the lowerbound 12 | -ub : set the upperbound 13 | -n : set number of runs 14 | 15 | example: ./syntaxfuzzer.native -type fp -lb 0 -ub 30 -n 10000 16 | -------------------------------------------------------------------------------- /x86model/fuzz/instr_fuzz/abbrev.ml: -------------------------------------------------------------------------------- 1 | (** Some abbreviation functions to make it less painful to use certain functions *) 2 | 3 | open Bits 4 | 5 | let bii = Big_int.big_int_of_int 6 | let unsigned1 = (Word.unsigned (bii 0)) 7 | let unsigned3 = (Word.unsigned (bii 2)) 8 | let unsigned8 = (Word.unsigned (bii 7)) 9 | let unsigned16 = (Word.unsigned (bii 15)) 10 | let unsigned32 = (Word.unsigned (bii 31)) 11 | let signed8 = (Word.signed (bii 7)) 12 | let signed32 = (Word.signed (bii 31)) 13 | 14 | let zero32 = (Word.zero (bii 311)) 15 | 16 | let int8_of_int i = Word.repr (bii 7) (bii i) 17 | 18 | let print_hex h = Printf.printf "%0xLx" h 19 | let sprint_hex h = Printf.sprintf "0x%Lx" h 20 | let print_bigint x = print_string (Big_int.string_of_big_int x) 21 | let hex_of_big x = sprint_hex (Big_int.int64_of_big_int x) 22 | 23 | (** Convert an unsigned 32-bit bitvector to its hex string *) 24 | let unsigned32_to_hex c = hex_of_big (unsigned32 c) 25 | 26 | let signed32_to_hex c = 27 | let d = signed32 c in 28 | if (Big_int.sign_big_int d >= 0) then hex_of_big d 29 | else "-" ^ hex_of_big (Big_int.abs_big_int d) 30 | -------------------------------------------------------------------------------- /x86model/fuzz/instr_fuzz/extract/Makefile: -------------------------------------------------------------------------------- 1 | all: test 2 | 3 | test: 4 | ocamlbuild -cflag -g -lflag -g test.native -lib unix -lib nums 5 | 6 | profiling:: 7 | ocamlbuild -cflag -g -lflag -g test.p.native -lib unix -lib nums 8 | 9 | extraction:: 10 | coqc extract.v -I "../../../Model/" 11 | cp patch/*.ml . 12 | rm Parser.mli Decode.mli 13 | 14 | clean:: 15 | rm -f *.ml *.mli *.glob *.vo 16 | -------------------------------------------------------------------------------- /x86model/fuzz/instr_fuzz/extract/extract.v: -------------------------------------------------------------------------------- 1 | (* Extract an OCaml decoder from the Coq x86 model *) 2 | 3 | (* Map nat to OCaml big_int *) 4 | Require ExtrOcamlNatBigInt. 5 | (* Map Z and pos to OCaml big_int *) 6 | Require ExtrOcamlZBigInt. 7 | 8 | (* bypassing the extraction of opaque constants *) 9 | Set Extraction AccessOpaque. 10 | 11 | Extract Inductive sigT => "(*)" [ "(,)" ]. 12 | 13 | Require Import Decode. 14 | Extraction Blacklist String List. 15 | Recursive Extraction Library Decode. 16 | 17 | (* Require Import NewDecode. *) 18 | (* Recursive Extraction Library NewDecode. *) 19 | 20 | Require Import Encode. 21 | Recursive Extraction Library Encode. 22 | 23 | (* Require Import ElfDecode. 24 | Recursive Extraction Library ElfDecode. 25 | *) 26 | -------------------------------------------------------------------------------- /x86model/fuzz/instr_fuzz/extract/patch/big.ml: -------------------------------------------------------------------------------- 1 | (************************************************************************) 2 | (* v * The Coq Proof Assistant / The Coq Development Team *) 3 | (* 0 then fp z else fn (opp z) 137 | 138 | let compare_case e l g x y = 139 | let s = compare x y in if s = 0 then e else if s<0 then l else g 140 | 141 | let nat_rec fO fS = 142 | let rec loop acc n = 143 | if sign n <= 0 then acc else loop (fS acc) (pred n) 144 | in loop fO 145 | 146 | let positive_rec f2p1 f2p f1 = 147 | let rec loop n = 148 | if le n one then f1 149 | else 150 | let (q,r) = quomod n two in 151 | if eq r zero then f2p (loop q) else f2p1 (loop q) 152 | in loop 153 | 154 | let z_rec fO fp fn = z_case (fun _ -> fO) fp fn 155 | -------------------------------------------------------------------------------- /x86model/fuzz/instr_fuzz/extract/patch/extrOcamlBigIntConv.ml: -------------------------------------------------------------------------------- 1 | open BinInt 2 | open BinNat 3 | open BinPos 4 | open Datatypes 5 | 6 | (** val bigint_of_nat : nat -> Big.big_int **) 7 | 8 | let bigint_of_nat x = 9 | let rec loop acc = function 10 | | O -> acc 11 | | S n0 -> loop (Big.succ acc) n0 12 | in loop Big.zero x 13 | 14 | (** val bigint_of_pos : positive -> Big.big_int **) 15 | 16 | let rec bigint_of_pos = function 17 | | Coq_xI p0 -> Big.succ (Big.double (bigint_of_pos p0)) 18 | | Coq_xO p0 -> Big.double (bigint_of_pos p0) 19 | | Coq_xH -> Big.succ Big.zero 20 | 21 | (** val bigint_of_z : coq_Z -> Big.big_int **) 22 | 23 | let rec bigint_of_z = function 24 | | Z0 -> Big.zero 25 | | Zpos p -> bigint_of_pos p 26 | | Zneg p -> Big.opp (bigint_of_pos p) 27 | 28 | (** val bigint_of_n : coq_N -> Big.big_int **) 29 | 30 | let rec bigint_of_n = function 31 | | N0 -> Big.zero 32 | | Npos p -> bigint_of_pos p 33 | 34 | (** val bigint_natlike_rec : 'a1 -> ('a1 -> 'a1) -> Big.big_int -> 'a1 **) 35 | 36 | let bigint_natlike_rec = Big.nat_rec 37 | 38 | (** val nat_of_bigint : Big.big_int -> nat **) 39 | 40 | let nat_of_bigint x = 41 | bigint_natlike_rec O (fun x0 -> S x0) x 42 | 43 | (** val bigint_poslike_rec : 44 | ('a1 -> 'a1) -> ('a1 -> 'a1) -> 'a1 -> Big.big_int -> 'a1 **) 45 | 46 | let bigint_poslike_rec = Big.positive_rec 47 | 48 | (** val pos_of_bigint : Big.big_int -> positive **) 49 | 50 | let pos_of_bigint x = 51 | bigint_poslike_rec (fun x0 -> Coq_xI x0) (fun x0 -> Coq_xO x0) Coq_xH x 52 | 53 | (** val bigint_zlike_case : 54 | 'a1 -> (Big.big_int -> 'a1) -> (Big.big_int -> 'a1) -> Big.big_int -> 'a1 **) 55 | 56 | let bigint_zlike_case = Big.z_rec 57 | 58 | (** val z_of_bigint : Big.big_int -> coq_Z **) 59 | 60 | let z_of_bigint x = 61 | bigint_zlike_case Z0 (fun i -> Zpos (pos_of_bigint i)) (fun i -> Zneg 62 | (pos_of_bigint i)) x 63 | 64 | (** val n_of_bigint : Big.big_int -> coq_N **) 65 | 66 | let n_of_bigint x = 67 | bigint_zlike_case N0 (fun i -> Npos (pos_of_bigint i)) (fun x0 -> N0) x 68 | 69 | -------------------------------------------------------------------------------- /x86model/fuzz/instr_fuzz/test.ml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gangtan/CPUmodels/a6decc3085e1f8d8d4875e67f9ad9c7663910f8a/x86model/fuzz/instr_fuzz/test.ml -------------------------------------------------------------------------------- /x86model/fuzz/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $# != 2 ] 4 | then 5 | echo Usage: ./run.sh executable end_symbol 6 | else 7 | if [ -e $1 ] 8 | then 9 | echo Instrumentation 10 | setarch i386 -R $PIN_PATH/pin -injection child -t ../semantics_trace/memlist.so -e "$2" -- ./$1 11 | sort memaddrs.txt > tmp0 12 | uniq tmp0 > memaddrs.txt 13 | setarch i386 -R $PIN_PATH/pin -injection child -t ../semantics_trace/gntrace.so -e "$2" -- ./$1 14 | else 15 | echo $1 does not exist. 16 | fi 17 | fi 18 | -------------------------------------------------------------------------------- /x86model/fuzz/test.c: -------------------------------------------------------------------------------- 1 | void _binary_fuzz_hex_start(); 2 | 3 | int main() { 4 | _binary_fuzz_hex_start(); 5 | } 6 | -------------------------------------------------------------------------------- /x86model/gdb_smtrace/.gdbinit: -------------------------------------------------------------------------------- 1 | set logging off 2 | set confirm off 3 | set height 0 4 | set output-radix 0x10 5 | set input-radix 0x10 6 | 7 | set print pretty on 8 | set print address on 9 | set print demangle off 10 | set print thread-events off 11 | set print symbol-filename off 12 | set print static-members off 13 | set print pascal_static-members off 14 | set print union off 15 | set print entry-values no 16 | set disassembly-flavor intel 17 | 18 | #break main 19 | #break __libc_start_main 20 | #break exit 21 | start 22 | 23 | define println 24 | printf "\n" 25 | end 26 | 27 | define printf_fp_regs 28 | set logging on 29 | 30 | #this doesn't work as $st0..$st7 store 31 | #the actual floating-point values, and 32 | #printf truncates them to ints 33 | # printf "st0: %08x\n", $st0 34 | # printf "st1: %08x\n", $st1 35 | # printf "st2: %08x\n", $st2 36 | # printf "st3: %08x\n", $st3 37 | # printf "st4: %08x\n", $st4 38 | # printf "st5: %08x\n", $st5 39 | # printf "st6: %08x\n", $st6 40 | # printf "st7: %08x\n", $st7 41 | 42 | #this trick doesn't work either because 43 | #convenience variable addresses can't be accessed. 44 | # if $st7 45 | # set $tmpp = * (int *)(&$st7) 46 | # end 47 | 48 | #for now, this will have to do 49 | info registers $st0 50 | info registers $st1 51 | info registers $st2 52 | info registers $st3 53 | info registers $st4 54 | info registers $st5 55 | info registers $st6 56 | info registers $st7 57 | 58 | 59 | printf "fctrl: %08x\n", $fctrl 60 | printf "fstat: %08x\n", $fstat 61 | printf "ftag: %08x\n", $ftag 62 | printf "fiseg: %08x\n", $fiseg 63 | printf "fioff: %08x\n", $fioff 64 | printf "foseg: %08x\n", $foseg 65 | printf "fooff: %08x\n", $fooff 66 | printf "fop: %08x\n", $fop 67 | println 68 | 69 | set logging off 70 | end 71 | 72 | define print_gp_regs 73 | set logging on 74 | #info registers 75 | println 76 | 77 | printf "eax: %08x\n", $eax 78 | printf "ecx: %08x\n", $ecx 79 | printf "edx: %08x\n", $edx 80 | printf "ebx: %08x\n", $ebx 81 | printf "esp: %08x\n", $esp 82 | printf "ebp: %08x\n", $ebp 83 | printf "esi: %08x\n", $esi 84 | printf "edi: %08x\n", $edi 85 | printf "eip: %08x\n", $eip 86 | printf "eflags: %08x\n", $eflags 87 | printf "cs: %08x\n", $cs 88 | printf "ss: %08x\n", $ss 89 | printf "ds: %08x\n", $ds 90 | printf "es: %08x\n", $es 91 | printf "fs: %08x\n", $fs 92 | printf "gs: %08x\n", $gs 93 | println 94 | set logging off 95 | end 96 | 97 | define print_all_info 98 | set logging on 99 | info all-registers 100 | set logging off 101 | end 102 | 103 | define print_address 104 | set logging on 105 | println 106 | 107 | #Output 4 words of data memory going back from the stack pointer 108 | x/24xw $sp 109 | 110 | # x/20w main 111 | # x/4w $pc 112 | # what (0x843e58955) 113 | # print $pc 114 | # where 115 | # x/i $pc 116 | # mem 804a000 0 117 | # x/5i 8049000 118 | # printf "current memory addr: %08x\n", $pc 119 | # printf "disassembly:\n" 120 | # disassemble /r 121 | # x/100xw $pc 122 | # println 123 | # info mem 124 | #The command below (info proc mappings) is promising to get the starting and ending address 125 | #locations 126 | # info proc mappings 127 | # info proc 128 | # info files 129 | # maintenance info sections 130 | set logging off 131 | end 132 | 133 | define smtrace 134 | step 135 | set $count = 0 136 | 137 | #hacky, but so far the only way I can detect when program ends 138 | #this is the address of libc_start_main 139 | while ($pc != 400524d3) 140 | set logging on 141 | output $ps 142 | println 143 | printf "***iteration #: %i \n", $count 144 | println 145 | set logging off 146 | print_gp_regs 147 | printf_fp_regs 148 | # print_all_info 149 | # print_address 150 | set $count++ 151 | nexti 152 | # stepi 153 | end 154 | end 155 | 156 | smtrace 157 | continue 158 | 159 | printf "finished running smtrace\n" 160 | 161 | quit 162 | -------------------------------------------------------------------------------- /x86model/gdb_smtrace/Makefile: -------------------------------------------------------------------------------- 1 | 2 | smtrace: 3 | gcc -g main.c -o main -lm 4 | rm gdb.txt 5 | rm instrs.txt 6 | cp gdb_init .gdbinit 7 | objdump -D main > instrs.txt 8 | gdb --eval-command=run --eval-command=quit --args main -------------------------------------------------------------------------------- /x86model/gdb_smtrace/README: -------------------------------------------------------------------------------- 1 | Uses gdb macros to step through a test program named main.c and dumps out state of all registers and memory operands at every step. Macros (a.k.a commands) are stored in gdb_init and are copied over to .gdbinit at compile-time. 2 | 3 | To run: make smtrace 4 | -Results are dumped to gdb.txt 5 | -Static assembler instructions are objdumped to instrs.txt 6 | 7 | Note: If gdb.txt or instrs.txt doesn't exist, just run touch gdb.txt or touch instrs.txt then run make smtrace 8 | 9 | -------------------------------------------------------------------------------- /x86model/gdb_smtrace/gdb_init: -------------------------------------------------------------------------------- 1 | set logging off 2 | set confirm off 3 | set height 0 4 | set output-radix 0x10 5 | set input-radix 0x10 6 | 7 | set print pretty on 8 | set print address on 9 | set print demangle off 10 | set print thread-events off 11 | set print symbol-filename off 12 | set print static-members off 13 | set print pascal_static-members off 14 | set print union off 15 | set print entry-values no 16 | set disassembly-flavor intel 17 | 18 | #break main 19 | #break __libc_start_main 20 | #break exit 21 | start 22 | 23 | define println 24 | printf "\n" 25 | end 26 | 27 | define printf_fp_regs 28 | set logging on 29 | 30 | #this doesn't work as $st0..$st7 store 31 | #the actual floating-point values, and 32 | #printf truncates them to ints 33 | # printf "st0: %08x\n", $st0 34 | # printf "st1: %08x\n", $st1 35 | # printf "st2: %08x\n", $st2 36 | # printf "st3: %08x\n", $st3 37 | # printf "st4: %08x\n", $st4 38 | # printf "st5: %08x\n", $st5 39 | # printf "st6: %08x\n", $st6 40 | # printf "st7: %08x\n", $st7 41 | 42 | #this trick doesn't work either because 43 | #convenience variable addresses can't be accessed. 44 | # if $st7 45 | # set $tmpp = * (int *)(&$st7) 46 | # end 47 | 48 | #for now, this will have to do 49 | info registers $st0 50 | info registers $st1 51 | info registers $st2 52 | info registers $st3 53 | info registers $st4 54 | info registers $st5 55 | info registers $st6 56 | info registers $st7 57 | 58 | 59 | printf "fctrl: %08x\n", $fctrl 60 | printf "fstat: %08x\n", $fstat 61 | printf "ftag: %08x\n", $ftag 62 | printf "fiseg: %08x\n", $fiseg 63 | printf "fioff: %08x\n", $fioff 64 | printf "foseg: %08x\n", $foseg 65 | printf "fooff: %08x\n", $fooff 66 | printf "fop: %08x\n", $fop 67 | println 68 | 69 | set logging off 70 | end 71 | 72 | define print_gp_regs 73 | set logging on 74 | #info registers 75 | println 76 | 77 | printf "eax: %08x\n", $eax 78 | printf "ecx: %08x\n", $ecx 79 | printf "edx: %08x\n", $edx 80 | printf "ebx: %08x\n", $ebx 81 | printf "esp: %08x\n", $esp 82 | printf "ebp: %08x\n", $ebp 83 | printf "esi: %08x\n", $esi 84 | printf "edi: %08x\n", $edi 85 | printf "eip: %08x\n", $eip 86 | printf "eflags: %08x\n", $eflags 87 | printf "cs: %08x\n", $cs 88 | printf "ss: %08x\n", $ss 89 | printf "ds: %08x\n", $ds 90 | printf "es: %08x\n", $es 91 | printf "fs: %08x\n", $fs 92 | printf "gs: %08x\n", $gs 93 | println 94 | set logging off 95 | end 96 | 97 | define print_all_info 98 | set logging on 99 | info all-registers 100 | set logging off 101 | end 102 | 103 | define print_address 104 | set logging on 105 | println 106 | 107 | #Output 4 words of data memory going back from the stack pointer 108 | x/24xw $sp 109 | 110 | # x/20w main 111 | # x/4w $pc 112 | # what (0x843e58955) 113 | # print $pc 114 | # where 115 | # x/i $pc 116 | # mem 804a000 0 117 | # x/5i 8049000 118 | # printf "current memory addr: %08x\n", $pc 119 | # printf "disassembly:\n" 120 | # disassemble /r 121 | # x/100xw $pc 122 | # println 123 | # info mem 124 | #The command below (info proc mappings) is promising to get the starting and ending address 125 | #locations 126 | # info proc mappings 127 | # info proc 128 | # info files 129 | # maintenance info sections 130 | set logging off 131 | end 132 | 133 | define smtrace 134 | step 135 | set $count = 0 136 | 137 | #hacky, but so far the only way I can detect when program ends 138 | #this is the address of libc_start_main 139 | while ($pc != 400524d3) 140 | set logging on 141 | output $ps 142 | println 143 | printf "***iteration #: %i \n", $count 144 | println 145 | set logging off 146 | print_gp_regs 147 | printf_fp_regs 148 | # print_all_info 149 | # print_address 150 | set $count++ 151 | nexti 152 | # stepi 153 | end 154 | end 155 | 156 | smtrace 157 | continue 158 | 159 | printf "finished running smtrace\n" 160 | 161 | quit 162 | -------------------------------------------------------------------------------- /x86model/gdb_smtrace/instrs.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gangtan/CPUmodels/a6decc3085e1f8d8d4875e67f9ad9c7663910f8a/x86model/gdb_smtrace/instrs.txt -------------------------------------------------------------------------------- /x86model/gdb_smtrace/main: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gangtan/CPUmodels/a6decc3085e1f8d8d4875e67f9ad9c7663910f8a/x86model/gdb_smtrace/main -------------------------------------------------------------------------------- /x86model/gdb_smtrace/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | float test(float a, float b) { 5 | float c = a / b; 6 | float d = c + c * 2.43414 - a * b; 7 | float e = c * d * d; 8 | double f = d - c + 3.1423423424 * 9999.0 * d * d * d * d * d + c * e - (d + e - c * a/b * b); 9 | double g = c - d * 2 + e + pow(2, 3); 10 | 11 | int i = (int)f; 12 | 13 | return c * d * e / f + g; 14 | } 15 | 16 | /*float test2(float a, float b) { 17 | double val = log2(a) + log2(b); 18 | double root = sqrt(sqrt(sqrt(val))); 19 | double s = pow(sin(root), 2) + pow(cos(root), 2); 20 | 21 | return s * val + sinh(root); 22 | } 23 | */ 24 | 25 | 26 | int main() { 27 | int i = 0; 28 | float a = 1.2, b = 3.4; 29 | 30 | printf("product: %f\n", (a * b)); 31 | 32 | printf("test: %f\n", test(a, b)); 33 | // printf("test 2: %f\n", test2(a + b, a * b)); 34 | printf ("float print test: %x\n", *(int*)&b); 35 | 36 | return 0; 37 | } 38 | 39 | 40 | /* 41 | int iter(int n) { 42 | int i = 0; 43 | int res = 1; 44 | for(i = 1; i <= n; i++) { 45 | res *= i; 46 | } 47 | return res; 48 | } 49 | 50 | int rec(int n) { 51 | if(n == 0) return 1; 52 | return n * rec(n-1); 53 | } 54 | 55 | 56 | int fin () { 57 | return -1; 58 | 59 | } 60 | 61 | int main() { 62 | int res1 = rec(4); 63 | int res2 = iter(4); 64 | fin(); 65 | return 0; 66 | } 67 | */ -------------------------------------------------------------------------------- /x86model/gdb_smtrace/main.s: -------------------------------------------------------------------------------- 1 | .file "main.c" 2 | .text 3 | .globl test 4 | .type test, @function 5 | test: 6 | .LFB0: 7 | .cfi_startproc 8 | pushl %ebp 9 | .cfi_def_cfa_offset 8 10 | .cfi_offset 5, -8 11 | movl %esp, %ebp 12 | .cfi_def_cfa_register 5 13 | subl $40, %esp 14 | flds 8(%ebp) 15 | fdivs 12(%ebp) 16 | fstps -20(%ebp) 17 | flds -20(%ebp) 18 | flds -20(%ebp) 19 | fldl .LC0 20 | fmulp %st, %st(1) 21 | faddp %st, %st(1) 22 | flds 8(%ebp) 23 | fmuls 12(%ebp) 24 | fsubrp %st, %st(1) 25 | fstps -16(%ebp) 26 | flds -20(%ebp) 27 | fmuls -16(%ebp) 28 | fmuls -16(%ebp) 29 | fstps -12(%ebp) 30 | flds -16(%ebp) 31 | fsubs -20(%ebp) 32 | flds -16(%ebp) 33 | fldl .LC1 34 | fmulp %st, %st(1) 35 | flds -16(%ebp) 36 | fmulp %st, %st(1) 37 | flds -16(%ebp) 38 | fmulp %st, %st(1) 39 | flds -16(%ebp) 40 | fmulp %st, %st(1) 41 | flds -16(%ebp) 42 | fmulp %st, %st(1) 43 | faddp %st, %st(1) 44 | flds -20(%ebp) 45 | fmuls -12(%ebp) 46 | faddp %st, %st(1) 47 | flds -16(%ebp) 48 | fadds -12(%ebp) 49 | flds -20(%ebp) 50 | fmuls 8(%ebp) 51 | fdivs 12(%ebp) 52 | fmuls 12(%ebp) 53 | fsubrp %st, %st(1) 54 | fsubrp %st, %st(1) 55 | fstps -8(%ebp) 56 | flds -8(%ebp) 57 | fnstcw -38(%ebp) 58 | movzwl -38(%ebp), %eax 59 | movb $12, %ah 60 | movw %ax, -40(%ebp) 61 | fldcw -40(%ebp) 62 | fistpl -4(%ebp) 63 | fldcw -38(%ebp) 64 | flds -20(%ebp) 65 | fmuls -16(%ebp) 66 | fmuls -12(%ebp) 67 | leave 68 | .cfi_restore 5 69 | .cfi_def_cfa 4, 4 70 | ret 71 | .cfi_endproc 72 | .LFE0: 73 | .size test, .-test 74 | .section .rodata 75 | .LC5: 76 | .string "product: %f" 77 | .LC6: 78 | .string "test: %f" 79 | .text 80 | .globl main 81 | .type main, @function 82 | main: 83 | .LFB1: 84 | .cfi_startproc 85 | pushl %ebp 86 | .cfi_def_cfa_offset 8 87 | .cfi_offset 5, -8 88 | movl %esp, %ebp 89 | .cfi_def_cfa_register 5 90 | andl $-16, %esp 91 | subl $32, %esp 92 | movl $0, 20(%esp) 93 | movl $0x3f99999a, %eax 94 | movl %eax, 24(%esp) 95 | movl $0x4059999a, %eax 96 | movl %eax, 28(%esp) 97 | flds 24(%esp) 98 | fmuls 28(%esp) 99 | fstpl 4(%esp) 100 | movl $.LC5, (%esp) 101 | call printf 102 | movl 28(%esp), %eax 103 | movl %eax, 4(%esp) 104 | movl 24(%esp), %eax 105 | movl %eax, (%esp) 106 | call test 107 | fstpl 4(%esp) 108 | movl $.LC6, (%esp) 109 | call printf 110 | leave 111 | .cfi_restore 5 112 | .cfi_def_cfa 4, 4 113 | ret 114 | .cfi_endproc 115 | .LFE1: 116 | .size main, .-main 117 | .section .rodata 118 | .align 8 119 | .LC0: 120 | .long 1685001570 121 | .long 1073969438 122 | .align 8 123 | .LC1: 124 | .long -46273606 125 | .long 1088335633 126 | .ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3" 127 | .section .note.GNU-stack,"",@progbits 128 | -------------------------------------------------------------------------------- /x86model/gdb_smtrace/tmp.txt: -------------------------------------------------------------------------------- 1 | Reading symbols from /home/ubuntu/Desktop/objdump_practice/main...done. 2 | Breakpoint 1 at 0x804848f: file main.c, line 14. 3 | 4 | Breakpoint 1, main () at main.c:14 5 | 14 int i = 0, done = 0; 6 | 15 float a = 1.2, b = 3.4; 7 | 8 | ***step number: 0 9 | 10 | st0: 00000000 11 | 0x080484a4 15 float a = 1.2, b = 3.4; 12 | 13 | ***step number: 1 14 | 15 | st0: 00000000 16 | 0x080484a8 15 float a = 1.2, b = 3.4; 17 | 18 | ***step number: 2 19 | 20 | st0: 00000000 21 | 0x080484ad 15 float a = 1.2, b = 3.4; 22 | 23 | ***step number: 3 24 | 25 | st0: 00000000 26 | 17 printf("product: %f", (a * b)); 27 | 28 | ***step number: 4 29 | 30 | st0: 00000000 31 | 0x080484b5 17 printf("product: %f", (a * b)); 32 | 33 | ***step number: 5 34 | 35 | st0: 00000001 36 | 0x080484b9 17 printf("product: %f", (a * b)); 37 | 38 | ***step number: 6 39 | 40 | st0: 00000004 41 | 0x080484bd 17 printf("product: %f", (a * b)); 42 | 43 | ***step number: 7 44 | 45 | st0: 00000000 46 | 0x080484c4 17 printf("product: %f", (a * b)); 47 | 48 | ***step number: 8 49 | 50 | st0: 00000000 51 | 0x08048300 in printf@plt () 52 | 53 | ***step number: 9 54 | 55 | st0: 00000000 56 | 0x08048306 in printf@plt () 57 | 58 | ***step number: 10 59 | 60 | st0: 00000000 61 | 0x0804830b in printf@plt () 62 | A debugging session is active. 63 | 64 | Inferior 1 [process 3975] will be killed. 65 | 66 | Quit anyway? (y or n) [answered Y; input not from terminal] 67 | -------------------------------------------------------------------------------- /x86model/semantics_trace/Makefile: -------------------------------------------------------------------------------- 1 | all:: 2 | make -C "./tracer/" 3 | cp ./tracer/gntrace.so ./ 4 | cp ./tracer/memlist.so ./ 5 | make -C "./simulator/" 6 | cp ./simulator/test.native ./ 7 | 8 | 9 | -------------------------------------------------------------------------------- /x86model/semantics_trace/README: -------------------------------------------------------------------------------- 1 | *** CAUTION : This is only tested and known to work on Linux systems 2 | 3 | Overview: 4 | --------------- 5 | 6 | This is a tool for testing the X86 semantics and parser. It consists of two 7 | parts: a tracer (gntrace, memlist) and simulators (test.native). 8 | 9 | The tracer runs a binary and uses Intel's Pin instrumentation tool to record 10 | the values of various regisers and memory locations as the program runs and 11 | then outputs them in "mem0.txt", "mem1.txt", and "regs.txt". The tracer stops 12 | the program after a certain number of instructions have been executed or a 13 | pre-defined stop symbol is reached. 14 | 15 | The memory values/addresses stored in the mem.txt files are addresses 16 | containing instructions that were decoded and any other memory addresses 17 | accessed while the program was being traced (ie: memory operands). 18 | 19 | The simulator then reads in the memory dump and copies the initial set of 20 | register values. It then steps through instruction by instruction, comparing 21 | the register values it gets with the ones in the file. 22 | 23 | Requirements: 24 | -------------- 25 | 26 | You need Intel's Pin analysis tool. It's pretty cool. Available from: 27 | http://www.pintool.org/ 28 | 29 | The simulator part requires ocamlbuild. I've only tested it on Ocaml 3.10+. 30 | 31 | 32 | Usage: 33 | -------------- 34 | 35 | First, you need to export $PIN_PATH in your bash environment, and it should 36 | point to the top level of the pin tool. 37 | 38 | To build, first go to the simulator/ directory and do "make extraction". This 39 | extracts the Coq code to Ocaml and sets everything up. Then run "make" in the 40 | semantics_trace/ directory. This runs the make files in tracer/ and simulator/ 41 | and then copies the resulting binaries to the toplevel. 42 | 43 | To generate a trace of a C program called "test.c" do: 44 | > ./run.sh test.c ./test.native "mem0.txt" "regs0.txt" "mem1.txt" 54 | 55 | These will output the simulator's register values after each instruction (in a 56 | format similar to regs.txt). If at some point the register values do not match 57 | the corresponding values in regs.txt or the "Failed" state is reached in the 58 | simulator, it stops. If all of the register values match, it does a diff of 59 | memory in the simulator against the memory values listed in mem1.txt. 60 | -------------------------------------------------------------------------------- /x86model/semantics_trace/elf.ml: -------------------------------------------------------------------------------- 1 | (* Copyright (c) 2011. Greg Morrisett, Gang Tan, Joseph Tassarotti, 2 | Jean-Baptiste Tristan, and Edward Gan. 3 | 4 | This file is part of RockSalt. 5 | 6 | This file is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License as 8 | published by the Free Software Foundation; either version 2 of 9 | the License, or (at your option) any later version. 10 | *) 11 | 12 | (* Loader for NaClVerifier. *) 13 | 14 | let ei_nident = 16 15 | type elf_half = Int64.t 16 | type elf_word = Int64.t 17 | type elf_addr = Int64.t 18 | type elf_off = Int64.t 19 | 20 | (* Watch out for endianess!!! *) 21 | let read_n_bytes n chan = 22 | let rec read_n_aux n l = 23 | if n = 0 then l else read_n_aux (n-1) (input_byte chan :: l) 24 | in 25 | read_n_aux n [] 26 | ;; 27 | 28 | let bytes_to_int64 l = 29 | let rec bytes_to_int l pos i = 30 | match l with 31 | | [] -> i 32 | | b :: l -> bytes_to_int l (pos - 1) (Int64.add i (Int64.shift_left (Int64.of_int b) (pos * 8))) 33 | in 34 | bytes_to_int l (List.length l - 1) (Int64.zero) 35 | ;; 36 | 37 | let convert_n_bytes n chan = bytes_to_int64 (read_n_bytes n chan) 38 | 39 | (* The following four definitions must be changed depending on the architecture *) 40 | let read_half chan = convert_n_bytes 2 chan 41 | let read_word chan = convert_n_bytes 4 chan 42 | let read_addr chan = convert_n_bytes 4 chan 43 | let read_off chan = convert_n_bytes 4 chan 44 | 45 | type file_header = { 46 | e_ident: (int list); (* Magic number and other info *) 47 | e_type: elf_half; (* Object file type *) 48 | e_machine: elf_half; (* Architecture *) 49 | e_version: elf_word; (* Object file version *) 50 | e_entry: elf_addr; (* Entry point virtual address *) 51 | e_phoff: elf_off; (* Program header table file offset *) 52 | e_shoff: elf_off; (* Section header table file offset *) 53 | e_flags: elf_word; (* Processor-specific flags *) 54 | e_ehsize: elf_half; (* ELF header size in bytes *) 55 | e_phentsize: elf_half; (* Program header table entry size *) 56 | e_phnum: elf_half; (* Program header table entry count *) 57 | e_shentsize: elf_half; (* Section header table entry size *) 58 | e_shnum: elf_half; (* Section header table entry count *) 59 | e_shstrndx: elf_half; (* Section header string table index *) 60 | };; 61 | 62 | let read_file_header chan : file_header = 63 | let e_ident = read_n_bytes ei_nident chan in 64 | let e_type = read_half chan in 65 | let e_machine = read_half chan in 66 | let e_version = read_word chan in 67 | let e_entry = read_addr chan in 68 | let e_phoff = read_off chan in 69 | let e_shoff = read_off chan in 70 | let e_flags = read_word chan in 71 | let e_ehsize = read_half chan in 72 | let e_phentsize = read_half chan in 73 | let e_phnum = read_half chan in 74 | let e_shentsize = read_half chan in 75 | let e_shnum = read_half chan in 76 | let e_shstrndx = read_half chan in 77 | { 78 | e_ident = e_ident; 79 | e_type = e_type; 80 | e_machine = e_machine; 81 | e_version = e_version; 82 | e_entry = e_entry; 83 | e_phoff = e_phoff; 84 | e_shoff = e_shoff; 85 | e_flags = e_flags; 86 | e_ehsize = e_ehsize; 87 | e_phentsize = e_phentsize; 88 | e_phnum = e_phnum; 89 | e_shentsize = e_shentsize; 90 | e_shnum = e_shnum; 91 | e_shstrndx = e_shstrndx; 92 | };; 93 | 94 | let print_file_header fh = 95 | Printf.printf "Type: %i\n" (Int64.to_int fh.e_type); 96 | Printf.printf "Machine: %i\n" (Int64.to_int fh.e_machine); 97 | Printf.printf "Version: 0x%x\n" (Int64.to_int fh.e_version); 98 | Printf.printf "Entry point address: 0x%x\n" (Int64.to_int fh.e_entry); 99 | Printf.printf "Size of this header: %i bytes\n" (Int64.to_int fh.e_ehsize); 100 | Printf.printf "Size of program headers: %i bytes\n" (Int64.to_int fh.e_phentsize); 101 | Printf.printf "Number of program headers: %i\n" (Int64.to_int fh.e_phnum); 102 | Printf.printf "Size of section headers: %i bytes\n" (Int64.to_int fh.e_shentsize); 103 | Printf.printf "Number of section headers: %i\n" (Int64.to_int fh.e_shnum); 104 | Printf.printf "Section header string table index: %i\n" (Int64.to_int fh.e_shstrndx) 105 | ;; 106 | 107 | type section_header = { 108 | sh_name: elf_word; (* Section name (string tbl index) *) 109 | sh_type: elf_word; (* Section type *) 110 | sh_flags: elf_word; (* Section flags *) 111 | sh_addr: elf_addr; (* Section virtual addr at execution *) 112 | sh_offset:elf_off; (* Section file offset *) 113 | sh_size: elf_word; (* Section size in bytes *) 114 | sh_link: elf_word; (* Link to another section *) 115 | sh_info: elf_word; (* Additional section information *) 116 | sh_addralign: elf_word; (* Section alignment *) 117 | sh_entsize: elf_word; (* Entry size if section holds table *) 118 | };; 119 | 120 | let read_section_header chan : section_header = 121 | let sh_name = read_word chan in 122 | let sh_type = read_word chan in 123 | let sh_flags = read_word chan in 124 | let sh_addr = read_addr chan in 125 | let sh_offset = read_off chan in 126 | let sh_size = read_word chan in 127 | let sh_link = read_word chan in 128 | let sh_info = read_word chan in 129 | let sh_addralign = read_word chan in 130 | let sh_entsize = read_word chan in 131 | { 132 | sh_name = sh_name; 133 | sh_type = sh_type; 134 | sh_flags = sh_flags; 135 | sh_addr = sh_addr; 136 | sh_offset = sh_offset; 137 | sh_size = sh_size; 138 | sh_link = sh_link; 139 | sh_info = sh_info; 140 | sh_addralign = sh_addralign; 141 | sh_entsize = sh_entsize; 142 | } 143 | 144 | let crap = Int64.to_int 145 | 146 | let goto_section_table chan fh = seek_in chan (crap fh.e_shoff);; 147 | let goto_next_section chan fh = seek_in chan (Int64.to_int fh.e_shentsize);; 148 | let goto_section_x chan fh x = 149 | seek_in chan ((crap fh.e_shoff) + x * ((Int64.to_int fh.e_shentsize))) 150 | ;; 151 | 152 | let get_string chan fh idx = 153 | goto_section_x chan fh (Int64.to_int fh.e_shstrndx); 154 | let s = read_section_header chan in 155 | seek_in chan ((crap s.sh_offset) + idx); 156 | let rec read_list l = 157 | let c = input_char chan in 158 | if (Char.code c) = 0 then List.rev (c :: l) 159 | else read_list (c :: l) 160 | in 161 | read_list [] 162 | ;; 163 | 164 | let print_string l = List.iter (Printf.printf "%c") l;; 165 | 166 | let main () = 167 | let elf = 168 | try open_in_bin Sys.argv.(1) 169 | with 170 | | Sys_error _ -> failwith "Cannot open file" 171 | in 172 | let fh = read_file_header elf in 173 | print_file_header fh; 174 | 175 | Printf.printf "\n\n\n"; 176 | Printf.printf "Start of section header: %x\n" (Int64.to_int fh.e_shoff); 177 | 178 | goto_section_table elf fh; 179 | Printf.printf "position: %i\n" (pos_in elf); 180 | goto_section_x elf fh 2; 181 | Printf.printf "position: %i\n" (pos_in elf); 182 | let s = read_section_header elf in 183 | Printf.printf "size of .text: %x\n" (Int64.to_int s.sh_size); 184 | Printf.printf "Section name: "; 185 | print_string (get_string elf fh (Int64.to_int s.sh_name)); 186 | print_newline() 187 | ;; 188 | 189 | main () 190 | -------------------------------------------------------------------------------- /x86model/semantics_trace/examples/factorial/factorial.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | int iter(int n) { 4 | int i = 0; 5 | int res = 1; 6 | for(i = 1; i <= n; i++) { 7 | res *= i; 8 | } 9 | return res; 10 | } 11 | 12 | int rec(int n) { 13 | if(n == 0) return 1; 14 | return n * rec(n-1); 15 | } 16 | 17 | 18 | int fin () { 19 | return -1; 20 | 21 | } 22 | 23 | int main() { 24 | int res1 = rec(4); 25 | int res2 = iter(4); 26 | fin(); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /x86model/semantics_trace/examples/factorial/mem.txt: -------------------------------------------------------------------------------- 1 | 080483a0 00 2 | 080483a1 00 3 | 080483a2 00 4 | 080483a3 00 5 | 080483a4 85 6 | 080483a5 c0 7 | 080483a6 74 8 | 080483a7 09 9 | 080483a8 c7 10 | 080483a9 04 11 | 080483aa 24 12 | 080483ab 1c 13 | 080483ac 9f 14 | 080483ad 04 15 | 080483ae 08 16 | 080483af ff 17 | 080483b0 d0 18 | 080483b1 c9 19 | 080483b2 c3 20 | 080483b3 90 21 | 080483b4 55 22 | 080483b5 89 23 | 080483b6 e5 24 | 080483b7 83 25 | 080483b8 ec 26 | 080483b9 10 27 | 080483ba c7 28 | 080483bb 45 29 | 080483bc fc 30 | 080483bd 00 31 | 080483be 00 32 | 080483bf 00 33 | 080483c0 00 34 | 080483c1 c7 35 | 080483c2 45 36 | 080483c3 f8 37 | 080483c4 01 38 | 080483c5 00 39 | 080483c6 00 40 | 080483c7 00 41 | 080483c8 c7 42 | 080483c9 45 43 | 080483ca fc 44 | 080483cb 01 45 | 080483cc 00 46 | 080483cd 00 47 | 080483ce 00 48 | 080483cf eb 49 | 080483d0 0e 50 | 080483d1 8b 51 | 080483d2 45 52 | 080483d3 f8 53 | 080483d4 0f 54 | 080483d5 af 55 | 080483d6 45 56 | 080483d7 fc 57 | 080483d8 89 58 | 080483d9 45 59 | 080483da f8 60 | 080483db 83 61 | 080483dc 45 62 | 080483dd fc 63 | 080483de 01 64 | 080483df 8b 65 | 080483e0 45 66 | 080483e1 fc 67 | 080483e2 3b 68 | 080483e3 45 69 | 080483e4 08 70 | 080483e5 7e 71 | 080483e6 ea 72 | 080483e7 8b 73 | 080483e8 45 74 | 080483e9 f8 75 | 080483ea c9 76 | 080483eb c3 77 | 080483ec 55 78 | 080483ed 89 79 | 080483ee e5 80 | 080483ef 83 81 | 080483f0 ec 82 | 080483f1 18 83 | 080483f2 83 84 | 080483f3 7d 85 | 080483f4 08 86 | 080483f5 00 87 | 080483f6 75 88 | 080483f7 07 89 | 080483f8 b8 90 | 080483f9 01 91 | 080483fa 00 92 | 080483fb 00 93 | 080483fc 00 94 | 080483fd eb 95 | 080483fe 12 96 | 080483ff 8b 97 | 08048400 45 98 | 08048401 08 99 | 08048402 83 100 | 08048403 e8 101 | 08048404 01 102 | 08048405 89 103 | 08048406 04 104 | 08048407 24 105 | 08048408 e8 106 | 08048409 df 107 | 0804840a ff 108 | 0804840b ff 109 | 0804840c ff 110 | 0804840d 0f 111 | 0804840e af 112 | 0804840f 45 113 | 08048410 08 114 | 08048411 c9 115 | 08048412 c3 116 | 08048413 55 117 | 08048414 89 118 | 08048415 e5 119 | 08048416 5d 120 | 08048417 c3 121 | 08048418 55 122 | 08048419 89 123 | 0804841a e5 124 | 0804841b 83 125 | 0804841c e4 126 | 0804841d f0 127 | 0804841e 83 128 | 0804841f ec 129 | 08048420 20 130 | 08048421 c7 131 | 08048422 04 132 | 08048423 24 133 | 08048424 04 134 | 08048425 00 135 | 08048426 00 136 | 08048427 00 137 | 08048428 e8 138 | 08048429 bf 139 | 0804842a ff 140 | 0804842b ff 141 | 0804842c ff 142 | 0804842d 89 143 | 0804842e 44 144 | 0804842f 24 145 | 08048430 1c 146 | 08048431 c7 147 | 08048432 04 148 | 08048433 24 149 | 08048434 04 150 | 08048435 00 151 | 08048436 00 152 | 08048437 00 153 | 08048438 e8 154 | 08048439 77 155 | 0804843a ff 156 | 0804843b ff 157 | 0804843c ff 158 | 0804843d 89 159 | 0804843e 44 160 | 0804843f 24 161 | 08048440 18 162 | 08048441 e8 163 | 08048442 cd 164 | 08048443 ff 165 | 08048444 ff 166 | 08048445 ff 167 | 08048446 b8 168 | 08048447 00 169 | 08048448 00 170 | 08048449 00 171 | 0804844a 00 172 | 0804844b c9 173 | 0804844c c3 174 | 0804844d 90 175 | 0804844e 90 176 | 0804844f 90 177 | 08048450 55 178 | 08048451 89 179 | 08048452 e5 180 | 08048453 5d 181 | 08048454 c3 182 | bf8adf9a 8a 183 | bf8adf9b bf 184 | bf8adf9c 79 185 | bf8adf9d 84 186 | bf8adf9e 04 187 | bf8adf9f 08 188 | bf8adfa0 24 189 | bf8adfa1 43 190 | bf8adfa2 6a 191 | bf8adfa3 00 192 | bf8adfa4 f4 193 | bf8adfa5 3f 194 | bf8adfa6 6a 195 | bf8adfa7 00 196 | bf8adfa8 60 197 | bf8adfa9 84 198 | bf8adfaa 04 199 | bf8adfab 08 200 | bf8adfac c8 201 | bf8adfad df 202 | bf8adfae 8a 203 | bf8adfaf bf 204 | bf8adfb0 a5 205 | bf8adfb1 d4 206 | bf8adfb2 57 207 | bf8adfb3 00 208 | bf8adfb4 30 209 | bf8adfb5 f0 210 | bf8adfb6 38 211 | bf8adfb7 00 212 | bf8adfb8 6b 213 | bf8adfb9 84 214 | bf8adfba 04 215 | bf8adfbb 08 216 | bf8adfbc f4 217 | bf8adfbd 3f 218 | bf8adfbe 6a 219 | bf8adfbf 00 220 | bf8adfc0 60 221 | bf8adfc1 84 222 | bf8adfc2 04 223 | bf8adfc3 08 224 | bf8adfc4 00 225 | bf8adfc5 00 226 | bf8adfc6 00 227 | bf8adfc7 00 228 | bf8adfc8 48 229 | bf8adfc9 e0 230 | bf8adfca 8a 231 | bf8adfcb bf 232 | bf8adfcc d6 233 | bf8adfcd 4b 234 | bf8adfce 56 235 | bf8adfcf 00 236 | bf8adfd0 01 237 | bf8adfd1 00 238 | bf8adfd2 00 239 | bf8adfd3 00 240 | bf8adfd4 74 241 | bf8adfd5 e0 242 | bf8adfd6 8a 243 | bf8adfd7 bf 244 | bf8adfd8 7c 245 | bf8adfd9 e0 246 | bf8adfda 8a 247 | bf8adfdb bf 248 | bf8adfdc 58 249 | bf8adfdd 48 250 | bf8adfde 77 251 | bf8adfdf b7 252 | bf8adfe0 30 253 | bf8adfe1 e0 254 | bf8adfe2 8a 255 | bf8adfe3 bf 256 | bf8adfe4 ff 257 | bf8adfe5 ff 258 | bf8adfe6 ff 259 | bf8adfe7 ff 260 | bf8adfe8 f4 261 | bf8adfe9 cf 262 | bf8adfea 39 263 | bf8adfeb 00 264 | bf8adfec 39 265 | bf8adfed 82 266 | bf8adfee 04 267 | bf8adfef 08 268 | bf8adff0 01 269 | bf8adff1 00 270 | bf8adff2 00 271 | bf8adff3 00 272 | bf8adff4 30 273 | bf8adff5 e0 274 | bf8adff6 8a 275 | bf8adff7 bf 276 | bf8adff8 26 277 | bf8adff9 e6 278 | bf8adffa 38 279 | bf8adffb 00 280 | bf8adffc b0 281 | bf8adffd da 282 | -------------------------------------------------------------------------------- /x86model/semantics_trace/examples/fib/fib.c: -------------------------------------------------------------------------------- 1 | 2 | // Calculates fibonacci numbers inefficiently. 3 | // 4 | 5 | #include 6 | 7 | int fib(int n) { 8 | if(n == 0) return 0; 9 | else if (n == 1) return 1; 10 | else return fib(n-1) + fib(n-2); 11 | } 12 | 13 | 14 | 15 | void fin () { } 16 | 17 | int main () { 18 | fib(4); 19 | fin(); 20 | return 0; 21 | 22 | } 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /x86model/semantics_trace/examples/fib/mem.txt: -------------------------------------------------------------------------------- 1 | 080483a0 00 2 | 080483a1 00 3 | 080483a2 00 4 | 080483a3 00 5 | 080483a4 85 6 | 080483a5 c0 7 | 080483a6 74 8 | 080483a7 09 9 | 080483a8 c7 10 | 080483a9 04 11 | 080483aa 24 12 | 080483ab 1c 13 | 080483ac 9f 14 | 080483ad 04 15 | 080483ae 08 16 | 080483af ff 17 | 080483b0 d0 18 | 080483b1 c9 19 | 080483b2 c3 20 | 080483b3 90 21 | 080483b4 55 22 | 080483b5 89 23 | 080483b6 e5 24 | 080483b7 53 25 | 080483b8 83 26 | 080483b9 ec 27 | 080483ba 14 28 | 080483bb 83 29 | 080483bc 7d 30 | 080483bd 08 31 | 080483be 00 32 | 080483bf 75 33 | 080483c0 07 34 | 080483c1 b8 35 | 080483c2 00 36 | 080483c3 00 37 | 080483c4 00 38 | 080483c5 00 39 | 080483c6 eb 40 | 080483c7 2e 41 | 080483c8 83 42 | 080483c9 7d 43 | 080483ca 08 44 | 080483cb 01 45 | 080483cc 75 46 | 080483cd 07 47 | 080483ce b8 48 | 080483cf 01 49 | 080483d0 00 50 | 080483d1 00 51 | 080483d2 00 52 | 080483d3 eb 53 | 080483d4 21 54 | 080483d5 8b 55 | 080483d6 45 56 | 080483d7 08 57 | 080483d8 83 58 | 080483d9 e8 59 | 080483da 01 60 | 080483db 89 61 | 080483dc 04 62 | 080483dd 24 63 | 080483de e8 64 | 080483df d1 65 | 080483e0 ff 66 | 080483e1 ff 67 | 080483e2 ff 68 | 080483e3 89 69 | 080483e4 c3 70 | 080483e5 8b 71 | 080483e6 45 72 | 080483e7 08 73 | 080483e8 83 74 | 080483e9 e8 75 | 080483ea 02 76 | 080483eb 89 77 | 080483ec 04 78 | 080483ed 24 79 | 080483ee e8 80 | 080483ef c1 81 | 080483f0 ff 82 | 080483f1 ff 83 | 080483f2 ff 84 | 080483f3 8d 85 | 080483f4 04 86 | 080483f5 03 87 | 080483f6 83 88 | 080483f7 c4 89 | 080483f8 14 90 | 080483f9 5b 91 | 080483fa 5d 92 | 080483fb c3 93 | 080483fc 55 94 | 080483fd 89 95 | 080483fe e5 96 | 080483ff 5d 97 | 08048400 c3 98 | 08048401 55 99 | 08048402 89 100 | 08048403 e5 101 | 08048404 83 102 | 08048405 e4 103 | 08048406 f0 104 | 08048407 83 105 | 08048408 ec 106 | 08048409 10 107 | 0804840a c7 108 | 0804840b 04 109 | 0804840c 24 110 | 0804840d 04 111 | 0804840e 00 112 | 0804840f 00 113 | 08048410 00 114 | 08048411 e8 115 | 08048412 9e 116 | 08048413 ff 117 | 08048414 ff 118 | 08048415 ff 119 | 08048416 e8 120 | 08048417 e1 121 | 08048418 ff 122 | 08048419 ff 123 | 0804841a ff 124 | 0804841b b8 125 | 0804841c 00 126 | 0804841d 00 127 | 0804841e 00 128 | 0804841f 00 129 | 08048420 c9 130 | 08048421 c3 131 | 08048422 90 132 | 08048423 90 133 | 08048424 90 134 | 08048425 90 135 | 08048426 90 136 | 08048427 90 137 | 08048428 90 138 | 08048429 90 139 | bf9e027a 9e 140 | bf9e027b bf 141 | bf9e027c 59 142 | bf9e027d 84 143 | bf9e027e 04 144 | bf9e027f 08 145 | bf9e0280 24 146 | bf9e0281 d3 147 | bf9e0282 78 148 | bf9e0283 00 149 | bf9e0284 f4 150 | bf9e0285 cf 151 | bf9e0286 78 152 | bf9e0287 00 153 | bf9e0288 40 154 | bf9e0289 84 155 | bf9e028a 04 156 | bf9e028b 08 157 | bf9e028c a8 158 | bf9e028d 02 159 | bf9e028e 9e 160 | bf9e028f bf 161 | bf9e0290 a5 162 | bf9e0291 64 163 | bf9e0292 66 164 | bf9e0293 00 165 | bf9e0294 30 166 | bf9e0295 30 167 | bf9e0296 f0 168 | bf9e0297 00 169 | bf9e0298 4b 170 | bf9e0299 84 171 | bf9e029a 04 172 | bf9e029b 08 173 | bf9e029c f4 174 | bf9e029d cf 175 | bf9e029e 78 176 | bf9e029f 00 177 | bf9e02a0 40 178 | bf9e02a1 84 179 | bf9e02a2 04 180 | bf9e02a3 08 181 | bf9e02a4 00 182 | bf9e02a5 00 183 | bf9e02a6 00 184 | bf9e02a7 00 185 | bf9e02a8 28 186 | bf9e02a9 03 187 | bf9e02aa 9e 188 | bf9e02ab bf 189 | bf9e02ac d6 190 | bf9e02ad db 191 | bf9e02ae 64 192 | bf9e02af 00 193 | bf9e02b0 01 194 | bf9e02b1 00 195 | bf9e02b2 00 196 | bf9e02b3 00 197 | bf9e02b4 54 198 | bf9e02b5 03 199 | bf9e02b6 9e 200 | bf9e02b7 bf 201 | bf9e02b8 5c 202 | bf9e02b9 03 203 | bf9e02ba 9e 204 | bf9e02bb bf 205 | bf9e02bc 58 206 | bf9e02bd 88 207 | bf9e02be 73 208 | bf9e02bf b7 209 | bf9e02c0 10 210 | bf9e02c1 03 211 | bf9e02c2 9e 212 | bf9e02c3 bf 213 | bf9e02c4 ff 214 | bf9e02c5 ff 215 | bf9e02c6 ff 216 | bf9e02c7 ff 217 | bf9e02c8 f4 218 | bf9e02c9 0f 219 | bf9e02ca f1 220 | bf9e02cb 00 221 | bf9e02cc 39 222 | bf9e02cd 82 223 | bf9e02ce 04 224 | bf9e02cf 08 225 | bf9e02d0 01 226 | bf9e02d1 00 227 | bf9e02d2 00 228 | bf9e02d3 00 229 | bf9e02d4 10 230 | bf9e02d5 03 231 | bf9e02d6 9e 232 | bf9e02d7 bf 233 | bf9e02d8 26 234 | bf9e02d9 26 235 | bf9e02da f0 236 | bf9e02db 00 237 | bf9e02dc b0 238 | bf9e02dd 1a 239 | -------------------------------------------------------------------------------- /x86model/semantics_trace/john: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | csmith --no-checksum > tmp.c 4 | gcc -w -I/home/tristan/Code/csmith-2.0.0/runtime/ -static tmp$1.c -o tmp > /dev/null 5 | setarch i386 -R $PIN_PATH/pin -injection child -t ../memlist.so -e "platform_main_end" -m 12000 -- ./tmp 6 | setarch i386 -R $PIN_PATH/pin -injection child -t ../gntrace.so -e "platform_main_end" -m 12000 -- ./tmp 7 | ../test.native "mem0.txt" "regs0.txt" > log -------------------------------------------------------------------------------- /x86model/semantics_trace/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $# != 2 ] 4 | then 5 | echo Usage: ./run.sh my_file.c end_symbol 6 | else 7 | echo Compiling $1 8 | rm test 9 | gcc -static $1 -o test 10 | if [ -e test ] 11 | then 12 | echo Instrumentation 13 | setarch i386 -R $PIN_PATH/pin -injection child -t memlist.so -e "$2" -- ./test 14 | setarch i386 -R $PIN_PATH/pin -injection child -t gntrace.so -e "$2" -- ./test 15 | else 16 | echo Compilation of $1 failed 17 | fi 18 | fi 19 | -------------------------------------------------------------------------------- /x86model/semantics_trace/simulator/Makefile: -------------------------------------------------------------------------------- 1 | all: test_step 2 | 3 | test_step: ../../Model/Parser.vo ../../Model/Decode.vo ../../Model/X86Semantics.vo 4 | ocamlbuild -cflag -g -lflag -g test.native -lib unix -lib nums 5 | 6 | 7 | ../../Model/X86Semantics.vo: ../../Model/X86Semantics.v 8 | make -C "../../Model/" 9 | coqc extract.v -I "../../Model/" 10 | 11 | ../../Model/X86Semantics.v: 12 | 13 | extract-nob:: 14 | coqc extract.v -I "../../Model/" 15 | #cp Parser.ml_fastarray Parser.ml 16 | #rm Parser.mli Decode.mli 17 | cp cZeven.ml Zeven.ml 18 | 19 | extraction:: 20 | make -C "../../Model/" 21 | coqc extract.v -I "../../Model/" 22 | #cp Parser.ml_fastarray Parser.ml 23 | #rm Parser.mli Decode.mli 24 | cp cZeven.ml Zeven.ml 25 | 26 | clean:: 27 | rm -rf _build/ 28 | -------------------------------------------------------------------------------- /x86model/semantics_trace/simulator/big.ml: -------------------------------------------------------------------------------- 1 | (************************************************************************) 2 | (* v * The Coq Proof Assistant / The Coq Development Team *) 3 | (* 0 then fp z else fn (opp z) 137 | 138 | let compare_case e l g x y = 139 | let s = compare x y in if s = 0 then e else if s<0 then l else g 140 | 141 | let nat_rec fO fS = 142 | let rec loop acc n = 143 | if sign n <= 0 then acc else loop (fS acc) (pred n) 144 | in loop fO 145 | 146 | let positive_rec f2p1 f2p f1 = 147 | let rec loop n = 148 | if le n one then f1 149 | else 150 | let (q,r) = quomod n two in 151 | if eq r zero then f2p (loop q) else f2p1 (loop q) 152 | in loop 153 | 154 | let z_rec fO fp fn = z_case (fun _ -> fO) fp fn 155 | -------------------------------------------------------------------------------- /x86model/semantics_trace/simulator/cZeven.ml: -------------------------------------------------------------------------------- 1 | open BinInt 2 | open BinPos 3 | open Datatypes 4 | 5 | (** val coq_Zeven_bool : Big.big_int -> bool **) 6 | 7 | let coq_Zeven_bool z = 8 | Big.z_case 9 | (fun _ -> true) 10 | (fun p -> 11 | Big.positive_case 12 | (fun p0 -> false) 13 | (fun p0 -> true) 14 | (fun _ -> false) 15 | p) 16 | (fun p -> 17 | Big.positive_case 18 | (fun p0 -> false) 19 | (fun p0 -> true) 20 | (fun _ -> false) 21 | p) 22 | z 23 | 24 | (** val coq_Zodd_bool : Big.big_int -> bool **) 25 | 26 | let coq_Zodd_bool z = 27 | Big.z_case 28 | (fun _ -> false) 29 | (fun p -> 30 | Big.positive_case 31 | (fun p0 -> true) 32 | (fun p0 -> false) 33 | (fun _ -> true) 34 | p) 35 | (fun p -> 36 | Big.positive_case 37 | (fun p0 -> true) 38 | (fun p0 -> false) 39 | (fun _ -> true) 40 | p) 41 | z 42 | 43 | (** val coq_Zeven_odd_dec : Big.big_int -> bool **) 44 | 45 | let coq_Zeven_odd_dec z = 46 | Big.z_case 47 | (fun _ -> true) 48 | (fun p -> 49 | Big.positive_case 50 | (fun p0 -> false) 51 | (fun p0 -> true) 52 | (fun _ -> false) 53 | p) 54 | (fun p -> 55 | Big.positive_case 56 | (fun p0 -> false) 57 | (fun p0 -> true) 58 | (fun _ -> false) 59 | p) 60 | z 61 | 62 | (** val coq_Zeven_dec : Big.big_int -> bool **) 63 | 64 | let coq_Zeven_dec z = 65 | Big.z_case 66 | (fun _ -> true) 67 | (fun p -> 68 | Big.positive_case 69 | (fun p0 -> false) 70 | (fun p0 -> true) 71 | (fun _ -> false) 72 | p) 73 | (fun p -> 74 | Big.positive_case 75 | (fun p0 -> false) 76 | (fun p0 -> true) 77 | (fun _ -> false) 78 | p) 79 | z 80 | 81 | (** val coq_Zodd_dec : Big.big_int -> bool **) 82 | 83 | let coq_Zodd_dec z = 84 | Big.z_case 85 | (fun _ -> false) 86 | (fun p -> 87 | Big.positive_case 88 | (fun p0 -> true) 89 | (fun p0 -> false) 90 | (fun _ -> true) 91 | p) 92 | (fun p -> 93 | Big.positive_case 94 | (fun p0 -> true) 95 | (fun p0 -> false) 96 | (fun _ -> true) 97 | p) 98 | z 99 | 100 | (** val coq_Zdiv2 : Big.big_int -> Big.big_int **) 101 | 102 | let coq_Zdiv2 z = 103 | Big.z_case 104 | (fun _ -> Big.zero) 105 | (fun p -> 106 | Big.positive_case 107 | (fun p0 -> (coq_Pdiv2 p)) 108 | (fun p0 -> (coq_Pdiv2 p)) 109 | (fun _ -> Big.zero) 110 | p) 111 | (fun p -> 112 | Big.positive_case 113 | (fun p0 -> Big.opp (coq_Pdiv2 p)) 114 | (fun p0 -> Big.opp (coq_Pdiv2 p)) 115 | (fun _ -> Big.zero) 116 | p) 117 | z 118 | 119 | (** val coq_Z_modulo_2 : Big.big_int -> (Big.big_int, Big.big_int) sum **) 120 | 121 | let coq_Z_modulo_2 x = 122 | if coq_Zeven_odd_dec x 123 | then Coq_inl (coq_Zdiv2 x) 124 | else Coq_inr 125 | (Big.z_case 126 | (fun _ -> assert false (* absurd case *)) 127 | (fun p -> coq_Zdiv2 p) 128 | (fun p -> coq_Zdiv2 (coq_Zpred (Big.opp p))) 129 | x) 130 | 131 | (** val coq_Zsplit2 : Big.big_int -> (Big.big_int * Big.big_int) **) 132 | 133 | let coq_Zsplit2 x = 134 | match coq_Z_modulo_2 x with 135 | | Coq_inl x0 -> (x0, x0) 136 | | Coq_inr x0 -> (x0, (coq_Zplus x0 Big.one)) 137 | 138 | -------------------------------------------------------------------------------- /x86model/semantics_trace/simulator/extrOcamlBigIntConv.ml: -------------------------------------------------------------------------------- 1 | open BinInt 2 | open BinNat 3 | open BinPos 4 | open Datatypes 5 | 6 | (** val bigint_of_nat : nat -> Big.big_int **) 7 | 8 | let bigint_of_nat x = 9 | let rec loop acc = function 10 | | O -> acc 11 | | S n0 -> loop (Big.succ acc) n0 12 | in loop Big.zero x 13 | 14 | (** val bigint_of_pos : positive -> Big.big_int **) 15 | 16 | let rec bigint_of_pos = function 17 | | Coq_xI p0 -> Big.succ (Big.double (bigint_of_pos p0)) 18 | | Coq_xO p0 -> Big.double (bigint_of_pos p0) 19 | | Coq_xH -> Big.succ Big.zero 20 | 21 | (** val bigint_of_z : coq_Z -> Big.big_int **) 22 | 23 | let rec bigint_of_z = function 24 | | Z0 -> Big.zero 25 | | Zpos p -> bigint_of_pos p 26 | | Zneg p -> Big.opp (bigint_of_pos p) 27 | 28 | (** val bigint_of_n : coq_N -> Big.big_int **) 29 | 30 | let rec bigint_of_n = function 31 | | N0 -> Big.zero 32 | | Npos p -> bigint_of_pos p 33 | 34 | (** val bigint_natlike_rec : 'a1 -> ('a1 -> 'a1) -> Big.big_int -> 'a1 **) 35 | 36 | let bigint_natlike_rec = Big.nat_rec 37 | 38 | (** val nat_of_bigint : Big.big_int -> nat **) 39 | 40 | let nat_of_bigint x = 41 | bigint_natlike_rec O (fun x0 -> S x0) x 42 | 43 | (** val bigint_poslike_rec : 44 | ('a1 -> 'a1) -> ('a1 -> 'a1) -> 'a1 -> Big.big_int -> 'a1 **) 45 | 46 | let bigint_poslike_rec = Big.positive_rec 47 | 48 | (** val pos_of_bigint : Big.big_int -> positive **) 49 | 50 | let pos_of_bigint x = 51 | bigint_poslike_rec (fun x0 -> Coq_xI x0) (fun x0 -> Coq_xO x0) Coq_xH x 52 | 53 | (** val bigint_zlike_case : 54 | 'a1 -> (Big.big_int -> 'a1) -> (Big.big_int -> 'a1) -> Big.big_int -> 'a1 **) 55 | 56 | let bigint_zlike_case = Big.z_rec 57 | 58 | (** val z_of_bigint : Big.big_int -> coq_Z **) 59 | 60 | let z_of_bigint x = 61 | bigint_zlike_case Z0 (fun i -> Zpos (pos_of_bigint i)) (fun i -> Zneg 62 | (pos_of_bigint i)) x 63 | 64 | (** val n_of_bigint : Big.big_int -> coq_N **) 65 | 66 | let n_of_bigint x = 67 | bigint_zlike_case N0 (fun i -> Npos (pos_of_bigint i)) (fun x0 -> N0) x 68 | 69 | -------------------------------------------------------------------------------- /x86model/semantics_trace/simulator/extract.v: -------------------------------------------------------------------------------- 1 | Require Import Parser. 2 | Require Import X86Semantics. 3 | 4 | (* Flocq defines functions that either return reals or take them as parameters. 5 | We don't use these, but when extracting, Coq will extract the 6 | axiomatization of the Reals, which will result in unrealized axioms that will 7 | raise exceptions. The following eliminates this problem. *) 8 | 9 | Extract Inlined Constant Fappli_IEEE.FF2R => "fun _ _ -> assert false". 10 | Extract Inlined Constant Fappli_IEEE.B2R => "fun _ _ _ -> assert false". 11 | Extract Inlined Constant Fappli_IEEE.round_mode => "fun _ _ -> assert false". 12 | Extract Inlined Constant Fcalc_bracket.inbetween_loc => "fun _ _ _ -> assert false". 13 | Extract Inlined Constant Fcore_defs.F2R => "fun _ _ -> assert false". 14 | Extract Inlined Constant Fcore_generic_fmt.canonic_exp => "fun _ _ _ => assert false". 15 | Extract Inlined Constant Fcore_generic_fmt.scaled_mantissa => "fun _ _ _ => assert false". 16 | 17 | Extraction Blacklist String List. 18 | 19 | Recursive Extraction Library Compare_dec. 20 | Recursive Extraction Library Peano_dec. 21 | (* Recursive Extraction User_t. *) 22 | (*Separate Extraction type User_t.*) 23 | 24 | (*Extract Inductive Type => "coq_type" ["coq_type"].*) 25 | Set Extraction AccessOpaque. 26 | 27 | Separate Extraction X86_PARSER_ARG.tipe 28 | X86_PARSER_ARG.user_type 29 | X86_PARSER_ARG.byte_explode 30 | type 31 | parse_token 32 | step. -------------------------------------------------------------------------------- /x86model/semantics_trace/tracer/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all: gntrace.so memlist.so 3 | 4 | 5 | gntrace.so: gntrace.cpp tracer.h 6 | g++ -m32 -c -Wall -Werror -Wno-unknown-pragmas -O3 -fomit-frame-pointer -DBIGARRAY_MULTIPLIER=1 -DUSING_XED -fno-strict-aliasing -I$(PIN_PATH)/extras/xed2-ia32/include -I$(PIN_PATH)/extras/components/include -I$(PIN_PATH)/source/include -I$(PIN_PATH)/source/include/gen -fno-stack-protector -DTARGET_IA32 -DHOST_IA32 -DTARGET_LINUX -O3 -fomit-frame-pointer -o gntrace.o gntrace.cpp 7 | g++ -m32 -Wl,--hash-style=sysv -shared -Wl,-Bsymbolic -Wl,--version-script=$(PIN_PATH)/source/include/pintool.ver -L$(PIN_PATH)/extras/xed2-ia32/lib -L$(PIN_PATH)/ia32/lib -L$(PIN_PATH)/ia32/lib-ext -o gntrace.so gntrace.o -L$(PIN_PATH)/extras/xed2-ia32/lib -L$(PIN_PATH)/ia32/lib -L$(PIN_PATH)/ia32/lib-ext -lpin -lxed -ldwarf -lelf -ldl 8 | 9 | memlist.so: memlist.cpp tracer.h 10 | g++ -m32 -c -Wall -Werror -Wno-unknown-pragmas -O3 -fomit-frame-pointer -DBIGARRAY_MULTIPLIER=1 -DUSING_XED -fno-strict-aliasing -I$(PIN_PATH)/extras/xed2-ia32/include -I$(PIN_PATH)/extras/components/include -I$(PIN_PATH)/source/include -I$(PIN_PATH)/source/include/gen -fno-stack-protector -DTARGET_IA32 -DHOST_IA32 -DTARGET_LINUX -O3 -fomit-frame-pointer -o memlist.o memlist.cpp 11 | g++ -m32 -Wl,--hash-style=sysv -shared -Wl,-Bsymbolic -Wl,--version-script=$(PIN_PATH)/source/include/pintool.ver -L$(PIN_PATH)/extras/xed2-ia32/lib -L$(PIN_PATH)/ia32/lib -L$(PIN_PATH)/ia32/lib-ext -o memlist.so memlist.o -L$(PIN_PATH)/extras/xed2-ia32/lib -L$(PIN_PATH)/ia32/lib -L$(PIN_PATH)/ia32/lib-ext -lpin -lxed -ldwarf -lelf -ldl 12 | -------------------------------------------------------------------------------- /x86model/semantics_trace/tracer/gntrace.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2011. Greg Morrisett, Gang Tan, Joseph Tassarotti, 2 | Jean-Baptiste Tristan, and Edward Gan. 3 | 4 | This file is part of RockSalt. 5 | 6 | This file is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License as 8 | published by the Free Software Foundation; either version 2 of 9 | the License, or (at your option) any later version. 10 | */ 11 | 12 | 13 | /* 14 | 15 | This generates a dump of the memory/register values as 16 | a program executes. Replaces an earlier less-portable pthread tool. 17 | 18 | Depends on the Pin instrumentation/dynamic analysis tool developed by Intel. 19 | See the examples in the manual, especially pinatrace for information about 20 | accessing memory operands with Pin. 21 | 22 | Basically the same as memlist.cpp except this prints out the mem values 23 | and register values. See the documentation in memlist.cpp for guidance. 24 | 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include "pin.H" 33 | #include "tracer.h" 34 | 35 | /* Some options. KNOBs are Pin's way of setting up config info. 36 | -s switch specifies the starting function to trace from 37 | -e is the symbol name to stop tracing at 38 | -m is the maximum number of instructions to trace 39 | */ 40 | 41 | 42 | KNOB KnobStartSymbol(KNOB_MODE_WRITEONCE, "pintool", 43 | "s", "main", "specify function to start tracing from"); 44 | 45 | KNOB KnobEndSymbol(KNOB_MODE_WRITEONCE, "pintool", 46 | "e", "", "specify function to stop tracing from"); 47 | 48 | KNOB KnobMaxInstrs(KNOB_MODE_WRITEONCE, "pintool", 49 | "m", "5000", "specify max number of instructions to trace"); 50 | 51 | FILE * memtrace; 52 | FILE * regtrace; 53 | FILE * flagtrace; 54 | int flag = 0; 55 | int found = 0; 56 | int lastinssyscall = 0; 57 | int dumpnum = 0; 58 | // Used to count the number of instructions we've traced. 59 | unsigned int counter = 0; 60 | unsigned int max_instrs = 0; 61 | unsigned int image_start_size = 0; 62 | unsigned int image_end_size = 0; 63 | 64 | VOID dumpmem(int last) { 65 | char filename[80]; 66 | sprintf(filename, "mem%d.txt", dumpnum); 67 | memtrace = fopen(filename, "w"); 68 | FILE * memaddrs = fopen("memaddrs.txt", "r"); 69 | unsigned int *addr = 0; 70 | unsigned int tmp = 0; 71 | tmp = 0; 72 | while( fscanf(memaddrs, "%08x\n", (unsigned int *) &addr) == 1) { 73 | PIN_SafeCopy(&tmp, addr, 1); 74 | fprintf(memtrace, "%08x %02x\n", (unsigned int) (addr), tmp); 75 | } 76 | fclose(memaddrs); 77 | fclose(memtrace); 78 | if(dumpnum > 0) { 79 | fprintf(regtrace, "END 0"); 80 | fclose(regtrace); 81 | } 82 | if(!last) { 83 | sprintf(filename, "regs%d.txt", dumpnum); 84 | regtrace = fopen(filename, "w"); 85 | dumpnum++; 86 | } 87 | } 88 | 89 | 90 | // This function runs every time an instruction is executed. If the flag is 91 | // turned on, it dumps out the memory for that instruction as well as the 92 | // register values / eflags prior to executing the instruction. 93 | 94 | VOID dumpins(char * ip, unsigned int sysflag, USIZE size, ADDRINT* EAX, ADDRINT* ECX, ADDRINT* EDX, ADDRINT* EBX, 95 | ADDRINT* ESP, ADDRINT* EBP, ADDRINT* ESI, ADDRINT* EDI, ADDRINT *FS, 96 | ADDRINT* GS, UINT32 eflags) 97 | { 98 | 99 | if(flag >= 1 && counter < max_instrs) { 100 | if(lastinssyscall) { 101 | /* the last thing we did was a syscall. Therefore we must do a memory dump 102 | and start up a new register file. */ 103 | dumpmem(0); 104 | lastinssyscall = 0; 105 | } 106 | if(sysflag) { 107 | printf("Encountered syscall at %08x\n", (unsigned int) ip); 108 | lastinssyscall = 1; 109 | } 110 | fprintf(regtrace, "FS %08x\n", *FS); 111 | fprintf(regtrace, "GS %08x\n", *GS); 112 | fprintf(regtrace, "EAX %08x\n", *EAX); 113 | fprintf(regtrace, "ECX %08x\n", *ECX); 114 | fprintf(regtrace, "EDX %08x\n", *EDX); 115 | fprintf(regtrace, "EBX %08x\n", *EBX); 116 | fprintf(regtrace, "ESP %08x\n", *ESP); 117 | fprintf(regtrace, "EBP %08x\n", *EBP); 118 | fprintf(regtrace, "ESI %08x\n", *ESI); 119 | fprintf(regtrace, "EDI %08x\n", *EDI); 120 | fprintf(regtrace, "EIP %08x\n\n", (unsigned int) ip); 121 | //fprintf(flagtrace, "%08x\n\n", (unsigned int) eflags); 122 | counter++; 123 | } 124 | 125 | if(flag == 2 || !(counter < max_instrs)) { 126 | printf("Done recording.\n"); 127 | dumpmem(1); 128 | PIN_ExitApplication(0); 129 | } 130 | } 131 | VOID startrecord(ADDRINT* ESP) { 132 | flag = 1; 133 | // Dump out all of the memory addresses that we identified as relevant in the previous pass 134 | dumpmem(0); 135 | } 136 | 137 | VOID endrecord() { 138 | flag = 2; 139 | } 140 | 141 | VOID ins_instrument(INS ins, VOID *v) 142 | { 143 | unsigned int sysflag = INS_IsSyscall(ins) ? 1 : 0; 144 | INS_InsertCall(ins, 145 | IPOINT_BEFORE, 146 | (AFUNPTR)dumpins, 147 | IARG_INST_PTR, 148 | IARG_UINT32, 149 | sysflag, 150 | IARG_UINT32, 151 | INS_Size(ins), 152 | IARG_REG_REFERENCE, REG_EAX, 153 | IARG_REG_REFERENCE, REG_ECX, 154 | IARG_REG_REFERENCE, REG_EDX, 155 | IARG_REG_REFERENCE, REG_EBX, 156 | IARG_REG_REFERENCE, REG_ESP, 157 | IARG_REG_REFERENCE, REG_EBP, 158 | IARG_REG_REFERENCE, REG_ESI, 159 | IARG_REG_REFERENCE, REG_EDI, 160 | IARG_REG_REFERENCE, REG_SEG_FS_BASE, 161 | IARG_REG_REFERENCE, REG_SEG_GS_BASE, 162 | IARG_REG_VALUE, REG_EFLAGS, 163 | IARG_END); 164 | } 165 | 166 | void init_start_stop(IMG img, void * b) { 167 | if(found) return; 168 | unsigned long start_addr = find_symbol(IMG_Name(img).c_str(), "main"); 169 | unsigned long end_addr = find_symbol(IMG_Name(img).c_str(), KnobEndSymbol.Value().c_str()); 170 | image_start_size = IMG_LowAddress(img); 171 | image_end_size = IMG_HighAddress(img); 172 | RTN start = RTN_FindByName(img, "main"); 173 | if(!RTN_Valid(start) && (image_start_size <= start_addr) && (start_addr <= image_end_size)) { 174 | start = RTN_CreateAt(start_addr, "main"); 175 | } 176 | 177 | RTN end = RTN_FindByName(img, KnobEndSymbol.Value().c_str()); 178 | if(!RTN_Valid(end) && (image_start_size <= end_addr) && (end_addr <= image_end_size)) { 179 | end = RTN_CreateAt(end_addr, "end"); 180 | } 181 | 182 | if(RTN_Valid(start) && RTN_Valid(end)) { 183 | RTN_Open(start); 184 | RTN_InsertCall(start, IPOINT_BEFORE, (AFUNPTR)startrecord, IARG_REG_REFERENCE, REG_ESP, IARG_END); 185 | RTN_Close(start); 186 | 187 | RTN_Open(end); 188 | RTN_InsertCall(end, IPOINT_BEFORE, (AFUNPTR)endrecord, IARG_END); 189 | RTN_Close(end); 190 | printf("Found end/start\n"); 191 | found = 1; 192 | } 193 | else { 194 | printf("Couldn't find either end/start in this image.\n"); 195 | } 196 | } 197 | 198 | int main(int argc, char * argv[]) 199 | { 200 | if (PIN_Init(argc, argv)) return -1; 201 | 202 | if(strcmp(KnobEndSymbol.Value().c_str(), "") == 0) { 203 | cerr << "Need to specify symbol to stop tracing at using the -e switch"; 204 | cerr << endl; 205 | return -1; 206 | } 207 | 208 | max_instrs = atoi(KnobMaxInstrs.Value().c_str()); 209 | PIN_InitSymbols(); 210 | 211 | /*flagtrace = fopen("flags0.txt", "w"); */ 212 | 213 | // This adds instrumentation to the functions "main" and the stop symbol 214 | // specified by the -e switch. 215 | 216 | IMG_AddInstrumentFunction(init_start_stop, 0); 217 | 218 | // This instruments every instruction with a call to a function that either 219 | // dumps/does not dump mem/regs/eflags based on the flag switched when we 220 | // reach the start/end symbols. 221 | 222 | INS_AddInstrumentFunction(ins_instrument, 0); 223 | 224 | PIN_StartProgram(); 225 | 226 | return 0; 227 | } 228 | 229 | -------------------------------------------------------------------------------- /x86model/semantics_trace/tracer/memlist.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2011. Greg Morrisett, Gang Tan, Joseph Tassarotti, 2 | Jean-Baptiste Tristan, and Edward Gan. 3 | 4 | This file is part of RockSalt. 5 | 6 | This file is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License as 8 | published by the Free Software Foundation; either version 2 of 9 | the License, or (at your option) any later version. 10 | */ 11 | 12 | 13 | /* 14 | 15 | This generates a list of memory addresses accessed by the binary. This file is 16 | used in later instrumentation passes. 17 | 18 | Depends on the Pin instrumentation/dynamic analysis tool developed by Intel. 19 | See the examples in the manual, especially pinatrace for information about 20 | accessing memory operands with Pin. 21 | 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include "pin.H" 29 | #include "tracer.h" 30 | 31 | 32 | /* Some options. KNOBs are Pin's way of setting up config info. 33 | -s switch specifies the starting function to trace from 34 | -e is the symbol name to stop tracing at 35 | -m is the maximum number of instructions to trace 36 | */ 37 | 38 | KNOB KnobStartSymbol(KNOB_MODE_WRITEONCE, "pintool", 39 | "s", "main", "specify function to start tracing from"); 40 | 41 | KNOB KnobEndSymbol(KNOB_MODE_WRITEONCE, "pintool", 42 | "e", "", "specify function to stop tracing from"); 43 | 44 | KNOB KnobMaxInstrs(KNOB_MODE_WRITEONCE, "pintool", 45 | "m", "5000", "specify max number of instructions to trace"); 46 | 47 | 48 | FILE * memtrace; 49 | // Used to count the number of instructions we've traced. 50 | unsigned int counter = 0; 51 | unsigned int max_instrs = 0; 52 | unsigned int image_start_size = 0; 53 | unsigned int image_end_size = 0; 54 | 55 | // A flag for determining if we're in record mode or not 56 | unsigned int flag = 0; 57 | unsigned int found = 0; 58 | 59 | // This function runs every time an instruction is executed. If the flag is 60 | // turned on, it dumps out the memory addresses for that instruction 61 | 62 | VOID dumpins(char * ip, USIZE size) 63 | { 64 | if(flag && counter < max_instrs) { 65 | for(unsigned int i = 0; i < size; i++){ 66 | fprintf(memtrace, "%08x\n", (unsigned int) (ip+i)); 67 | } 68 | counter++; 69 | } 70 | } 71 | 72 | VOID readmem (char * ip, VOID * addrvoid, USIZE size) { 73 | // An address in memory was read. 74 | // We should record this as an address worth watching. 75 | char * addr = (char *) addrvoid; 76 | if (counter < max_instrs) { 77 | for(unsigned int i = 0; i < size; i++) { 78 | fprintf(memtrace, "%08x\n", (unsigned int) (addr+i)); 79 | } 80 | } 81 | } 82 | 83 | VOID startrecord(ADDRINT* ESP) { 84 | flag = 1; 85 | } 86 | 87 | VOID endrecord() { 88 | flag = 0; 89 | PIN_ExitApplication(0); 90 | } 91 | 92 | VOID ins_instrument(INS ins, VOID *v) 93 | { 94 | INS_InsertCall(ins, 95 | IPOINT_BEFORE, 96 | (AFUNPTR)dumpins, 97 | IARG_INST_PTR, 98 | IARG_UINT32, 99 | INS_Size(ins), 100 | IARG_END); 101 | UINT32 memop_count = INS_MemoryOperandCount(ins); 102 | UINT32 i = 0; 103 | for(i = 0; i < memop_count; i++) { 104 | if(INS_MemoryOperandIsRead(ins, i)) { 105 | INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) readmem, IARG_INST_PTR, 106 | IARG_MEMORYOP_EA, i, 107 | IARG_UINT32, INS_MemoryOperandSize(ins, i), IARG_END); 108 | } 109 | } 110 | } 111 | 112 | void init_start_stop(IMG img, void * b) { 113 | // We attempt to find the desired symbol names in each of the images. 114 | // We do not use Pin's default tool for doing this because it working in some 115 | // cases. Instead we write a custom function that calls nm to extract this info. 116 | // see tracer.h 117 | 118 | if(found) return; 119 | unsigned long start_addr = find_symbol(IMG_Name(img).c_str(), "main"); 120 | unsigned long end_addr = find_symbol(IMG_Name(img).c_str(), KnobEndSymbol.Value().c_str()); 121 | image_start_size = IMG_LowAddress(img); 122 | image_end_size = IMG_HighAddress(img); 123 | RTN start = RTN_FindByName(img, "main"); 124 | if(!RTN_Valid(start) && (image_start_size <= start_addr) && (start_addr <= image_end_size)) { 125 | start = RTN_CreateAt(start_addr, "end"); 126 | } 127 | 128 | RTN end = RTN_FindByName(img, KnobEndSymbol.Value().c_str()); 129 | if(!RTN_Valid(end) && (image_start_size <= end_addr) && (end_addr <= image_end_size)) { 130 | end = RTN_CreateAt(end_addr, "end"); 131 | } 132 | 133 | if(RTN_Valid(start) && RTN_Valid(end)) { 134 | RTN_Open(start); 135 | RTN_InsertCall(start, IPOINT_BEFORE, (AFUNPTR)startrecord, IARG_REG_REFERENCE, REG_ESP, IARG_END); 136 | RTN_Close(start); 137 | 138 | RTN_Open(end); 139 | RTN_InsertCall(end, IPOINT_BEFORE, (AFUNPTR)endrecord, IARG_END); 140 | RTN_Close(end); 141 | printf("Found end/start\n"); 142 | found = 1; 143 | } 144 | else { 145 | printf("Couldn't find either end/start in this image.\n"); 146 | } 147 | } 148 | 149 | 150 | 151 | int main(int argc, char * argv[]) 152 | { 153 | if (PIN_Init(argc, argv)) return -1; 154 | 155 | if(strcmp(KnobEndSymbol.Value().c_str(), "") == 0) { 156 | cerr << "Need to specify symbol to stop tracing at using the -e switch"; 157 | cerr << endl; 158 | return -1; 159 | } 160 | 161 | max_instrs = atoi(KnobMaxInstrs.Value().c_str()); 162 | PIN_InitSymbols(); 163 | 164 | memtrace = fopen("memaddrs.txt", "w"); 165 | 166 | // This adds instrumentation to the functions "main" and the stop symbol 167 | // specified by the -e switch. 168 | 169 | IMG_AddInstrumentFunction(init_start_stop, 0); 170 | 171 | // This instruments every instruction with a call to a function that either 172 | // dumps/does not dump mem/regs/eflags based on the flag switched when we 173 | // reach the start/end symbols. 174 | 175 | INS_AddInstrumentFunction(ins_instrument, 0); 176 | 177 | PIN_StartProgram(); 178 | 179 | return 0; 180 | } 181 | 182 | -------------------------------------------------------------------------------- /x86model/semantics_trace/tracer/tracer.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2011. Greg Morrisett, Gang Tan, Joseph Tassarotti, 2 | Jean-Baptiste Tristan, and Edward Gan. 3 | 4 | This file is part of RockSalt. 5 | 6 | This file is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License as 8 | published by the Free Software Foundation; either version 2 of 9 | the License, or (at your option) any later version. 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | unsigned long find_symbol(const char *, const char *); 17 | 18 | /* 19 | This takes in the name of an executable and a symbol name, 20 | and finds the address of that symbol by calling "nm " 21 | 22 | For some reason PIN wasn't finding some symbols on it's own. 23 | I suspect that this is not the most robust approach. For example 24 | this won't let you find the address of symbols that are dynamically 25 | loaded, but we don't need that for our testing purposes. 26 | */ 27 | 28 | unsigned long find_symbol(const char *proc, const char *symname) { 29 | char nmcall[256]; 30 | char output[512]; 31 | char tempname[256]; 32 | strcpy(nmcall, "nm "); 33 | strcat(nmcall, proc); 34 | FILE * nmout = popen(nmcall, "r"); 35 | 36 | while(fgets(output, 512, nmout) != 0) { 37 | unsigned long loc = 0; 38 | // This sscanf formatting string extracts the location and symbol name from a line of 39 | // nm output 40 | 41 | if(sscanf(output, "%lx %*[^ \n] %[^ \n]", &loc, tempname) == 2) { 42 | if(!strcmp(symname, tempname)) { 43 | return loc; 44 | } 45 | } 46 | } 47 | return 0; 48 | } 49 | --------------------------------------------------------------------------------