├── lopstr2017_ldrgen_preprint.pdf ├── headache ├── header └── config ├── generate.mli ├── ldrgen.ml ├── dune-project ├── dune ├── utils.mli ├── options.mli ├── utils.ml ├── options.ml ├── README.md ├── generate.ml └── LICENSE /lopstr2017_ldrgen_preprint.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gergo-/ldrgen/HEAD/lopstr2017_ldrgen_preprint.pdf -------------------------------------------------------------------------------- /headache/header: -------------------------------------------------------------------------------- 1 | 2 | ldrgen, a generator of random C programs 3 | Copyright (C) 2017-2025, Gergö Barany 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | -------------------------------------------------------------------------------- /generate.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* ldrgen, a generator of random C programs *) 4 | (* Copyright (C) 2017-2025, Gergö Barany *) 5 | (* *) 6 | (* This program is free software: you can redistribute it and/or modify *) 7 | (* it under the terms of the GNU General Public License as published by *) 8 | (* the Free Software Foundation, either version 3 of the License, or *) 9 | (* (at your option) any later version. *) 10 | (* *) 11 | (* This program is distributed in the hope that it will be useful, *) 12 | (* but WITHOUT ANY WARRANTY; without even the implied warranty of *) 13 | (* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) 14 | (* GNU General Public License for more details. *) 15 | (* *) 16 | (* You should have received a copy of the GNU General Public License *) 17 | (* along with this program. If not, see . *) 18 | (* *) 19 | (**************************************************************************) 20 | 21 | val run: unit -> unit 22 | -------------------------------------------------------------------------------- /ldrgen.ml: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* ldrgen, a generator of random C programs *) 4 | (* Copyright (C) 2017-2025, Gergö Barany *) 5 | (* *) 6 | (* This program is free software: you can redistribute it and/or modify *) 7 | (* it under the terms of the GNU General Public License as published by *) 8 | (* the Free Software Foundation, either version 3 of the License, or *) 9 | (* (at your option) any later version. *) 10 | (* *) 11 | (* This program is distributed in the hope that it will be useful, *) 12 | (* but WITHOUT ANY WARRANTY; without even the implied warranty of *) 13 | (* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) 14 | (* GNU General Public License for more details. *) 15 | (* *) 16 | (* You should have received a copy of the GNU General Public License *) 17 | (* along with this program. If not, see . *) 18 | (* *) 19 | (**************************************************************************) 20 | 21 | let () = 22 | Boot.Main.extend Generate.run 23 | -------------------------------------------------------------------------------- /dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 3.7) 2 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3 | ;; ;; 4 | ;; ldrgen, a generator of random C programs ;; 5 | ;; Copyright (C) 2017-2025, Gergö Barany ;; 6 | ;; ;; 7 | ;; This program is free software: you can redistribute it and/or modify ;; 8 | ;; it under the terms of the GNU General Public License as published by ;; 9 | ;; the Free Software Foundation, either version 3 of the License, or ;; 10 | ;; (at your option) any later version. ;; 11 | ;; ;; 12 | ;; This program is distributed in the hope that it will be useful, ;; 13 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; 14 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; 15 | ;; GNU General Public License for more details. ;; 16 | ;; ;; 17 | ;; You should have received a copy of the GNU General Public License ;; 18 | ;; along with this program. If not, see . ;; 19 | ;; ;; 20 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 21 | 22 | (using dune_site 0.1) 23 | (name frama-c-ldrgen) 24 | (package (name frama-c-ldrgen)) 25 | -------------------------------------------------------------------------------- /headache/config: -------------------------------------------------------------------------------- 1 | ########################################################################## 2 | # # 3 | # ldrgen, a generator of random C programs # 4 | # Copyright (C) 2017-2025, Gergö Barany # 5 | # # 6 | # This program is free software: you can redistribute it and/or modify # 7 | # it under the terms of the GNU General Public License as published by # 8 | # the Free Software Foundation, either version 3 of the License, or # 9 | # (at your option) any later version. # 10 | # # 11 | # This program is distributed in the hope that it will be useful, # 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 14 | # GNU General Public License for more details. # 15 | # # 16 | # You should have received a copy of the GNU General Public License # 17 | # along with this program. If not, see . # 18 | # # 19 | ########################################################################## 20 | 21 | # Dune stuff 22 | "dune" -> frame open:";;" line:";" close:";;" 23 | | "dune-project" -> frame open:";;" line:";" close:";;" 24 | | "dune-project" -> skip match:".lang dune .*" 25 | # Headache config 26 | | "config" -> frame open:"#" line:"#" close:"#" 27 | -------------------------------------------------------------------------------- /dune: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ;; ;; 3 | ;; ldrgen, a generator of random C programs ;; 4 | ;; Copyright (C) 2017-2025, Gergö Barany ;; 5 | ;; ;; 6 | ;; This program is free software: you can redistribute it and/or modify ;; 7 | ;; it under the terms of the GNU General Public License as published by ;; 8 | ;; the Free Software Foundation, either version 3 of the License, or ;; 9 | ;; (at your option) any later version. ;; 10 | ;; ;; 11 | ;; This program is distributed in the hope that it will be useful, ;; 12 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; 13 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; 14 | ;; GNU General Public License for more details. ;; 15 | ;; ;; 16 | ;; You should have received a copy of the GNU General Public License ;; 17 | ;; along with this program. If not, see . ;; 18 | ;; ;; 19 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20 | 21 | (library 22 | (name Ldrgen) 23 | (public_name frama-c-ldrgen.core) 24 | (flags -open Frama_c_kernel :standard) 25 | (libraries frama-c.kernel)) 26 | 27 | (plugin 28 | (optional) 29 | (name ldrgen) 30 | (libraries frama-c-ldrgen.core) 31 | (site (frama-c plugins))) 32 | -------------------------------------------------------------------------------- /utils.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* ldrgen, a generator of random C programs *) 4 | (* Copyright (C) 2017-2025, Gergö Barany *) 5 | (* *) 6 | (* This program is free software: you can redistribute it and/or modify *) 7 | (* it under the terms of the GNU General Public License as published by *) 8 | (* the Free Software Foundation, either version 3 of the License, or *) 9 | (* (at your option) any later version. *) 10 | (* *) 11 | (* This program is distributed in the hope that it will be useful, *) 12 | (* but WITHOUT ANY WARRANTY; without even the implied warranty of *) 13 | (* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) 14 | (* GNU General Public License for more details. *) 15 | (* *) 16 | (* You should have received a copy of the GNU General Public License *) 17 | (* along with this program. If not, see . *) 18 | (* *) 19 | (**************************************************************************) 20 | 21 | open Cil_datatype 22 | 23 | (** Select a random member of the list. *) 24 | val random_select: 'a list -> 'a 25 | 26 | (** Select a random element of the [lval] set. 27 | @raises [Not_found] if the set is empty. *) 28 | val random_select_from_set: LvalStructEq.Set.t -> Cil_types.lval 29 | 30 | (** Compute the set of all free variables in the expression. We define "free 31 | variables" as non-global, non-parameter variables. Return the set of 32 | variables in a list of lvalues without repetitions. *) 33 | val free_vars: Cil_types.exp -> Cil_types.lval list 34 | 35 | (** Print the ldrgen-specific arguments that were set on the command line. 36 | They are printed separated by spaces, with an initial space. *) 37 | val print_command_line_args: Format.formatter -> unit -> unit 38 | 39 | (** Return [true] iff the expression is an infinite constant. *) 40 | val is_infinity: Cil_types.exp -> bool 41 | -------------------------------------------------------------------------------- /options.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* ldrgen, a generator of random C programs *) 4 | (* Copyright (C) 2017-2025, Gergö Barany *) 5 | (* *) 6 | (* This program is free software: you can redistribute it and/or modify *) 7 | (* it under the terms of the GNU General Public License as published by *) 8 | (* the Free Software Foundation, either version 3 of the License, or *) 9 | (* (at your option) any later version. *) 10 | (* *) 11 | (* This program is distributed in the hope that it will be useful, *) 12 | (* but WITHOUT ANY WARRANTY; without even the implied warranty of *) 13 | (* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) 14 | (* GNU General Public License for more details. *) 15 | (* *) 16 | (* You should have received a copy of the GNU General Public License *) 17 | (* along with this program. If not, see . *) 18 | (* *) 19 | (**************************************************************************) 20 | 21 | include Plugin.General_services 22 | 23 | module Run: Parameter_sig.Bool 24 | 25 | module Seed: Parameter_sig.Int 26 | module ExprDepth: Parameter_sig.Int 27 | module StmtDepth: Parameter_sig.Int 28 | module BlockLength: Parameter_sig.Int 29 | module MaxLive: Parameter_sig.Int 30 | module MaxArgs: Parameter_sig.Int 31 | module Arrays: Parameter_sig.Bool 32 | module MaxArrayDim: Parameter_sig.Int 33 | module MaxArrayLengthPerDim: Parameter_sig.Int 34 | 35 | module FloatingPoint: Parameter_sig.Bool 36 | module Float: Parameter_sig.Bool 37 | module FloatingPointOnly: Parameter_sig.Bool 38 | module IntOnly: Parameter_sig.Bool 39 | module LongLong: Parameter_sig.Bool 40 | module PointerArgs: Parameter_sig.Bool 41 | module DivMod: Parameter_sig.Bool 42 | module Mod: Parameter_sig.Bool 43 | module Bitwise: Parameter_sig.Bool 44 | module Loops: Parameter_sig.Bool 45 | module WhileLoops: Parameter_sig.Bool 46 | module ForLoops: Parameter_sig.Bool 47 | 48 | module CheckAst: Parameter_sig.Bool 49 | 50 | (** Initialize global state, such as the random number generator. *) 51 | val initialize: unit -> unit 52 | -------------------------------------------------------------------------------- /utils.ml: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* ldrgen, a generator of random C programs *) 4 | (* Copyright (C) 2017-2025, Gergö Barany *) 5 | (* *) 6 | (* This program is free software: you can redistribute it and/or modify *) 7 | (* it under the terms of the GNU General Public License as published by *) 8 | (* the Free Software Foundation, either version 3 of the License, or *) 9 | (* (at your option) any later version. *) 10 | (* *) 11 | (* This program is distributed in the hope that it will be useful, *) 12 | (* but WITHOUT ANY WARRANTY; without even the implied warranty of *) 13 | (* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) 14 | (* GNU General Public License for more details. *) 15 | (* *) 16 | (* You should have received a copy of the GNU General Public License *) 17 | (* along with this program. If not, see . *) 18 | (* *) 19 | (**************************************************************************) 20 | 21 | open Cil_datatype 22 | open Cil_types 23 | 24 | let random_select xs = 25 | let i = Random.int (List.length xs) in 26 | List.nth xs i 27 | 28 | let random_select_from_set set = 29 | try 30 | (* FIXME: Use a smarter selection algorithm. *) 31 | random_select (LvalStructEq.Set.elements set) 32 | with _ -> raise Not_found 33 | 34 | class free_vars_visitor set = object 35 | inherit Visitor.frama_c_inplace 36 | method !vvrbl vi = 37 | if not vi.vglob && not vi.vformal then 38 | set := LvalStructEq.Set.add (Cil.var vi) !set; 39 | Cil.SkipChildren 40 | end 41 | 42 | let free_vars exp = 43 | let set = ref LvalStructEq.Set.empty in 44 | ignore (Visitor.visitFramacExpr (new free_vars_visitor set) exp); 45 | LvalStructEq.Set.elements !set 46 | 47 | let print_command_line_args fmt () = 48 | let interesting_option s = 49 | Str.string_match (Str.regexp "^-ldrgen") s 0 50 | in 51 | let numerical_arg s = 52 | try 53 | ignore (int_of_string s); 54 | true 55 | with Failure _ -> false 56 | in 57 | let rec process_options os = 58 | match os with 59 | | o :: n :: os when interesting_option o && numerical_arg n -> 60 | Format.fprintf fmt " %s %s" o n; 61 | process_options os 62 | | o :: os when interesting_option o -> 63 | Format.fprintf fmt " %s" o; 64 | process_options os 65 | | _ :: os -> process_options os 66 | | [] -> () 67 | in 68 | process_options (Array.to_list Sys.argv) 69 | 70 | let is_infinity = function 71 | | { enode = Const (CReal (f, _, _)); _ } -> not (Float.is_finite f) 72 | | _ -> false 73 | -------------------------------------------------------------------------------- /options.ml: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* ldrgen, a generator of random C programs *) 4 | (* Copyright (C) 2017-2025, Gergö Barany *) 5 | (* *) 6 | (* This program is free software: you can redistribute it and/or modify *) 7 | (* it under the terms of the GNU General Public License as published by *) 8 | (* the Free Software Foundation, either version 3 of the License, or *) 9 | (* (at your option) any later version. *) 10 | (* *) 11 | (* This program is distributed in the hope that it will be useful, *) 12 | (* but WITHOUT ANY WARRANTY; without even the implied warranty of *) 13 | (* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) 14 | (* GNU General Public License for more details. *) 15 | (* *) 16 | (* You should have received a copy of the GNU General Public License *) 17 | (* along with this program. If not, see . *) 18 | (* *) 19 | (**************************************************************************) 20 | 21 | include Plugin.Register 22 | (struct 23 | let name = "Ldrgen" 24 | let shortname = "ldrgen" 25 | let help = "generate a random C program" 26 | end) 27 | 28 | module Run = False 29 | (struct 30 | let option_name = "-ldrgen" 31 | let help = "generate a random C function" 32 | end) 33 | 34 | module CheckAst = True 35 | (struct 36 | let option_name = "-ldrgen-check-ast" 37 | let help = "perform sanity checks on the generated ast" 38 | end) 39 | 40 | module Seed = Zero 41 | (struct 42 | let option_name = "-ldrgen-seed" 43 | let arg_name = "s" 44 | let help = "set random seed" 45 | end) 46 | 47 | module ExprDepth = Int 48 | (struct 49 | let option_name = "-ldrgen-expr-depth" 50 | let arg_name = "d" 51 | let default = 5 52 | let help = "set maximal expression depth" 53 | end) 54 | 55 | module StmtDepth = Int 56 | (struct 57 | let option_name = "-ldrgen-stmt-depth" 58 | let arg_name = "d" 59 | let default = 3 60 | let help = "set maximal statement nesting depth" 61 | end) 62 | 63 | module BlockLength = Int 64 | (struct 65 | let option_name = "-ldrgen-block-length" 66 | let arg_name = "n" 67 | let default = 5 68 | let help = "set maximal number of instructions per block" 69 | end) 70 | 71 | module MaxLive = Int 72 | (struct 73 | let option_name = "-ldrgen-max-live" 74 | let arg_name = "l" 75 | let default = 32 76 | let help = "set maximal number of concurrently live variables" 77 | end) 78 | 79 | module MaxArgs = Int 80 | (struct 81 | let option_name = "-ldrgen-max-args" 82 | let arg_name = "a" 83 | let default = 8 84 | let help = "set maximal number of function arguments" 85 | end) 86 | 87 | module Arrays = True 88 | (struct 89 | let option_name = "-ldrgen-arrays" 90 | let help = "allow generation of arrays" 91 | end) 92 | 93 | module MaxArrayDim = Int 94 | (struct 95 | let option_name = "-ldrgen-max-array-dim" 96 | let arg_name = "n" 97 | let default = 3 98 | let help = "set maximal number of array dimensions" 99 | end) 100 | 101 | module MaxArrayLengthPerDim = Int 102 | (struct 103 | let option_name = "-ldrgen-max-array-length-per-dim" 104 | let arg_name = "n" 105 | let default = 5 106 | let help = "set maximal number of array elements per dimension" 107 | end) 108 | 109 | module FloatingPoint = True 110 | (struct 111 | let option_name = "-ldrgen-fp" 112 | let help = "allow generation of floating-point arithmetic" 113 | end) 114 | 115 | module Float = True 116 | (struct 117 | let option_name = "-ldrgen-float" 118 | let help = "allow generation of the float type if -ldrgen-fp is set" 119 | end) 120 | 121 | module FloatingPointOnly = False 122 | (struct 123 | let option_name = "-ldrgen-fp-only" 124 | let help = "allow *only* generation of floating-point arithmetic but \ 125 | no integer arithmetic" 126 | end) 127 | 128 | module IntOnly = False 129 | (struct 130 | let option_name = "-ldrgen-int-only" 131 | let help = "allow *only* generation of int and unsigned int types" 132 | end) 133 | 134 | module LongLong = True 135 | (struct 136 | let option_name = "-ldrgen-long-long" 137 | let help = "allow generation of long long arithmetic" 138 | end) 139 | 140 | module PointerArgs = True 141 | (struct 142 | let option_name = "-ldrgen-pointer-args" 143 | let help = "allow generation of pointer arguments" 144 | end) 145 | 146 | module DivMod = True 147 | (struct 148 | let option_name = "-ldrgen-div-mod" 149 | let help = "allow generation of division and modulo operations" 150 | end) 151 | 152 | module Mod = True 153 | (struct 154 | let option_name = "-ldrgen-mod" 155 | let help = "allow generation of modulo operations if -ldrgen-divmod \ 156 | is set" 157 | end) 158 | 159 | module Bitwise = True 160 | (struct 161 | let option_name = "-ldrgen-bitwise" 162 | let help = "allow generation of bitwise operations" 163 | end) 164 | 165 | module Loops = True 166 | (struct 167 | let option_name = "-ldrgen-loops" 168 | let help = "allow generation of loops" 169 | end) 170 | 171 | module WhileLoops = True 172 | (struct 173 | let option_name = "-ldrgen-while-loops" 174 | let help = "allow generation of while loops" 175 | end) 176 | 177 | module ForLoops = True 178 | (struct 179 | let option_name = "-ldrgen-for-loops" 180 | let help = "allow generation of for loops" 181 | end) 182 | 183 | let initialize () = 184 | (* Fake some command line settings to keep Frama-C from complaining about 185 | missing input files, and about problems preprocessing [/dev/null]. *) 186 | Kernel.Verbose.set 0; 187 | Kernel.Files.set [Fc_Filepath.of_string "/dev/null"]; 188 | Kernel.CppCommand.set "/usr/bin/true"; 189 | Kernel.CppGnuLike.set false; 190 | (* Initialize the random number generator. *) 191 | if Seed.is_default () then begin 192 | Random.self_init (); 193 | let s = Random.bits () in 194 | Seed.set s 195 | end; 196 | Random.init (Seed.get ()) 197 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ldrgen 2 | 3 | This is ldrgen, a small experimental random C program generator. 4 | 5 | 6 | ## Introduction 7 | 8 | This program is a generator of C code: On every call it generates a new 9 | random C function and prints it to the standard output. The generator is 10 | "liveness-driven", which means that it tries to avoid generating dead code: 11 | All the computations it generates are (in a certain, limited sense) actually 12 | used to compute the function's return value. Other than this, ldrgen does 13 | not do much to ensure that its output resembles anything like "real" 14 | programs. 15 | 16 | See [Csmith](https://github.com/csmith-project/csmith) for another C program 17 | generator that is in many ways more sophisticated than this. 18 | 19 | A paper describing ldrgen has been accepted for presentation at the LOPSTR 20 | 2017 conference. A preprint is at 21 | [lopstr2017_ldrgen_preprint.pdf](lopstr2017_ldrgen_preprint.pdf). 22 | 23 | 24 | ## Examples 25 | 26 | Here is a small example program generated by ldrgen: 27 | 28 | ```c 29 | /* Generated by Frama-C */ 30 | // Generated by ldrgen 31 | // Seed: 82678471 32 | // Command line arguments: -ldrgen -ldrgen-stmt-depth 2 -ldrgen-expr-depth 3 33 | short fn1(char p, double p_5, unsigned long p_7, unsigned int p_11, 34 | unsigned short p_17, long long p_21, double p_25, 35 | unsigned char p_27) 36 | { 37 | double v_51; 38 | long v_49; 39 | float v_47; 40 | unsigned char v_45; 41 | unsigned long long v_43; 42 | short v_41; 43 | unsigned int v_39; 44 | signed char v_37; 45 | long long v_35; 46 | unsigned short v_33; 47 | unsigned long v_31; 48 | double v_29; 49 | unsigned int v_23; 50 | int v_19; 51 | unsigned long long v_15; 52 | long long v_13; 53 | unsigned short v_9; 54 | unsigned char v; 55 | short result; 56 | v_51 = p_5; 57 | v_47 = -7300539349.21f; 58 | v_43 = 18446744073709511602ULL; 59 | v_41 = (short)-20504; 60 | v_35 = -26125LL; 61 | v_31 = 4169455334UL; 62 | v_29 = 670.493914988; 63 | v_23 = 4245290602U; 64 | v_19 = -2470; 65 | v_13 = 1064779636LL; 66 | v_9 = (unsigned short)45625; 67 | v_49 = (long)(- ((v_51 - (double)(unsigned short)38061) / ((double)(signed char)53 * p_25 + (double)404))); 68 | if ((unsigned int)(-3.2054506015e+38 * (double)((unsigned long)4864751150.7 * p_7)) + ( 69 | (unsigned int)(~ v_41) - (p_11 - (unsigned int)v_47)) == (unsigned int)( 70 | (double)(- v_49) / (- p_5 + (double)87))) { 71 | v_41 = (short)((long long)(- (p_7 - p_7)) + - p_21); 72 | v_9 = (unsigned short)((long long)p_17 + (long long)p_25 % (((long long)p - v_35) + 719LL)); 73 | v_39 = (unsigned int)((int)(- ((float)(short)-21044 * 3.19873597495e+37f))); 74 | v_15 = (unsigned long long)(- ((unsigned long)(~ v_39) / 3082953060UL)); 75 | v_23 = (unsigned int)(- ((v_15 | 18446744073709503346ULL) % 4294921912ULL)); 76 | } 77 | else { 78 | v_45 = (unsigned char)(! (-33986LL + p_21 / -107602102LL)); 79 | v_13 = (long long)(~ (- ((long)v_45 * -128552529L))); 80 | v_31 = 74UL; 81 | v_29 = (double)(~ ((unsigned long long)p_7 - 18446744073406306995ULL * v_43)); 82 | v_15 = (unsigned long long)(172U + ~ (~ p_11)); 83 | } 84 | while (~ v_23 < 1U) { 85 | v_19 = (int)((char)v_29) % 125; 86 | v_37 = (signed char)-9951321808.38; 87 | v_33 = (unsigned short)(((double)v_37 * (p_5 - (double)p)) / (double)18446744073294828742ULL); 88 | v_15 = (unsigned long long)(((double)((int)v_33 * 78) * - p_5) * (double)( 89 | (long long)(~ p_7) / ((215LL - v_35) + 852LL))); 90 | v_13 = (long long)(~ (~ (! p_11))); 91 | v_23 = (unsigned int)(2729386713.2f + (float)(! p_21 * (long long)v_31)); 92 | } 93 | if ((unsigned long long)((float)(p_7 / 64249UL + (unsigned long)((unsigned int)v_9 * p_11)) * ( 94 | (1.88298916636e+38f - (float)v_13) - (float)( 95 | v_15 % 203ULL))) <= (unsigned long long)((long long)( 96 | -120 / ( 97 | (int)p_17 + 71)) + ( 98 | (long long)v_19 - p_21)) * 4294946671ULL) { 99 | v = (unsigned char)(~ ((unsigned long long)p_5 - 42536ULL) % (unsigned long long)( 100 | (long)(- -6414484372.37) % 43253L + 627L)); 101 | result = (short)((84 + (int)(- v)) + (int)(- p)); 102 | } 103 | else result = (short)-24120; 104 | return result; 105 | } 106 | ``` 107 | 108 | 109 | ## TODOs 110 | 111 | Many more C language constructs should be added. 112 | 113 | 114 | ## Installation 115 | 116 | This program is implemented as a plugin for Frama-C . 117 | It should run on all Unix-like platforms with Frama-C and standard build 118 | tools. 119 | 120 | Your favorite package manager may provide a Frama-C package that installs 121 | all you need. Otherwise, the easiest way to install Frama-C is to first 122 | install OPAM, the OCaml package manager . You can 123 | then run: 124 | 125 | opam install frama-c 126 | 127 | See for more information on 128 | installing Frama-C via OPAM. ldrgen is known to work with Frama-C 31.0 129 | (Gallium) on OCaml 5.3.0 installed via OPAM 2.1.6. 130 | 131 | With Frama-C installed and the `frama-c` executable in your path, you can 132 | compile ldrgen by running `dune build` and install it with `dune install`. 133 | It will be installed in Frama-C's plugin directory. You can remove it again 134 | by running `dune uninstall`. 135 | 136 | For now, run ldrgen as `frama-c -ldrgen`. See `frama-c -ldrgen-h` for 137 | documentation on some command-line flags that can affect the generated code. 138 | 139 | 140 | ## Contact 141 | 142 | This program was written by Gergö Barany . It lives at 143 | . 144 | 145 | Comments, questions, bug reports, feature requests, and patches are welcome! 146 | 147 | 148 | ## Copying 149 | 150 | This program is free software: you can redistribute it and/or modify it 151 | under the terms of the GNU General Public License as published by the Free 152 | Software Foundation, either version 3 of the License, or (at your option) 153 | any later version. 154 | 155 | This program is distributed in the hope that it will be useful, but WITHOUT 156 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 157 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 158 | more details. 159 | 160 | You should have received a copy of the GNU General Public License along with 161 | this program (file LICENSE). If not, see . 162 | -------------------------------------------------------------------------------- /generate.ml: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* ldrgen, a generator of random C programs *) 4 | (* Copyright (C) 2017-2025, Gergö Barany *) 5 | (* *) 6 | (* This program is free software: you can redistribute it and/or modify *) 7 | (* it under the terms of the GNU General Public License as published by *) 8 | (* the Free Software Foundation, either version 3 of the License, or *) 9 | (* (at your option) any later version. *) 10 | (* *) 11 | (* This program is distributed in the hope that it will be useful, *) 12 | (* but WITHOUT ANY WARRANTY; without even the implied warranty of *) 13 | (* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) 14 | (* GNU General Public License for more details. *) 15 | (* *) 16 | (* You should have received a copy of the GNU General Public License *) 17 | (* along with this program. If not, see . *) 18 | (* *) 19 | (**************************************************************************) 20 | 21 | open Cil_const 22 | open Cil_types 23 | open Cil_datatype 24 | 25 | module LvalSet = struct 26 | include LvalStructEq.Set 27 | 28 | let add_vi vi = add (Cil.var vi) 29 | let singleton_vi vi = singleton (Cil.var vi) 30 | end 31 | 32 | let loc = Location.unknown 33 | 34 | (* The function we're building. *) 35 | let fundec = ref (Cil.emptyFunction "fn1") 36 | 37 | (* "Parameter lvalues" are lvalues that may be used in expressions and are 38 | based on function parameters. If the parameter is a pointer, the 39 | corresponding lvalue in this set is dereferenced appropriately. *) 40 | let param_lvals = ref (LvalSet.empty) 41 | 42 | (* Global variable for modeling the sizes of arrays. *) 43 | let array_size_var = ref None 44 | 45 | let array_size () = 46 | match !array_size_var with 47 | | Some vi -> Cil.evar vi 48 | | None -> 49 | let vi = Cil.makeGlobalVar "N" uintType in 50 | vi.vstorage <- Extern; 51 | array_size_var := Some vi; 52 | Cil.evar vi 53 | 54 | (* Build an assignment of the value of [exp] to [lval]. The [exp] is 55 | automatically cast to the [lval]'s type if needed. *) 56 | let assign lval exp = 57 | let typ = Cil.typeOfLval lval in 58 | let exp = Cil.mkCast ~force:false exp ~newt:typ in 59 | Set (lval, exp, loc) 60 | 61 | let gen_type () = 62 | let open Options in 63 | let types = [intType; uintType; longType; ulongType; 64 | charType; scharType; ucharType; 65 | shortType; ushortType] 66 | in 67 | let fp_types = 68 | if Options.Float.get () then [floatType; doubleType] else [doubleType] 69 | in 70 | let types = 71 | if FloatingPoint.get () then fp_types @ types else types 72 | in 73 | let types = 74 | if LongLong.get () then [longLongType; ulongLongType] @ types else types 75 | in 76 | let types = 77 | if FloatingPointOnly.get () then fp_types else types 78 | in 79 | let types = 80 | (* There is a conflict between [-int-only] and [-float-only]; the former 81 | wins. There's no very good way to warn about this. *) 82 | if IntOnly.get () then begin 83 | LongLong.set false; (* don't want [long long] to appear in modulo *) 84 | [intType; uintType] 85 | end else types 86 | in 87 | Utils.random_select types 88 | 89 | let gen_compound_type ~base_type = 90 | let rec gen_multidim_array ~dim ~typ = 91 | if dim = 0 then 92 | typ 93 | else 94 | let typ = 95 | let length = Random.int (Options.MaxArrayLengthPerDim.get ()) + 1 in 96 | mk_tarray typ (Some (Cil.integer ~loc length)) 97 | in 98 | gen_multidim_array ~dim:(dim - 1) ~typ 99 | in 100 | let types = 101 | if Options.PointerArgs.get () then 102 | [mk_tptr base_type] 103 | else 104 | [] 105 | in 106 | let types = 107 | if Options.Arrays.get () then 108 | let dim = Random.int (Options.MaxArrayDim.get ()) + 1 in 109 | gen_multidim_array ~dim ~typ:base_type :: types 110 | else 111 | types 112 | in 113 | Utils.random_select types 114 | 115 | let gen_local_var ?basename typ = 116 | let name = match basename with Some n -> n | None -> "v" in 117 | Cil.makeLocalVar !fundec name typ 118 | 119 | let gen_formal_var ?basename typ = 120 | (* Only actually generate a new formal if we haven't exhausted the maximum 121 | number of arguments. *) 122 | if List.length !fundec.sformals < Options.MaxArgs.get () then begin 123 | let name = match basename with Some n -> n | None -> "p" in 124 | let vi = Cil.makeFormalVar !fundec name typ in 125 | if Ast_types.is_ptr typ then 126 | let mem = (Mem (Cil.evar vi), NoOffset) in 127 | param_lvals := LvalSet.add mem !param_lvals 128 | else 129 | param_lvals := LvalSet.add_vi vi !param_lvals; 130 | vi 131 | end else 132 | Utils.random_select !fundec.sformals 133 | 134 | let gen_var ?basename ?(local_only=false) typ = 135 | let gen_funcs = 136 | if local_only then [gen_local_var] else [gen_local_var; gen_formal_var] 137 | in 138 | let f = Utils.random_select gen_funcs in 139 | let vi = f ?basename typ in 140 | (* Use the [vreferenced] field to indicate whether this variable is ever 141 | used. The [gen_lval_use] function below sets it. It is never reset. *) 142 | vi.vreferenced <- false; 143 | vi 144 | 145 | let gen_vars n = 146 | let rec loop i acc = 147 | if i > 0 then 148 | let vi = gen_var ~local_only:true (gen_type ()) in 149 | loop (i - 1) (LvalSet.add_vi vi acc) 150 | else 151 | acc 152 | in 153 | loop n LvalSet.empty 154 | 155 | let gen_return ?typ () = 156 | let typ = match typ with Some t -> t | None -> gen_type () in 157 | let var = gen_local_var ~basename:"result" typ in 158 | let live = LvalSet.singleton_vi var in 159 | (live, Cil.mkStmt ~valid_sid:true (Return (Some (Cil.evar var), loc))) 160 | 161 | let format_of_fkind = function 162 | | FFloat -> Floating_point.Single 163 | | FDouble -> Floating_point.Double 164 | | FLongDouble -> Floating_point.Double 165 | 166 | (* For integer or floating-point types, generate a random number (possibly 167 | negative) of the appropriate type. For other types, just generate a zero 168 | of the appropriate type. *) 169 | let gen_const typ = 170 | let sign = if Random.bool () then 1 else -1 in 171 | match typ.tnode with 172 | | TInt ikind -> 173 | let i = Random.bits () in 174 | (* Make small-ish constants more likely. *) 175 | let i = if Random.bool () then i mod (1 lsl 16) else i in 176 | Cil.kinteger ~loc ikind (sign * i) 177 | | TFloat fkind -> 178 | let max = Floating_point.largest_finite_float_of (format_of_fkind fkind) in 179 | (* Try to allow generation of small constants; without something like 180 | this, almost all floating point constants would be in the 1e37-1e38 181 | order of magnitude. *) 182 | let bound = Utils.random_select [1e3; 1e10; max] in 183 | Cil.kfloat ~loc fkind (float_of_int sign *. Random.float bound) 184 | | _ -> 185 | Cil.mkCast ~force:false (Cil.zero ~loc) ~newt:typ 186 | 187 | let gen_array_elt (lhost, offset as lval) = 188 | let rec gen_offset = function 189 | | TInt _ | TFloat _ -> 190 | NoOffset 191 | | TArray (t, e) -> 192 | Index 193 | (Cil.(integer ~loc (Random.int (lenOfArray e))), 194 | gen_offset t.tnode) 195 | | _ -> 196 | assert false 197 | in 198 | match (Cil.typeOfLval lval).tnode with 199 | | TArray _ as typ -> 200 | assert (offset = NoOffset); (* By construction. See [new_lval]. *) 201 | let offset = gen_offset typ in 202 | lhost, offset 203 | | typ -> 204 | let err_msg = 205 | Format.asprintf 206 | "Expected lvalue of array type, got `%a'." 207 | Cil_printer.pp_typ { tnode = typ; tattr = [] } 208 | in 209 | raise (Invalid_argument err_msg) 210 | 211 | let gen_lval_occurrence lval = 212 | if Ast_types.is_array (Cil.typeOfLval lval) then 213 | (* Arrays are generated as a single lvalue with array type. Here we need to 214 | actually pick an element of the array [lval]. *) 215 | gen_array_elt lval 216 | else 217 | lval 218 | 219 | (* Initialize a local variable to a constant or a parameter. *) 220 | let gen_local_init lval = 221 | let gen_param_use typ = 222 | if not (LvalSet.is_empty !param_lvals) then 223 | let lval = Utils.random_select_from_set !param_lvals in 224 | let lval = gen_lval_occurrence lval in 225 | let e = Cil.new_exp ~loc (Lval lval) in 226 | Cil.mkCast ~force:false e ~newt:typ 227 | else 228 | (* OK, fall back to constants. *) 229 | gen_const typ 230 | in 231 | let generators = [gen_const; gen_param_use] in 232 | let f = Utils.random_select generators in 233 | let assign = assign lval (f (Cil.typeOfLval lval)) in 234 | Cil.mkStmtOneInstr ~valid_sid:true assign 235 | 236 | let new_lval () = 237 | let typ = gen_type () in 238 | let vi = 239 | if List.length !fundec.sformals < Options.MaxArgs.get () && 240 | (Options.PointerArgs.get () || Options.Arrays.get ()) && 241 | Random.float 1.0 < 0.1 242 | then 243 | (* Make a parameter of pointer or array type. *) 244 | let ptr_or_array_typ = gen_compound_type ~base_type:typ in 245 | gen_formal_var ptr_or_array_typ 246 | else 247 | (* Make a plain variable. *) 248 | let vi = gen_var typ in 249 | vi.vreferenced <- true; 250 | vi 251 | in 252 | if Ast_types.is_ptr vi.vtype then 253 | (Mem (Cil.evar vi), NoOffset) 254 | else 255 | (Var vi, NoOffset) 256 | 257 | let gen_lval_use ~num_live () = 258 | (* Select a known local var or parameter of the function, or generate a 259 | new variable. *) 260 | let select_or_new vars = 261 | if vars <> [] then begin 262 | let vi = Utils.random_select vars in 263 | vi.vreferenced <- true; 264 | (Var vi, NoOffset) 265 | end else 266 | new_lval () 267 | in 268 | let use_param () = 269 | if LvalSet.is_empty !param_lvals then 270 | new_lval () 271 | else 272 | Utils.random_select_from_set !param_lvals 273 | in 274 | let use_local () = select_or_new !fundec.slocals in 275 | (* Try to generate new variables if we don't have many live ones; pick 276 | existing ones if enough are live. *) 277 | let lval = 278 | if Random.int (Options.MaxLive.get ()) > num_live then 279 | new_lval () 280 | else 281 | let f = Utils.random_select [use_param; use_local] in 282 | f () 283 | in 284 | let lval = gen_lval_occurrence lval in 285 | (* We never want to generate assignments to the function's formal 286 | parameters. This is easy: We simply never put them into the live set, 287 | which is where variables to assign to are selected from. 288 | [Utils.free_vars] only selects locals, not formals. *) 289 | let exp = Cil.new_exp ~loc (Lval lval) in 290 | let live = LvalSet.of_list (Utils.free_vars exp) in 291 | (live, exp) 292 | 293 | let gen_leaf_exp ~depth ~num_live () = 294 | ignore depth; 295 | let gen_const ~num_live () = 296 | ignore num_live; 297 | let typ = gen_type () in 298 | (LvalSet.empty, gen_const typ) 299 | in 300 | (* Prefer variables over constants to discourage constant folding and 301 | propagation, i.e., to avoid making the compiler's job too easy. *) 302 | let f = Utils.random_select [gen_const; gen_lval_use; gen_lval_use] in 303 | f ~num_live () 304 | 305 | (* Make sure that either both expressions are integers or both are 306 | floating-point values (picking randomly, if originally one is integer and 307 | the other floating). Return a pair of the two expressions with 308 | appropriate casts. *) 309 | let gen_common_type_exprs expr1 expr2 = 310 | let is_int e = Ast_types.is_integral (Cil.typeOf e) in 311 | let is_float e = Ast_types.is_float (Cil.typeOf e) in 312 | if is_int expr1 && is_int expr2 || is_float expr1 && is_float expr2 then 313 | (expr1, expr2) 314 | else 315 | let typ = Utils.random_select [Cil.typeOf expr1; Cil.typeOf expr2] in 316 | let cast_to_common_typ e = Cil.mkCast ~force:false e ~newt:typ in 317 | (cast_to_common_typ expr1, cast_to_common_typ expr2) 318 | 319 | let choose_binop typ = 320 | let binops = 321 | if Ast_types.is_integral typ then 322 | (* Prefer arithmetic over bitwise operations; prefer other bitwise 323 | operations over shifts. *) 324 | let bitwise = 325 | if Options.Bitwise.get () then 326 | let shift = Utils.random_select [Shiftlt; Shiftrt] in 327 | let bitwise = Utils.random_select [shift; BAnd; BXor; BOr] in 328 | [bitwise] 329 | else 330 | [] 331 | in 332 | bitwise @ [PlusA; MinusA; Mult] 333 | else 334 | [PlusA; MinusA; Mult] 335 | in 336 | let binops = 337 | if Options.DivMod.get () then 338 | if Ast_types.is_integral typ then 339 | [Div] @ (if Options.Mod.get () then [Mod] else []) @ binops 340 | else 341 | [Div] @ binops 342 | else 343 | binops 344 | in 345 | Utils.random_select binops 346 | 347 | (* For some operations, it's best to patch the RHS operand to avoid some 348 | common problems. *) 349 | let fixup_binop_rexp op lexp rexp = 350 | match op with 351 | | Shiftlt | Shiftrt -> 352 | (* Generate a bit mask expression to transform this operand into the 353 | legal range. *) 354 | let lhs_bitsize = Cil.bitsSizeOf (Cil.typeOf lexp) in 355 | let mask = Cil.integer ~loc (lhs_bitsize - 1) in 356 | Cil.mkBinOp ~loc BAnd rexp mask 357 | | Div | Mod -> 358 | let rexp = Cil.constFold true rexp in 359 | begin match Cil.isInteger rexp with 360 | | Some n when not (Integer.equal Integer.zero n) -> 361 | (* Division by a nonzero integer. OK, keep it. *) 362 | rexp 363 | | _ -> 364 | (* Something other than a nonzero integer. Add a small random 365 | integer, just to be on the safe side; it's unlikely that this 366 | produces a constant zero. *) 367 | let random_num = Cil.integer ~loc (Random.int 1024 + 1) in 368 | Cil.mkBinOp ~loc PlusA rexp random_num 369 | end 370 | | _ -> rexp 371 | 372 | let gen_binop_for (llive, lexp) (rlive, rexp) = 373 | let lexp, rexp = gen_common_type_exprs lexp rexp in 374 | let op = choose_binop (Cil.typeOf lexp) in 375 | let rexp' = fixup_binop_rexp op lexp rexp in 376 | let live = LvalSet.union llive rlive in 377 | (live, Cil.mkBinOp ~loc op lexp rexp') 378 | 379 | let rec gen_exp ~depth ~num_live () = 380 | let generators = 381 | if depth <= Options.ExprDepth.get () then 382 | (* Prefer binary operations over all other kinds. *) 383 | [gen_leaf_exp; gen_binop; gen_binop; gen_unop] 384 | else 385 | [gen_leaf_exp] 386 | in 387 | let f = Utils.random_select generators in 388 | let live, exp = f ~depth ~num_live () in 389 | (* We sometimes generate expressions that constant fold to floating point 390 | infinities. These would get printed as "inff" and cause compiler 391 | errors. In such cases, try again. *) 392 | if Utils.is_infinity exp then 393 | gen_exp ~depth ~num_live () 394 | else 395 | live, exp 396 | 397 | and gen_binop ~depth ~num_live () = 398 | let depth = depth + 1 in 399 | let llive, lexp = gen_exp ~depth ~num_live () in 400 | let rlive, rexp = gen_exp ~depth ~num_live () in 401 | gen_binop_for (llive, lexp) (rlive, rexp) 402 | 403 | and gen_unop ~depth ~num_live () = 404 | let depth = depth + 1 in 405 | let live, exp = gen_exp ~depth ~num_live () in 406 | let typ = Cil.typeOf exp in 407 | let unops = 408 | if Ast_types.is_integral typ && Options.Bitwise.get () then 409 | [Neg; BNot; LNot] 410 | else 411 | [Neg] 412 | in 413 | let op = Utils.random_select unops in 414 | (live, Cil.new_exp ~loc (UnOp (op, exp, typ))) 415 | 416 | let gen_exp ~num_live ?typ () = 417 | let live, exp = gen_exp ~depth:1 ~num_live () in 418 | match typ with 419 | | Some typ -> (live, Cil.mkCast ~force:false exp ~newt:typ) 420 | | None -> (live, exp) 421 | 422 | let gen_cond ~num_live () = 423 | (* Make sure a condition always uses at least one variable. *) 424 | let rec make_nonconst_exprs () = 425 | let llive, lexp = gen_exp ~num_live () in 426 | let rlive, rexp = gen_exp ~num_live () in 427 | let live = LvalSet.union llive rlive in 428 | if LvalSet.is_empty live then 429 | make_nonconst_exprs () 430 | else 431 | let lexp, rexp = gen_common_type_exprs lexp rexp in 432 | (live, lexp, rexp) 433 | in 434 | let live, lexp, rexp = make_nonconst_exprs () in 435 | let comparisons = [Lt; Gt; Le; Ge; Eq; Ne] in 436 | let cmp = Utils.random_select comparisons in 437 | (live, Cil.mkBinOp ~loc cmp lexp rexp) 438 | 439 | let gen_assignment_to lval ~depth ~live () = 440 | ignore depth; 441 | let num_live = LvalSet.cardinal live in 442 | let typ = Cil.typeOfLval lval in 443 | let (new_live_vars, exp) = gen_exp ~num_live ~typ () in 444 | let live = 445 | LvalSet.union (LvalSet.remove lval live) new_live_vars 446 | in 447 | let assign = assign lval exp in 448 | let stmt = Cil.mkStmtOneInstr ~valid_sid:true assign in 449 | (live, stmt) 450 | 451 | let gen_assignment ~depth ~live () = 452 | let vi = Utils.random_select_from_set live in 453 | gen_assignment_to vi ~depth ~live () 454 | 455 | let rec gen_stmt ~depth ~live () = 456 | let generators = 457 | if depth < Options.StmtDepth.get () then 458 | let gens = [gen_assignment; gen_if_stmt] in 459 | if Options.Loops.get () then [gen_loop] @ gens else gens 460 | else 461 | [gen_assignment] 462 | in 463 | let f = Utils.random_select generators in 464 | f ~depth ~live () 465 | 466 | and gen_if_stmt ~depth ~live () = 467 | let depth = depth + 1 in 468 | let (true_live, true_stmts) = gen_stmts ~depth ~live ~tail:[] () in 469 | let (false_live, false_stmts) = gen_stmts ~depth ~live ~tail:[] () in 470 | let body_live = LvalSet.union true_live false_live in 471 | let num_live = LvalSet.cardinal body_live in 472 | let (cond_new_live, cond) = gen_cond ~num_live () in 473 | let live = LvalSet.union body_live cond_new_live in 474 | let if_stmt = 475 | Cil.mkStmt ~valid_sid:true 476 | (If (cond, Cil.mkBlock true_stmts, Cil.mkBlock false_stmts, loc)) 477 | in 478 | (live, if_stmt) 479 | 480 | and gen_loop ~depth ~live () = 481 | let while_loop = 482 | if Options.WhileLoops.get () then [gen_while_loop] else [] 483 | in 484 | (* We can only generate a for loop if we can generate a corresponding 485 | array argument. *) 486 | let generators = 487 | if Options.ForLoops.get () && 488 | List.length !fundec.sformals < Options.MaxArgs.get () then 489 | [gen_for_loop] @ while_loop 490 | else 491 | while_loop 492 | in 493 | let generators = 494 | (* We may have found a combination of command line arguments and program 495 | state that doesn't allow us to generate a loop after all. In that 496 | case, try some other statement. *) 497 | if generators = [] then [gen_stmt] else generators 498 | in 499 | let generator = Utils.random_select generators in 500 | generator ~depth ~live () 501 | 502 | and gen_for_loop ~depth ~live () = 503 | ignore depth; 504 | (* loop counter *) 505 | let i = gen_local_var ~basename:"i" uintType in 506 | (* array parameter *) 507 | let elem_typ = gen_type () in 508 | let ptr_typ = mk_tptr elem_typ in 509 | let a = gen_formal_var ~basename:"arr" ptr_typ in 510 | (* Hack: [gen_formal_var] put [a] into the set of usable formals, but we 511 | only ever want to use this array in the context of this loop, so remove 512 | it from there. *) 513 | param_lvals := LvalSet.remove (Var a, NoOffset) !param_lvals; 514 | (* The loop body will be of the form 515 | x = arr[i]; 516 | r = r op exp(x); 517 | for some random expression [exp] and a random binary operator [op]. 518 | That is, we map [exp] over the array, then reduce (fold) with [op], and 519 | put the result in [r]. *) 520 | (* Result of the loop computation. *) 521 | let r = Utils.random_select_from_set live in 522 | let live' = LvalSet.remove r live in 523 | let num_live = LvalSet.cardinal live' in 524 | (* The last statement of the block is an assignment to this result 525 | variable, combining its old value with some new, nontrivial expression 526 | that will be made to use a reference to [a[i]]. *) 527 | let rec gen_nonconst_rexp () = 528 | let (rlive, rexp) = gen_exp ~num_live ~typ:(Cil.typeOfLval r) () in 529 | if Utils.free_vars rexp = [] then 530 | gen_nonconst_rexp () 531 | else 532 | (rlive, rexp) 533 | in 534 | let (rlive, rexp) = gen_nonconst_rexp () in 535 | let (llive, lexp) = (LvalSet.empty, Cil.new_exp ~loc (Lval r)) in 536 | let assign_live, assign_exp = gen_binop_for (llive, lexp) (rlive, rexp) in 537 | let assign_stmt = 538 | Cil.mkStmtOneInstr ~valid_sid:true (assign r assign_exp) 539 | in 540 | let use_var = Utils.random_select (Utils.free_vars rexp) in 541 | let use_stmt = 542 | let array_elem = 543 | Cil.mkMem 544 | ~addr:(Cil.mkBinOp ~loc PlusPI (Cil.evar a) (Cil.evar i)) 545 | ~off:NoOffset 546 | in 547 | let array_elem_exp = Cil.new_exp ~loc (Lval array_elem) in 548 | Cil.mkStmtOneInstr ~valid_sid:true (assign use_var array_elem_exp) 549 | in 550 | (* The body consists of these two assignments. *) 551 | let use_live = LvalSet.remove r assign_live in 552 | let (body_live, body) = (use_live, [use_stmt; assign_stmt]) in 553 | (* Finally, make a loop for i from 0 to N over this body. *) 554 | let for_stmt_list = 555 | Cil.mkForIncr 556 | ~iter:i 557 | ~first:(Cil.mkCast ~force:true (Cil.zero ~loc) ~newt:uintType) 558 | ~stopat:(array_size ()) 559 | ~incr:(Cil.one ~loc) 560 | ~body () 561 | in 562 | let for_stmt = 563 | Cil.mkStmt ~valid_sid:true (Block (Cil.mkBlock for_stmt_list)) 564 | in 565 | (* Now, the variables live before the loop are the variables live into the 566 | body, as well as [r], since it must be initialized. And, of course, 567 | whatever is live after the body. *) 568 | let live = LvalSet.union (LvalSet.add r body_live) live' in 569 | (live, for_stmt) 570 | 571 | and gen_while_loop ~depth ~live () = 572 | let depth = depth + 1 in 573 | (* Save the variables that are live after the loop. They may be defined in 574 | the loop body, but must nevertheless still be live before the loop. *) 575 | let live_out = live in 576 | let num_live = LvalSet.cardinal live in 577 | let (cond_new_live, cond) = gen_cond ~num_live () in 578 | (* Generate a set of newly used variables in the loop. Some of these will 579 | be loop-carried dependences. *) 580 | let num_live = num_live + LvalSet.cardinal cond_new_live in 581 | let n = 582 | if num_live >= Options.MaxLive.get () then 583 | Random.int 2 + 1 584 | else 585 | Random.int ((Options.MaxLive.get () + 1 - num_live) / 2) + 1 586 | in 587 | let body_new_live = gen_vars n in 588 | let body_live_out = 589 | LvalSet.union live_out 590 | (LvalSet.union cond_new_live body_new_live) 591 | in 592 | let live = body_live_out in 593 | (* Try to generate an assignment to one of the variables in the condition. 594 | This is meant to simulate some kind of progress towards termination of 595 | the loop. *) 596 | let (live, tail) = 597 | let cond_vars = Utils.free_vars cond in 598 | if cond_vars <> [] then 599 | let vi = Utils.random_select cond_vars in 600 | let (live, stmt) = gen_assignment_to vi ~depth ~live () in 601 | (live, [stmt]) 602 | else 603 | (live, []) 604 | in 605 | let (body_live_in, stmts) = gen_stmts ~depth ~live ~tail () in 606 | (* Now we must ensure that every variable in [body_new_live] does actually 607 | have a use before a possible redefinition in the loop. If there is a 608 | redefinition but no use before it, the variable is not live into the 609 | body. Otherwise, the variable is not used at all. Both conditions are 610 | checked here. *) 611 | let referenced_vi = function 612 | | Var vi, _ -> vi.vreferenced 613 | | _ -> false 614 | in 615 | let need_use = 616 | LvalSet.filter 617 | (fun b -> not (LvalSet.mem b body_live_in) || not (referenced_vi b)) 618 | body_new_live 619 | in 620 | let (body_live_in', stmts') = 621 | if LvalSet.is_empty need_use then 622 | (body_live_in, stmts) 623 | else begin 624 | (* Make an assignment using all the variables in [need_use]. *) 625 | let (newly_live, exp) = 626 | LvalSet.fold 627 | (fun lval acc -> 628 | let exp = Cil.new_exp ~loc (Lval lval) in 629 | gen_binop_for (LvalSet.singleton lval, exp) acc) 630 | need_use 631 | (LvalSet.empty, gen_const (gen_type ())) 632 | in 633 | assert (LvalSet.equal newly_live need_use); 634 | (* For the LHS choose a currently live variable. If there is none, 635 | things get a bit more annoying. *) 636 | let (stmts, lval) = 637 | if LvalSet.is_empty body_live_in then begin 638 | (* The only way everything could have been killed is through an 639 | assignment to some variable. Pick that variable and remove the 640 | assignment. *) 641 | match stmts with 642 | | { skind = Instr (Set (lval, _exp, _)); _ } :: stmts -> 643 | (stmts, lval) 644 | | _ -> assert false 645 | end else 646 | (stmts, Utils.random_select_from_set body_live_in) 647 | in 648 | let body_live_in' = 649 | LvalSet.union (LvalSet.remove lval body_live_in) newly_live 650 | in 651 | let assign = assign lval exp in 652 | let assign_stmt = Cil.mkStmtOneInstr ~valid_sid:true assign in 653 | (body_live_in', assign_stmt :: stmts) 654 | end 655 | in 656 | let loop = Cil.mkLoop ~sattr:[] ~guard:cond ~body:stmts' () in 657 | let live = 658 | LvalSet.union 659 | (LvalSet.union cond_new_live body_live_in') 660 | live_out 661 | in 662 | (live, Cil.mkStmt ~valid_sid:true (Block (Cil.mkBlock loop))) 663 | 664 | and gen_stmts ?n ~depth ~live ~tail () = 665 | let rec rec_gen_stmts n ~live ~tail = 666 | (* Stop when we have generated [n] statements or when we have no more 667 | live variables to define. *) 668 | if n < 1 || LvalSet.is_empty live then 669 | (live, tail) 670 | else 671 | let (live, stmt) = gen_stmt ~depth ~live () in 672 | rec_gen_stmts (n-1) ~live ~tail:(stmt :: tail) 673 | in 674 | let n = 675 | match n with 676 | | Some n -> n 677 | | None -> Options.BlockLength.get () - List.length tail 678 | in 679 | rec_gen_stmts n ~live ~tail 680 | 681 | let gen_function () = 682 | let typ = gen_type () in 683 | Cil.setReturnType !fundec typ; 684 | let (live, return) = gen_return ~typ () in 685 | let (live', stmts) = gen_stmts ~depth:1 ~live ~tail:[return] () in 686 | !fundec.sbody.bstmts <- stmts; 687 | (* Initialize all live non-formal local variables. *) 688 | let glob_or_formal_vi = function 689 | | Var vi, _ -> vi.vglob || vi.vformal 690 | | _ -> false 691 | in 692 | LvalSet.iter 693 | (fun vi -> 694 | if not (glob_or_formal_vi vi) then 695 | let init = gen_local_init vi in 696 | !fundec.sbody.bstmts <- init :: !fundec.sbody.bstmts) 697 | live'; 698 | (* Register the function definition as global. *) 699 | !fundec.svar.vdefined <- true; 700 | Globals.Functions.replace_by_definition !fundec.sspec !fundec loc; 701 | (* Compute the control-flow graph of the function to ensure a well-formed AST. 702 | This is typically needed when several analyses are chained in Frama-C. *) 703 | Cfg.prepareCFG !fundec; 704 | Cfg.cfgFun !fundec; 705 | let f = GFun (!fundec, loc) in 706 | f 707 | 708 | let gen_random_function ast = 709 | let f = gen_function () in 710 | (* Set the function's list of formal arguments to its list of formal 711 | arguments. This is silly, but it ensures that we generate a proper 712 | prototype: If the list of formals is empty, the argument list will be 713 | (void) instead of empty (). *) 714 | begin match f with 715 | | GFun (fdec, _) -> Cil.setFormals fdec fdec.sformals 716 | | _ -> () 717 | end; 718 | let global_array_size_var = 719 | match !array_size_var with 720 | | Some vi -> 721 | Globals.Vars.add vi { init = None }; 722 | [GVarDecl (vi, loc)] 723 | | None -> [] 724 | in 725 | ast.globals <- global_array_size_var @ f :: ast.globals 726 | 727 | let gen_header ast = 728 | let header = Format.asprintf 729 | "// Generated by ldrgen\n\ 730 | // Seed: %d\n\ 731 | // Command line arguments:%a" 732 | (Options.Seed.get ()) Utils.print_command_line_args () 733 | in 734 | ast.globals <- GText header :: ast.globals 735 | 736 | let run () = 737 | if Options.Run.get () then begin 738 | Options.initialize (); 739 | let prj = Project.create_by_copy ~last:true "ldrgen" in 740 | Project.on 741 | prj 742 | (fun () -> 743 | let ast = Ast.get () in 744 | gen_random_function ast; 745 | gen_header ast; 746 | if Options.CheckAst.get () then 747 | Filecheck.check_ast ~is_normalized:true ~ast "ldrgen"; 748 | Ast.mark_as_grown (); 749 | Format.printf "%a" Printer.pp_file ast; 750 | let selection = State_selection.with_dependencies Options.Run.self in 751 | Project.clear ~selection ~project:prj ()) 752 | () 753 | end 754 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | --------------------------------------------------------------------------------