├── .gitmodules ├── LICENSE ├── Makefile.bootstrap ├── README.md ├── TODO ├── compiler ├── compiler.py ├── mi2c.py └── parser.py ├── core ├── dict.c ├── dict.h ├── main.c ├── minerva_call.c ├── minerva_concat.c ├── minerva_dict.c ├── minerva_func.c ├── minerva_generic.c ├── minerva_lexer.l ├── minerva_loop.c ├── minerva_parser.y ├── minerva_repl.c ├── minerva_signal.c ├── minerva_trace.c ├── minerva_var.c ├── rand.c ├── random.c └── xmalloc.c ├── include ├── minerva_assert.h ├── minerva_call.h ├── minerva_colors.h ├── minerva_concat.h ├── minerva_dict.h ├── minerva_func.h ├── minerva_generic.h ├── minerva_loop.h ├── minerva_parser.h ├── minerva_refs.h ├── minerva_repl.h ├── minerva_signal.h ├── minerva_trace.h ├── minerva_var.h ├── random.h ├── tree.h └── xmalloc.h ├── mk ├── config.mk ├── core.mk ├── minerva.mk └── target.mk ├── target ├── compare.sh ├── generic │ ├── Makefile │ ├── cast.mi │ ├── mutate.mi │ └── stringify_generic.mi ├── http │ ├── Makefile │ ├── http.abnf │ └── request.mi ├── libc │ ├── Makefile │ ├── generate.c │ ├── generate.h │ ├── libc.mi │ ├── wrappers.c │ └── wrappers.h ├── libressl-bn │ ├── Makefile │ ├── README │ ├── bn.mi │ ├── generate.c │ ├── generate.h │ ├── stringify.c │ └── stringify.h ├── libressl │ ├── Makefile │ ├── asn1.mi │ ├── bn.mi │ ├── generate.c │ ├── generate.h │ └── minerva_vars_init.c ├── lm │ ├── Makefile │ ├── gen.c │ ├── gen.h │ └── lm.mi ├── netbsd-syscalls │ ├── Makefile │ ├── rump-syscalls.c │ ├── rump-syscalls.h │ └── syscalls.mi ├── openssl-bn │ ├── Makefile │ ├── README │ ├── bn.mi │ ├── generate.c │ ├── generate.h │ ├── stringify.c │ └── stringify.h ├── openssl │ ├── Makefile │ ├── asn1.mi │ ├── bn.mi │ ├── minerva_vars_init.c │ └── minerva_vars_init.h ├── toy │ ├── Makefile │ ├── toy.c │ ├── toy.h │ └── toy.mi ├── toy2 │ ├── Makefile │ ├── mutators.mi │ ├── toy.c │ ├── toy.h │ └── toy.mi └── url │ ├── Makefile.curl │ ├── Makefile.fetch │ ├── exec-curl.c │ ├── exec-fetch.c │ ├── exec.h │ ├── url.abnf │ └── urltest.mi └── utils ├── abnf ├── abnf_ast.py ├── compiler.py └── parser.py └── queue ├── .gitignore ├── compare-worker.py ├── lib ├── exceptions.py └── task.py ├── run_fuzz.sh ├── server.py └── worker.py /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/progressbar"] 2 | path = lib/progressbar 3 | url = https://github.com/akat1/progressbar 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Most of the code is released under following license: 2 | 3 | ---------------------------------------------------------------------------- 4 | "THE BEER-WARE LICENSE" 5 | If we meet some day, and you think this stuff is worth it, you can buy us 6 | a beer in return. 7 | ---------------------------------------------------------------------------- 8 | 9 | core/rand.c: 10 | 11 | Borrowed from the FreeBSD 12 | 13 | core/rand.c: 14 | 15 | /*- 16 | * SPDX-License-Identifier: BSD-3-Clause 17 | * 18 | * Copyright (c) 1990, 1993 19 | * The Regents of the University of California. All rights reserved. 20 | * 21 | * Redistribution and use in source and binary forms, with or without 22 | * modification, are permitted provided that the following conditions 23 | * are met: 24 | * 1. Redistributions of source code must retain the above copyright 25 | * notice, this list of conditions and the following disclaimer. 26 | * 2. Redistributions in binary form must reproduce the above copyright 27 | * notice, this list of conditions and the following disclaimer in the 28 | * documentation and/or other materials provided with the distribution. 29 | * 3. Neither the name of the University nor the names of its contributors 30 | * may be used to endorse or promote products derived from this software 31 | * without specific prior written permission. 32 | * 33 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 34 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 35 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 36 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 37 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 38 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 39 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 40 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 41 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 42 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 43 | * SUCH DAMAGE. 44 | * 45 | * Posix rand_r function added May 1999 by Wes Peters . 46 | */ 47 | 48 | core/random.c: 49 | 50 | /*- 51 | * SPDX-License-Identifier: BSD-3-Clause 52 | * 53 | * Copyright (c) 1983, 1993 54 | * The Regents of the University of California. All rights reserved. 55 | * 56 | * Redistribution and use in source and binary forms, with or without 57 | * modification, are permitted provided that the following conditions 58 | * are met: 59 | * 1. Redistributions of source code must retain the above copyright 60 | * notice, this list of conditions and the following disclaimer. 61 | * 2. Redistributions in binary form must reproduce the above copyright 62 | * notice, this list of conditions and the following disclaimer in the 63 | * documentation and/or other materials provided with the distribution. 64 | * 3. Neither the name of the University nor the names of its contributors 65 | * may be used to endorse or promote products derived from this software 66 | * without specific prior written permission. 67 | * 68 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 69 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 70 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 71 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 72 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 73 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 74 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 75 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 76 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 77 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 78 | * SUCH DAMAGE. 79 | */ 80 | 81 | include/tree.h: 82 | 83 | /*- 84 | * Copyright 2002 Niels Provos 85 | * All rights reserved. 86 | * 87 | * Redistribution and use in source and binary forms, with or without 88 | * modification, are permitted provided that the following conditions 89 | * are met: 90 | * 1. Redistributions of source code must retain the above copyright 91 | * notice, this list of conditions and the following disclaimer. 92 | * 2. Redistributions in binary form must reproduce the above copyright 93 | * notice, this list of conditions and the following disclaimer in the 94 | * documentation and/or other materials provided with the distribution. 95 | * 96 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 97 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 98 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 99 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 100 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 101 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 102 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 103 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 104 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 105 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 106 | */ 107 | 108 | lib/progressbar: 109 | 110 | Copyright (c) 2010, Trevor Fountain 111 | Copyright (c) 2014, Johannes Buchner 112 | All rights reserved. 113 | 114 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 115 | 116 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 117 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 118 | * Neither the name of software nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 119 | 120 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 121 | -------------------------------------------------------------------------------- /Makefile.bootstrap: -------------------------------------------------------------------------------- 1 | all: git-submodules lib/progressbar/libprogressbar.a 2 | 3 | 4 | git-submodules: 5 | @git submodule init 6 | @git submodule update 7 | 8 | lib/progressbar/libprogressbar.a: 9 | $(MAKE) -C lib/progressbar -f Makefile 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # **minerva_lib a.k.a Polish Fuzzy Lop** 2 | 3 | # Disclaimer 4 | 5 | **Minerva_lib is still in its early development stage, therefore it is full of bugs. It also lacks many features. Since dumb fuzzing is just dumb fuzzing please don't expect any sort of intelligence from it. You're using it at your own risk. You've been warned.** 6 | 7 | **If you would like to contribute to the project, please feel free to submit pull requests, bug reports, letters of complain (or love) etc. Any support is appreciated.** 8 | 9 | # What am I dealing with? 10 | PFL is a fuzzer designed mainly for torturing stuff (mainly libraries or APIs, sometimes co-workers). It uses minerva algorithm (please refer to an article listed as [1] in reading section for any further information). Minerva_lib is able to fuzz any piece of code, as long as it can be linked against its core. 11 | 12 | PFL can also be treated as an animal. Feed it with C function prototypes, supply a simple Makefile and it will treat you with a new shiny fuzzer. 13 | Since, as mentioned earlier on, PFL is in its early development stage, most cases you will have to provide generators though. 14 | 15 | **Let's make dumb fuzzing great again!** 16 | 17 | # How do I add new targets? 18 | We tried to make this process as painless as possible. It is on you to provide config file (target.mi) and magic makefile (refer to a few target examples we provided in case of any problems). Than, PFL generates target.c and target.h, which supported by minerva_core results in target_bin (your shiny fuzzer, that is). 19 | ## Generation process 20 | 21 | +-----------+ +----------------+ 22 | | target.mi |<----------------| magic Makefile | 23 | | (config) | +----------------+ 24 | +-----------+ | 25 | | | things you provide 26 | -- 8< - 8< - 8< - 8< - 8< - 8< - 8< - 8< - 8< ------------------ 27 | | | stuff that is done 28 | | | automatically 29 | | (mi2c compiler) | 30 | | | 31 | v v 32 | +------------+ +--------------+ 33 | | target.[ch]|-------------->| minerva core | 34 | +------------+ +--------------+ 35 | | | 36 | \--------------+---------------/ 37 | | 38 | v 39 | +------------+ 40 | | target_bin | (your shiny fuzzer) 41 | +------------+ 42 | 43 | ## Configuration 44 | The format used in configuration file is very similar to C format. To help you understand it we provide the following scheme. 45 | 46 | include files (e.g.. #include 47 | 48 | C prototypes => check function; (e.g. int foo(int x) => generic_success;) 49 | 50 | ### Toy target 51 | In order to help you get the basics we created a toy target(You can find it in /target/toy directory). Taking toy api's declarations from toy.h: 52 | 53 | int zero(void); 54 | int add_one(int x); 55 | int crashme(int x); 56 | 57 | A configuration file (toy.mi) would look like that: 58 | 59 | #include 60 | #include 61 | --this a comment 62 | int zero() => generic_success; 63 | int add_one(int x) => generic_success; 64 | int crashme(int x) => generic_success; 65 | 66 | 67 | For the sake of PFL working, minerva includes generic functions in order to check the result of particular call. 68 | Take a look at include/minerva_generic.h for the complete list of these. 69 | 70 | 71 | ###Variables can also have annotations 72 | 73 | void BN_CTX_free(BN_CTX *c {DESTROY}) => generic_void; 74 | DESTROY indicates that call destroys the variable, so fuzzer wont use it any further. 75 | 76 | 77 | int mutate_int_and(int a {MUTATE}, int b {MUTATE}) => generic_success; 78 | 79 | MUTATE indicates that particular variable is mutated by the function. Fuzzer uses it for 80 | mutation phase (see var_mut shell command). 81 | 82 | ## Building 83 | 84 | Create your own subdirectory in target/ directory, it should contain 85 | configuration file (as explained above) and Makefile. That's it, a minimal set of files 86 | needed to generate fuzzer. 87 | Example Makefile looks as follows(/target/toy/Makefile): 88 | 89 | TARGET=toy 90 | LOCAL_SRC= \ 91 | toy.c 92 | 93 | include ../../mk/minerva.mk 94 | 95 | TARGET - is a target name (could be any name). 96 | LOCAL_SRC - is a set of files that is additionally linked with the fuzzer (helper functions etc). 97 | 98 | Makefiles may also include LDFLAGS in order to link against other libraries (see target/openssl/Makefile): 99 | 100 | TARGET=openssl 101 | LOCAL_SRC= \ 102 | minerva_vars_init.c 103 | 104 | LDFLAGS=-lssl -lcrypto 105 | 106 | include ../../mk/minerva.mk 107 | 108 | Including of minerva.mk is mandatory (it does magic to generate fuzzer for 109 | You). Building system is mostly inspired by BSD ports. 110 | 111 | Makefile also supports a few parameters, as follows: 112 | 113 | 114 | 115 | - DEBUG=1 - build without optimizations, additional debug features are 116 | turned on. 117 | - ASAN=1 - build with address sanitizer 118 | - WITHOUT_READLINE=1 - build without readline library 119 | - WITHOUT_PROGRESSBAR=1 - build without progressbar library 120 | 121 | ## Fuzzing 122 | 123 | Fuzzing should be as easy as running compiled binary. 124 | 125 | target/toy/ $ ./bin/minerva-toy-toy 126 | seed: 2946546160 127 | \o/ found crash *yay* \o/ 128 | 129 | target/toy/ $ lldb ./bin/minerva-toy-toy 130 | (lldb) target create "./bin/minerva-toy-toy" 131 | Current executable set to './bin/minerva-toy-toy' (x86_64). 132 | (lldb) r 133 | Process 58757 launched: './bin/minerva-toy-toy' (x86_64) 134 | seed: 799555025 135 | Process 58757 stopped 136 | * thread #1: (...) toy.c:22, queue = 'com.apple.main-thread', 137 | stop reason = EXC_BAD_ACCESS (code=1, address=0x0) 138 | frame #0: 0x000000010000809d minerva-toy-toy`crashme(x=5) + 29 at toy.c:22 139 | 140 | 19 { 141 | 20 int *y = NULL; 142 | 21 if (x > 4) 143 | -> 22 return *y; 144 | 23 else 145 | 24 return x+2; 146 | 25 } 147 | 148 | ## Shell mode 149 | 150 | If you want to run the fuzzing in shell mode, execute the binary with -r option: 151 | 152 | target/toy/ $ ./bin/minerva-toy-toy -r 153 | seed: 100837884 154 | pfl> help 155 | fuzz([iter, [ctx]]) - fuzz: does iter iterations, uses ctx 156 | var_mut(iter, ctx) - does iter mutations of variables stored in ctx 157 | var_stat(ctx) - shows statistics about variables stored in ctx 158 | func_stat(ctx) - shows statistics about functions calls stored in ctx 159 | play(trace) - plays trace or context 160 | restore("filename") - restores trace from file 161 | save(trace, "filename") - saves trace to file 162 | min(trace) - minimizes trace 163 | show(trace) - shows trace 164 | quit, exit - quits 165 | 166 | In order to perform fuzzing, being in shell mode, use fuzz command: 167 | 168 | target/toy/ $ ./bin/minerva-toy-toy -r 169 | seed: 3366955315 170 | pfl> x = fuzz(100) 171 | Fuzzing |====================================================| ETA: 0h00m00s 172 | pfl> 173 | 174 | ## Test case management 175 | 176 | Fuzzing process saves traces, which can be replayed later on in order to reproduce 177 | particular execution. It uses simple format to save the function calls: 178 | 179 | target/toy/ $ ./bin/minerva-toy-toy -T /dev/stdout 180 | seed: 2631490055 181 | \o/ found crash *yay* \o/ 182 | 0 = zero() 183 | 1 = zero() 184 | 2 = crashme(1) 185 | 3 = add_one(2) 186 | 4 = crashme(3) 187 | 5 = crashme(0) 188 | 6 = crashme(2) 189 | 7 = zero() 190 | 8 = zero() 191 | 9 = zero() 192 | 10 = crashme(3) 193 | 11 = add_one(5) 194 | 12 = crashme(4) 195 | 196 | target/toy/ $ ./bin/minerva-toy-toy -T tmp 197 | seed: 3370842429 198 | \o/ found crash *yay* \o/ 199 | target/toy/ $ ./bin/minerva-toy-toy -p tmp 200 | seed: 1519824755 201 | Replay |=================================================== | ETA: 0h00m00s 202 | target/toy/ $ lldb ./bin/minerva-toy-toy 203 | r -p tmp 204 | (lldb) target create "./bin/minerva-toy-toy" 205 | Current executable set to './bin/minerva-toy-toy' (x86_64). 206 | (lldb) r -p tmp 207 | Process 12467 launched: './bin/minerva-toy-toy' (x86_64) 208 | seed: 904045424 209 | Process 12467 stopped======================================= | ETA: 0h00m00s 210 | * thread #1: tid = 0x2bca2, 0x000000010000823d minerva-toy-toy`crashme + 29, 211 | queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, 212 | address=0x0) 213 | 214 | ## F.A.Q 215 | 216 | ### Q: My API function requires some pre-conditions to be satisfied. 217 | A: Write a simple wrapper to make sure that those conditions are met. 218 | 219 | ### Q: My API function requires some var initialization / depends on internal state 220 | A: Write wrapper or introduce new types that indicate internal state. Here's an quick example: 221 | 222 | STH_new *STH_new(void) => generic_not_null; 223 | STH *STH_init(STH_new *) => generic_not_null; 224 | 225 | ### Q: Where I can get help? 226 | A: Use -h switch or help command in the shell mode. 227 | 228 | ### Q: Does function input variables depend on each other? 229 | A: You have to wrap function yourself, sorry. 230 | 231 | ### Q: How can I help you? 232 | A: Take a look at TODO list, fill bug reports, send PRs. Your help is more than welcome. 233 | 234 | ### Q: What are the dependencies? 235 | A: Python, GNU Make, C compiler, Bison, Flex, py-yacc, libprogressbar. 236 | 237 | ### Q: Is the name - Polish Fuzzy Lop a joke? 238 | A: No, it's a coincidence. 239 | 240 | ### Q: Have it found any bugs, ever? 241 | A: Yes, including various minor bugs in OpenSSL, LibreSSL and OpenSSH. 242 | 243 | ### Q: What platforms are supported? 244 | A: We successfully ran this software on Linux, FreeBSD, NetBSD, OpenBSD and Mac OS X. 245 | 246 | ### Q: When are you going to implement more features (like coverage)? 247 | A: We don't know. However, You're more than welcome to develop it on your own and share it with us. 248 | 249 | ## Reading material 250 | 251 | 1. http://akat1.pl/talks/2016-alligatorcon.pdf - slides about minerva_lib itself 252 | 2. https://web.archive.org/web/20170717042933/http://php-security.org/2010/05/11/mops-submission-05-the-minerva-php-fuzzer/ - text about minerva algorithm 253 | 3. http://www.slideshare.net/logicaltrust/torturing-the-php-interpreter - slides that contains something about minerva algorithm 254 | 4. https://www.youtube.com/watch?v=bXpZoHlmsUU - talk about minerva_lib from BSidesWarsaw 2018 (encrypted in Polish) 255 | 256 | ## Credits 257 | 258 | - @akat1_pl - http://akat1.pl/ 259 | - n1x0n 260 | - s1m0n 261 | - PSi 262 | - Zeruś 263 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | TODO: 2 | 3 | * test case min 4 | * smart fuzzing (coverage) 5 | * get rid of compiler in Python 6 | * write (better/any) documentation 7 | * split fuzzing and shell stuff (into separate processes) 8 | * fix redundancy between minerva_loop & minerva_trace 9 | * variadic functions? 10 | -------------------------------------------------------------------------------- /compiler/compiler.py: -------------------------------------------------------------------------------- 1 | # 2 | # this code is full of shit, you have been warned! 3 | # 4 | 5 | MINERVA_PREFIX = "minerva_"; 6 | ALWAYS_SKIP_TYPES = ["const","unsigned", "signed"] 7 | def __type_to_minerva(t): 8 | r = "__minerva_" 9 | 10 | while t[0] is not None: 11 | r += t[0] + "_" 12 | t = t[1] 13 | r += t[1] 14 | 15 | r = r.replace("*","ptr") 16 | 17 | for type in ALWAYS_SKIP_TYPES: 18 | r = r.replace(type + "_","") 19 | 20 | return r + "_t" 21 | 22 | def __type_to_str(t): 23 | r = "" 24 | 25 | while t[0] is not None: 26 | r += t[0] + " " 27 | t = t[1] 28 | r += t[1] 29 | 30 | for type in ALWAYS_SKIP_TYPES: 31 | r = r.replace(type + " ","") 32 | 33 | return r 34 | 35 | def __compile_type_enum(types): 36 | r = "typedef enum {\n" 37 | r += ",\n".join(set(map(lambda x: "\t"+__type_to_minerva(x), types))) 38 | r += "\n\t,__minerva_types_no" 39 | r += "\n} minerva_type_t;\n" 40 | 41 | return r 42 | 43 | def __compile_type_name(types): 44 | r = "const char *minerva_type_name[] = {\n" 45 | r += ",\n".join(set(map(lambda x: "\t\""+__type_to_str(x)+"\"", types))) 46 | r += "\n};\n" 47 | 48 | return r 49 | 50 | def __compile_wrapper(funcs): 51 | 52 | c = [] 53 | 54 | for f in funcs: 55 | r = "int\n" 56 | r += "__minerva_wrap_call_"+f[2]+"(minerva_var_t *new, minerva_var_t **vars) {\n" 57 | #skipping void args 58 | args = [ elem for elem in f[3] if elem[0][1] != "void" ] 59 | 60 | for i, a in enumerate(args): 61 | a = a[0] 62 | r += "\t"+__type_to_str(a)+" "+"__arg"+str(i)+" = " 63 | r += "(" + __type_to_str(a) +") " 64 | if '*' in __type_to_str(a): 65 | r += "vars["+str(i)+"]->val;\n" 66 | else: 67 | r += "*("+__type_to_str(a)+"*)vars["+str(i)+"]->val;\n" 68 | if f[1][1] == 'void': 69 | r += "\t"+f[2]+"("+",".join(["__arg"+str(i) for i in range(len(args))])+");" 70 | else: 71 | if '*' in f[1][1]: 72 | r += "\tnew->val = " + \ 73 | f[2]+"("+",".join(["__arg"+str(i) for i in range(len(args))])+");" 74 | else: 75 | r += "\tnew->val = xcalloc(1,sizeof("+__type_to_str(f[1])+"));\n" 76 | r += "\tnew->flags |= F_VAR_ALLOC;\n" 77 | r += "\t*(("+__type_to_str(f[1])+"*)new->val) = ("+__type_to_str(f[1])+")"+\ 78 | f[2]+"("+",".join(["__arg"+str(i) for i in range(len(args))])+");" 79 | 80 | r += "\n\treturn 1;\n}\n\n" 81 | c.append(r) 82 | 83 | return "".join(c) 84 | 85 | def __compile_wrapper_init(funcs): 86 | 87 | c = ["void\nminerva_funcs_init(minerva_funcs_t *funcs) {\n\tminerva_arg_t *x;\n"] 88 | 89 | for f in funcs: 90 | r = "" 91 | if len(f[3]) > 0: 92 | r += "\tx = xcalloc("+str(len(f[3]))+" ,sizeof(minerva_arg_t));\n" 93 | for n, t in enumerate(f[3]): 94 | flags = '|'.join(map(lambda x: "F_VAR_"+x, t[1])) or "0" 95 | r += "\tx["+str(n)+"] = (minerva_arg_t){"+__type_to_minerva(t[0])+","+flags+"};\n" 96 | r += "\tminerva_funcs_add(funcs, " 97 | r += __type_to_minerva(f[1]) + ", " 98 | r += "__minerva_wrap_call_"+f[2]+", " 99 | r += "\"" + f[2] + "\", " 100 | r += "0, " 101 | r += f[4] +", " 102 | r += str(len(f[3])) 103 | if len(f[3]) > 0: 104 | r += "," 105 | r += ",".join(map(lambda x: "&x["+str(x)+"]", range(len(f[3])))) 106 | r += ");\n" 107 | c.append(r) 108 | 109 | c += ["}\n\n"] 110 | 111 | return "".join(c) 112 | 113 | def __compile_stringify(funcs): 114 | r = "const minerva_var_stringify_t minerva_var_stringify_funcs[] = {\n" 115 | r += ",\n".join(set(map(lambda x: "\t{"+__type_to_minerva(x[1])+", "+x[2]+"}", funcs))) 116 | r += "\n};\n" 117 | 118 | return r 119 | 120 | def compile(x): 121 | 122 | header_file = """#include 123 | #include 124 | #include 125 | """ 126 | 127 | headers = reversed(list(filter(lambda x: x[0] == 'include', x))) 128 | functions = list(filter(lambda x: x[0] == 'function', x)) 129 | stringify_functions = list(filter(lambda x: x[0] == 'stringify', x)) 130 | 131 | for h in headers: 132 | header_file += ("#include %s\n" % h[1]) 133 | 134 | body_file = header_file 135 | 136 | header_file = """#ifndef _MINERVA_TARGET_H_ 137 | #define _MINERVA_TARGET_H_ 138 | 139 | extern const char *minerva_type_name[]; 140 | """ 141 | 142 | types = set() 143 | 144 | for f in functions: 145 | types.add(f[1]) 146 | for t in f[3]: 147 | types.add(t[0]) 148 | 149 | header_file += "#define MINERVA_FUNC_NUM %d\n" % (len(functions)) 150 | header_file += "#define MINERVA_STRINGIFY_FUNC_NUM %d\n" % \ 151 | (len(stringify_functions)) 152 | header_file += __compile_type_enum(types) 153 | body_file += __compile_wrapper(functions) 154 | body_file += __compile_wrapper_init(functions) 155 | body_file += __compile_type_name(types) 156 | body_file += __compile_stringify(stringify_functions) 157 | 158 | header_file += "\n#endif\n" 159 | 160 | return (header_file, body_file) 161 | -------------------------------------------------------------------------------- /compiler/mi2c.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | import compiler 4 | import getopt 5 | import parser 6 | import sys 7 | import traceback 8 | import errno 9 | 10 | EXIT_FAILURE = 1 11 | 12 | WARNINGS = set(["unreachable"]) 13 | 14 | def _print_usage(): 15 | print("%s -h -m[FILE] -o[OUTPUT] -I[PATH] -W[WARN]" % (sys.argv[0])) 16 | 17 | def _print_fatal(err): 18 | print("") 19 | print("fatal error: %s" % err) 20 | print("") 21 | traceback.print_exc() 22 | sys.exit(EXIT_FAILURE) 23 | 24 | def _parse_args(args, config): 25 | try: 26 | opts,_ = getopt.getopt(args, "hm:o:I:W:") 27 | except (getopt.GetoptError, err): 28 | print(err) 29 | _print_usage() 30 | sys.exit() 31 | 32 | # empty argv list 33 | if len(opts) == 0: 34 | _print_usage() 35 | sys.exit() 36 | 37 | for opt, arg in opts: 38 | if opt == '-h': 39 | _print_usage() 40 | sys.exit() 41 | elif opt == '-m': 42 | config['input_file'] = arg 43 | elif opt in '-o': 44 | config['output'] = arg 45 | elif opt in '-I': 46 | config['include_path'].append(arg) 47 | elif opt in '-W': 48 | if arg in WARNINGS: 49 | config['warnings'].add(arg) 50 | else: 51 | _print_fatal("Unknown warning flag: %s" % arg) 52 | else: 53 | assert False, "unhandled" 54 | 55 | def _write_file(filename, body): 56 | fh = open(filename, 'w') 57 | fh.write(body) 58 | fh.close 59 | 60 | def _check_unreachable(functions): 61 | reached_types = set() 62 | reached_functions = set() 63 | changed = True 64 | 65 | while changed: 66 | changed = False 67 | for function in filter(lambda x: x[0] == 'function', functions): 68 | if function[2] in reached_functions: 69 | continue 70 | if not set(map(lambda t: t[0], 71 | function[3])).issubset(reached_types): 72 | continue 73 | reached_types.add(function[1]) 74 | reached_functions.add(function[2]) 75 | changed = True 76 | 77 | diff = set(map(lambda x: x[2], filter(lambda x: x[0] == 'function', 78 | functions))).difference(reached_functions) 79 | 80 | if diff != set(): 81 | print('unreachable functions: %s' % ' '.join(diff)) 82 | sys.exit(EXIT_FAILURE) 83 | 84 | 85 | def main(): 86 | config = {} 87 | config['input_file'] = None 88 | config['output'] = None 89 | config['include_path'] = [''] # empty prefix is default 90 | config['warnings'] = set() 91 | 92 | _parse_args(sys.argv[1:], config) 93 | 94 | if config['input_file'] is None or config['output'] is None: 95 | _print_usage() 96 | sys.exit(EXIT_FAILURE) 97 | 98 | functions = [] 99 | input_files = [(config['input_file'], False)] 100 | 101 | while input_files != []: 102 | (input_file, local) = input_files.pop() 103 | 104 | input_content = None 105 | paths = config['include_path'] if not local else ['./'] 106 | for path in paths: 107 | try: 108 | input_fh = open(path + input_file, 'r') 109 | input_content = input_fh.read() 110 | input_fh.close() 111 | break 112 | except IOError as e: 113 | if e.errno != errno.ENOENT: 114 | _print_fatal(e) 115 | 116 | if input_content is None: 117 | _print_fatal("can't open include file: %s" % input_file) 118 | 119 | try: 120 | x = parser.parse(input_content) 121 | except Exception as err: 122 | _print_fatal(err) 123 | 124 | includes = reversed(list(filter(lambda x: x[0] == 'miinclude', x))) 125 | 126 | for include in includes: 127 | # check if file is local or not: 128 | # 129 | # "file" are local 130 | # are global 131 | # 132 | # (just like in C) 133 | local = include[1].startswith('"') 134 | include = include[1][1:-1] 135 | if include in input_files: 136 | _print_fatal('cycle include on file: %s' % include) 137 | else: 138 | input_files.append((include, local)) 139 | 140 | functions += x 141 | 142 | if 'unreachable' in config['warnings']: 143 | _check_unreachable(functions) 144 | 145 | try: 146 | (header, body) = compiler.compile(functions) 147 | except Exception as err: 148 | _print_fatal(err) 149 | 150 | _write_file(config['output']+".h", header) 151 | _write_file(config['output']+".c", body) 152 | 153 | if __name__ == "__main__": 154 | main() 155 | -------------------------------------------------------------------------------- /compiler/parser.py: -------------------------------------------------------------------------------- 1 | import ply.yacc as yacc 2 | import ply.lex as lex 3 | 4 | # XXX: this is lame ~C funcion prototype parser 5 | 6 | ### LEXER 7 | 8 | tokens = ( 9 | 'LCHEVRON', 'RCHEVRON', 10 | 'LBRACKET', 'RBRACKET', 11 | 'STRUCT', 'PTR', 'UNION', 'RESTRICT', 'STANDARDTYPE', 'TYPE_QUALIFIER', 12 | 'COMMA', 'SEPARATOR', 'COMMENT', 'STRING', 13 | 'MIINCLUDE', 'INCLUDE', 'INCLUDEFILE', 'INCLUDEFILELOCAL', 'ARROW', 14 | 'STRINGIFY' 15 | ) 16 | 17 | def t_newline(t): 18 | r'\n+' 19 | t.lexer.lineno += t.value.count("\n") 20 | 21 | def t_UNION(t): r'\bunion\b'; return t 22 | def t_STRUCT(t): r'\bstruct\b'; return t 23 | def t_TYPE_QUALIFIER(t): r'\bconst\b'; return t; #skipped volatile 24 | def t_RESTRICT(t): r'\brestrict\b'; return t; 25 | t_LCHEVRON = r'\{' 26 | t_RCHEVRON = r'\}' 27 | t_LBRACKET = r'\(' 28 | t_RBRACKET = r'\)' 29 | t_COMMA = r',' 30 | t_SEPARATOR = r';' 31 | t_PTR = r'\*' 32 | t_ARROW = r'\=\>' 33 | t_STRINGIFY = r'\-\>' 34 | t_COMMENT = r'--[^\n]*' 35 | t_STRING = r'[a-zA-Z][a-zA-Z0-9_\-\.\/]*' 36 | t_STANDARDTYPE = r'\b(void|char|short|int|long|float|double|signed|unsigned)\b' 37 | t_MIINCLUDE = r'%include' 38 | t_INCLUDE = r'\#include' 39 | t_INCLUDEFILE = r'<'+t_STRING+r'>' 40 | t_INCLUDEFILELOCAL = r'"'+t_STRING+r'"' 41 | t_ignore = "\t " # ignore spaces and tabs 42 | 43 | def t_error(t): 44 | print("Illegal character '%s' at %d line" % (t.value[0], t.lexer.lineno)) 45 | 46 | lex.lex() 47 | 48 | ### PARSER 49 | def p_decls(t): 50 | '''decls : decl decls 51 | | decl 52 | ''' 53 | 54 | if len(t) == 2: 55 | t[0] = [] 56 | else: 57 | t[0] = t[2] 58 | 59 | if t[1] is not None: 60 | t[0].append(t[1]) 61 | 62 | def p_decl(t): 63 | '''decl : miinclude 64 | | include 65 | | function 66 | | stringify 67 | | comment''' 68 | if t[1] != None: 69 | t[0] = t[1] 70 | 71 | def p_comment(t): 72 | '''comment : COMMENT''' 73 | 74 | def p_include(t): 75 | '''include : INCLUDE INCLUDEFILE 76 | | INCLUDE INCLUDEFILELOCAL''' 77 | t[0] = ('include', t[2]) 78 | 79 | def p_miinclude(t): 80 | '''miinclude : MIINCLUDE INCLUDEFILE 81 | | MIINCLUDE INCLUDEFILELOCAL''' 82 | 83 | t[0] = ('miinclude', t[2]) 84 | 85 | def p_function(t): 86 | '''function : type STRING LBRACKET args RBRACKET ARROW STRING SEPARATOR 87 | | type STRING LBRACKET RBRACKET ARROW STRING SEPARATOR''' 88 | if len(t) == 9: 89 | t[0] = ('function', t[1],t[2],t[4],t[7]) 90 | else: 91 | t[0] = ('function', t[1],t[2],[],t[6]) 92 | 93 | def p_stringify(t): 94 | '''stringify : type STRINGIFY STRING SEPARATOR''' 95 | t[0] = ('stringify', t[1], t[3]) 96 | 97 | def p_args(t): 98 | '''args : arg_wrapper COMMA args 99 | | arg_wrapper''' 100 | 101 | if len(t) == 2: 102 | t[0] = [] 103 | else: 104 | t[0] = t[3] 105 | 106 | t[0] = [t[1]] + t[0] 107 | 108 | def p_arg_wrapper(t): 109 | '''arg_wrapper : arg RESTRICT 110 | | arg''' 111 | if len(t) == 2: 112 | t[0] = t[1] 113 | else: 114 | t[1][1].append('UNIQUE') 115 | t[0] = t[1] 116 | def p_arg(t): 117 | '''arg : type STRING var_flags 118 | | type var_flags''' 119 | 120 | if len(t) == 3: 121 | t[0] = (t[1], t[2]) 122 | else: 123 | t[0] = (t[1], t[3]) 124 | 125 | 126 | def p_var_flags(t): 127 | '''var_flags : LCHEVRON var_arg_flags RCHEVRON 128 | | empty''' 129 | 130 | if len(t) == 2: 131 | t[0] = [] 132 | else: 133 | t[0] = t[2] 134 | 135 | 136 | def p_var_arg_flags(t): 137 | '''var_arg_flags : STRING COMMA var_arg_flags 138 | | STRING''' 139 | 140 | if len(t) == 2: 141 | t[0] = [] 142 | else: 143 | t[0] = t[3] 144 | 145 | t[0] = [t[1]] + t[0] 146 | 147 | 148 | def p_type(t): 149 | '''type : type_list 150 | | user_definied_type''' 151 | if len(t) == 2: 152 | t[0] = t[1] 153 | else: 154 | t[0] = (t[1],t[2]) 155 | 156 | def p_user_definied_type(t): 157 | '''user_definied_type : TYPE_QUALIFIER STRING ptr_list 158 | | UNION STRING ptr_list 159 | | STRUCT STRING ptr_list 160 | | struct_things 161 | | STRING ptr_list''' 162 | # I dont like it... 163 | if len(t) == 4: 164 | t[0] = (t[1],(t[2],t[3])) 165 | elif len(t) == 3: 166 | t[0] = (t[1],t[2]) 167 | else: 168 | t[0] = t[1] 169 | 170 | def p_struct_things(t): 171 | '''struct_things : TYPE_QUALIFIER STRUCT STRING 172 | | TYPE_QUALIFIER STRUCT STRING ptr_list 173 | | TYPE_QUALIFIER STRING 174 | | STRUCT STRING 175 | | UNION STRING 176 | | STRING''' 177 | if len(t) == 5: 178 | t[0] = (t[1],(t[2],(t[3],t[4]))) 179 | elif len(t) == 4: 180 | t[0] = (t[1],(t[2],(None,t[3]))) 181 | elif len(t) == 2 : 182 | t[0] = (None,t[1]) 183 | else: 184 | t[0] = (t[1],(None,t[2])) 185 | 186 | def p_ptr_list(t): 187 | '''ptr_list : PTR ptr_list 188 | | PTR''' 189 | if len(t) == 2: 190 | t[0] = (None,t[1]) 191 | else: 192 | t[0] = (t[1],t[2]) 193 | 194 | def p_type_list(t): 195 | '''type_list : basic_type 196 | | basic_type type_list''' 197 | 198 | if len(t) == 2: 199 | t[0] = (None, t[1]) 200 | else: 201 | t[0] = (t[1], t[2]) 202 | 203 | def p_basic_type(t): 204 | '''basic_type : TYPE_QUALIFIER 205 | | STANDARDTYPE 206 | | PTR''' 207 | #skipped storage_class_specifier (auto,register,static, extern, typedef) 208 | t[0] = t[1] 209 | 210 | def p_empty(p): 211 | 'empty :' 212 | pass 213 | 214 | def p_error(t): 215 | print("Syntax error '%s' at line %d" % (t.value, t.lexer.lineno)) 216 | 217 | yacc.yacc() 218 | 219 | def parse(content): 220 | return yacc.parse(content) 221 | 222 | if __name__ == '__main__': 223 | import sys 224 | if len(sys.argv) > 1: 225 | print(yacc.parse(open(sys.argv[1]).read())) 226 | else: 227 | while 1: 228 | try: 229 | line = raw_input('parser_test> ') 230 | print(yacc.parse(line)) 231 | except EOFError: 232 | break 233 | -------------------------------------------------------------------------------- /core/dict.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, 2011, 2012 Mateusz Kocielski 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "dict.h" 25 | #include "xmalloc.h" 26 | 27 | /* local headers */ 28 | 29 | /** dictionary */ 30 | LIST_HEAD(dict_t, dict_node_t); 31 | 32 | /** dictionary linked list */ 33 | typedef struct dict_node_t { 34 | LIST_ENTRY(dict_node_t) nodes; 35 | char *key; /**< key */ 36 | void *value; /**< value */ 37 | } dict_node_t; 38 | 39 | static bool valid_key(const char *); 40 | static void list_node_destroy(dict_node_t *); 41 | static dict_node_t *get_node_by_key(const dict_t *, 42 | const char *); 43 | 44 | /** 45 | * @brief checks if the key is legal 46 | * @param key node key 47 | * @return true if key is legal, false otherwise 48 | */ 49 | 50 | static bool 51 | valid_key(const char *key) 52 | { 53 | size_t i; 54 | 55 | /* key is empty string */ 56 | if (key == NULL) 57 | return false; 58 | 59 | for (i = 0; key[i] != '\0'; i++) { 60 | if (key[i] != '_' && isalnum((unsigned char)key[i]) == 0) 61 | return false; 62 | } 63 | 64 | return true; 65 | } 66 | 67 | /** 68 | * @brief destroys and deallocates list node 69 | * @param node list node 70 | */ 71 | 72 | static void 73 | list_node_destroy(dict_node_t *node) 74 | { 75 | free(node->key); 76 | minerva_dict_var_destroy(node->value); 77 | LIST_REMOVE(node, nodes); 78 | free(node); 79 | } 80 | 81 | /** 82 | * @brief gets node from the dictionary using key 83 | * @param dict dictionary 84 | * @param key node key 85 | * @return pointer to node if key is in the dictionary, NULL otherwise 86 | */ 87 | 88 | static dict_node_t * 89 | get_node_by_key(const dict_t *dict, const char *key) 90 | { 91 | dict_node_t *node; 92 | 93 | LIST_FOREACH(node, dict, nodes) { 94 | if (strcmp(node->key, key) == 0) 95 | return node; 96 | } 97 | 98 | return NULL; 99 | } 100 | 101 | /** 102 | * @brief destroys and deallocates the dictionary 103 | * @param dict dictionary 104 | */ 105 | 106 | void 107 | dict_destroy(dict_t *dict) 108 | { 109 | while(!LIST_EMPTY(dict)) 110 | list_node_destroy(LIST_FIRST(dict)); 111 | 112 | free(dict); 113 | } 114 | 115 | /** 116 | * @brief removes node from the dictionary using key 117 | * @param dict dictionary 118 | * @param key node key 119 | * @return DICT_OK on success, DICT_KEYNOTFOUND if node was not found (key 120 | * does not exist in the dictionary. 121 | */ 122 | 123 | dict_result_t 124 | dict_remove(dict_t *dict, const char *key) 125 | { 126 | dict_node_t *node; 127 | 128 | LIST_FOREACH(node, dict, nodes) { 129 | if (strcmp(node->key, key) == 0) { 130 | list_node_destroy(node); 131 | return DICT_OK; 132 | } 133 | } 134 | 135 | return DICT_KEYNOTFOUND; 136 | } 137 | 138 | /** 139 | * @brief gets node value from the dictionary using key 140 | * @param dict dictionary 141 | * @param key node key 142 | * @return pointer to the value if key was found in the dictionary, NULL 143 | * otherwise. 144 | */ 145 | 146 | void * 147 | dict_get(const dict_t *dict, const char *key) 148 | { 149 | dict_node_t *node = get_node_by_key(dict, key); 150 | 151 | return (node != NULL) ? node->value : NULL; 152 | } 153 | 154 | /** 155 | * @brief creates and allocates dictionary 156 | * @return pointer to new dictionary, NULL is returned on allocation failure 157 | */ 158 | 159 | dict_t * 160 | dict_create(void) 161 | { 162 | dict_t *head; 163 | 164 | head = xcalloc(1, sizeof(dict_t)); 165 | 166 | LIST_INIT(head); 167 | 168 | return head; 169 | } 170 | 171 | /** 172 | * @brief inserts node into the dictionary 173 | * @param dict dictionary 174 | * @param key node key 175 | * @param val node value 176 | * @return 177 | * DICT_OK - on success, 178 | * DICT_KEYINVALID - if node key is illegal, 179 | * DICT_VALBAD - if node value is illegal, 180 | * DICT_KEYEXISTS - if node with the same key already exists in the 181 | * dictionary, 182 | */ 183 | 184 | dict_result_t 185 | dict_insert(dict_t *dict, const char *key, void *val) 186 | { 187 | char *d_key = NULL; 188 | dict_node_t *node; 189 | 190 | if (valid_key(key) == false) 191 | return DICT_KEYINVALID; 192 | 193 | if (val == NULL) 194 | return DICT_VALBAD; 195 | 196 | /* XXXSHM: leak you, leak me */ 197 | /* check if key exists in dictionary */ 198 | node = get_node_by_key(dict, key); 199 | if (node != NULL) 200 | dict_remove(dict, key); 201 | d_key = xstrdup(key); 202 | node = xcalloc(1, sizeof(*node)); 203 | 204 | LIST_INSERT_HEAD(dict, node, nodes); 205 | node->key = d_key; 206 | node->value = val; 207 | 208 | return DICT_OK; 209 | } 210 | -------------------------------------------------------------------------------- /core/dict.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, 2011 Mateusz Kocielski 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #ifndef _DICT_H_ 18 | #define _DICT_H_ 19 | #include 20 | #include 21 | 22 | typedef enum { 23 | DICT_OK = 0, 24 | DICT_NOMEM, 25 | DICT_KEYNOTFOUND, 26 | DICT_KEYEXISTS, 27 | DICT_KEYINVALID, 28 | DICT_VALBAD 29 | } dict_result_t; 30 | 31 | /* dictionary type */ 32 | /* in minerva_dict.h */ 33 | 34 | /* interface */ 35 | dict_t *dict_create(void); 36 | dict_result_t dict_insert(dict_t *, const char *, 37 | void *); 38 | void *dict_get(const dict_t *, const char *); 39 | dict_result_t dict_remove(dict_t *, const char *); 40 | void dict_destroy(dict_t *); 41 | 42 | #endif /* ! _DICT_H_ */ 43 | -------------------------------------------------------------------------------- /core/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | static void 31 | sigsegv_handler(int sig) 32 | { 33 | printf("\nSIGSEGV exiting...\n"); 34 | abort(); 35 | /*NOTREACHED*/ 36 | assert(0); 37 | } 38 | 39 | static void 40 | sigint_handler(int sig) 41 | { 42 | printf("\n^C exiting...\n"); 43 | exit(0); 44 | /*NOTREACHED*/ 45 | assert(0); 46 | } 47 | 48 | static void /*NOTRETURN*/ 49 | usage(int status) 50 | { 51 | printf("Minerva library fuzzer\n" 52 | "\n" 53 | " -h\t\thelp\n" 54 | " -i num\t\tnumber of iterations\n" 55 | " -s seed\tseed for random generator\n" 56 | " -S\t\thandle SIGSEGV\n" 57 | " -r\t\tshell mode\n" 58 | " -T filename\tsave trace to file\n" 59 | " -p filename\tplay trace from file\n" 60 | " -M\t\tmutate mode\n" 61 | " -D filename\tsave stringify dump to file" 62 | "\n"); 63 | 64 | exit(status); 65 | } 66 | 67 | int 68 | main(int argc, char **argv) 69 | { 70 | int ch; 71 | char *trace_filename = NULL, *play_filename = NULL, 72 | *stringify_filename = NULL; 73 | char handle_sigsegv = 0, repl = 0, mutate = 0, handle_sigint = 1; 74 | unsigned int iter = 0; 75 | uint32_t seed; 76 | minerva_vars_t *vars = NULL; 77 | minerva_funcs_t *funcs = NULL; 78 | minerva_trace_t *trace = NULL; 79 | 80 | #ifdef __linux__ 81 | getentropy(&seed, sizeof(seed)); 82 | #else 83 | seed = arc4random(); 84 | #endif 85 | 86 | while ((ch = getopt(argc, argv, "hi:s:SrT:p:MCvD:")) != -1) { 87 | switch (ch) { 88 | case 'h': 89 | usage(EXIT_SUCCESS); 90 | /*NOTREACHED*/ 91 | break; 92 | case 's': 93 | seed = strtoul(optarg, NULL, 10); 94 | break; 95 | case 'i': 96 | iter = strtoul(optarg, NULL, 10); 97 | break; 98 | case 'M': 99 | mutate = 1; 100 | case 'C': 101 | handle_sigint = 0; 102 | break; 103 | case 'S': 104 | handle_sigsegv = 1; 105 | break; 106 | case 'r': 107 | repl = 1; 108 | break; 109 | case 'T': 110 | trace_filename = xstrdup(optarg); 111 | break; 112 | case 'p': 113 | play_filename = xstrdup(optarg); 114 | break; 115 | case 'v': 116 | verbose++; 117 | break; 118 | case 'D': 119 | stringify_filename = xstrdup(optarg); 120 | break; 121 | default: 122 | usage(EXIT_FAILURE); 123 | /*NOTREACHED*/ 124 | } 125 | } 126 | 127 | if (VERBOSE_LEVEL(VERBOSE_NOISY)) 128 | fprintf(stderr, "seed: %u\n", seed); 129 | 130 | __srand(seed); 131 | 132 | if (handle_sigint == 1) { 133 | /* signal handlers - ^C - SIGINT */ 134 | if (signal(SIGINT, sigint_handler) == SIG_ERR) { 135 | fprintf(stderr, "can't install signal handler\n"); 136 | exit(EXIT_FAILURE); 137 | } 138 | } 139 | 140 | if (handle_sigsegv == 1) { 141 | /* signal handlers - SIGSEGV */ 142 | 143 | if (signal(SIGSEGV, sigsegv_handler) == SIG_ERR) { 144 | fprintf(stderr, "can't install signal handler\n"); 145 | exit(EXIT_FAILURE); 146 | } 147 | } 148 | 149 | /* REPL */ 150 | if (repl != 0) { 151 | minerva_repl(); 152 | return EXIT_SUCCESS; 153 | } 154 | 155 | if (play_filename != NULL) { 156 | funcs = minerva_funcs_new(); 157 | vars = minerva_vars_new(); 158 | minerva_funcs_init(funcs); 159 | trace = minerva_trace_restore(play_filename, funcs); 160 | minerva_trace_play(trace, vars); 161 | goto out; 162 | } 163 | 164 | /* MAIN LOOP */ 165 | if (mutate != 0) { 166 | for(;;) { 167 | if (minerva_loop(iter, &vars, &funcs, &trace, 0) || 168 | minerva_loop(iter/128, &vars, &funcs, &trace, 1)) 169 | break; 170 | } 171 | } else { 172 | minerva_loop(iter, &vars, &funcs, &trace, 0); 173 | } 174 | 175 | out: 176 | if (trace_filename != NULL) 177 | minerva_trace_save(trace, trace_filename); 178 | if (stringify_filename != NULL) 179 | minerva_vars_stringify(vars, stringify_filename); 180 | minerva_funcs_destroy(funcs); 181 | minerva_vars_destroy(vars); 182 | minerva_trace_destroy(trace); 183 | 184 | return EXIT_SUCCESS; 185 | } 186 | -------------------------------------------------------------------------------- /core/minerva_call.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | void 22 | minerva_call(minerva_vars_t *vars, minerva_var_t *new_var, 23 | minerva_func_t *call_func, minerva_var_t **call_vars) 24 | { 25 | int i; 26 | 27 | minerva_assert(new_var != NULL); 28 | minerva_assert(call_func != NULL); 29 | minerva_assert((call_func->arg_num > 0 && call_vars != NULL) || 30 | call_func->arg_num == 0); 31 | 32 | if (VERBOSE_LEVEL(VERBOSE_NOISY)) { 33 | fprintf(stderr, "calling %s", call_func->name); 34 | fprintf(stderr, "("); 35 | for (i = 0; i < call_func->arg_num ; i++) { 36 | fprintf(stderr, "%d", call_vars[i]->id); 37 | if (i+1 != call_func->arg_num) 38 | fprintf(stderr, ", "); 39 | } 40 | fprintf(stderr, ") "); 41 | fflush(stderr); 42 | } 43 | 44 | /* call wrapper */ 45 | call_func->func(new_var, call_vars); 46 | 47 | /* 48 | * XXXSHM: 49 | * It's ambigious if vars with F_VAR_DESTROY flag should be removed in 50 | * general or only in case when call failed. For safety we're doing it 51 | * in all cases. 52 | */ 53 | 54 | for (i = 0; i < call_func->arg_num ; i++) { 55 | if ((call_func->args[i]->flags & F_VAR_DESTROY) != 0) { 56 | if (VERBOSE_LEVEL(VERBOSE_NOISY)) { 57 | fprintf(stderr, "!!! destroy: %d ", call_vars[i]->id); 58 | } 59 | minerva_var_destroy(vars, call_vars[i]); 60 | } 61 | } 62 | 63 | 64 | /* 65 | * check if called function returned success, if no check function is 66 | * provided, then functions cannot fail. In this case check function is 67 | * indicated by NULL 68 | */ 69 | 70 | if (call_func->check == NULL || (call_func->check)(new_var->val) == 1) { 71 | call_func->success++; 72 | if (VERBOSE_LEVEL(VERBOSE_NOISY)) { 73 | fprintf(stderr, "success"); 74 | } 75 | } else { 76 | call_func->failure++; 77 | if (VERBOSE_LEVEL(VERBOSE_NOISY)) { 78 | fprintf(stderr, "failed"); 79 | } 80 | minerva_var_destroy(vars, new_var); 81 | } 82 | 83 | 84 | if (VERBOSE_LEVEL(VERBOSE_NOISY)) { 85 | fprintf(stderr, "\n"); 86 | } 87 | 88 | 89 | 90 | return; 91 | } 92 | 93 | void 94 | minerva_random_call(minerva_vars_t *vars, minerva_funcs_t *funcs, 95 | minerva_trace_t *trace, int mutate) 96 | { 97 | minerva_func_t *call_func = minerva_func_get(funcs, vars, mutate); 98 | minerva_var_t **call_vars = NULL; 99 | minerva_var_t *new_var = NULL; 100 | int result; 101 | int i, j, unique; 102 | 103 | minerva_assert(call_func != NULL); 104 | 105 | if (call_func->arg_num > 0) 106 | call_vars = xcalloc(call_func->arg_num, sizeof(*call_vars)); 107 | 108 | /* generating parameters looks as follows: 109 | * 1) first get variables for UNIQUE args (and ensure that they're 110 | * unique) 111 | * 2) get variables for other args (and ensure that they don't collide 112 | * with UNIQUE ones) 113 | */ 114 | 115 | for (i = 0; i < call_func->arg_num; i++) { 116 | if ((call_func->args[i]->flags & F_VAR_UNIQUE) != 0) { 117 | while (1) { 118 | call_vars[i] = minerva_var_get(vars, call_func->args[i]->type); 119 | for (j = 0, unique = 1; j < i; j++) { 120 | if (call_vars[i] == call_vars[j]) { 121 | unique = 0; 122 | break; 123 | } 124 | } 125 | if (unique != 0) 126 | break; 127 | } 128 | } 129 | } 130 | 131 | for (i = 0; i < call_func->arg_num; i++) { 132 | if ((call_func->args[i]->flags & F_VAR_UNIQUE) == 0) { 133 | while (1) { 134 | call_vars[i] = minerva_var_get(vars, call_func->args[i]->type); 135 | for (j = 0, unique = 1; j < i; j++) { 136 | if (((call_func->args[j]->flags & F_VAR_UNIQUE) != 0) && 137 | call_vars[i] == call_vars[j]) { 138 | unique = 0; 139 | continue; 140 | } 141 | } 142 | if (unique != 0) 143 | break; 144 | } 145 | } 146 | } 147 | 148 | for (i = 0; i < call_func->arg_num; i++) 149 | minerva_assert(call_vars[i] != NULL); 150 | 151 | new_var = minerva_var_new(vars, call_func->return_type, 0); 152 | minerva_trace_record(trace, new_var, call_func, call_vars); 153 | minerva_call(vars, new_var, call_func, call_vars); 154 | 155 | xfree(call_vars); 156 | 157 | return; 158 | } 159 | -------------------------------------------------------------------------------- /core/minerva_concat.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | /* 13 | * XXX: char is not the best type because we need to track length of the data 14 | */ 15 | 16 | void 17 | minerva_concat(char **r, char *s) 18 | { 19 | /* skip in case of null */ 20 | if (s == NULL || *r == NULL) { 21 | *r = NULL; 22 | goto out; 23 | } 24 | 25 | /* XXX: memory leak */ 26 | asprintf(r, "%s%s", *r, s); 27 | 28 | out: 29 | /* XXX: free */ 30 | return; 31 | } 32 | -------------------------------------------------------------------------------- /core/minerva_dict.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #include 10 | 11 | #include "dict.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | dict_t * 18 | minerva_dict_create(void) 19 | { 20 | return dict_create(); 21 | } 22 | 23 | int 24 | minerva_dict_set(dict_t *dict, const char *key, minerva_dict_var_t *var) 25 | { 26 | return dict_insert(dict, key, var); 27 | } 28 | 29 | minerva_dict_var_t * 30 | minerva_dict_get(dict_t *dict, const char *key) 31 | { 32 | return dict_get(dict, key); 33 | } 34 | 35 | void 36 | minerva_dict_destroy(dict_t *dict) 37 | { 38 | return dict_destroy(dict); 39 | } 40 | 41 | void 42 | minerva_dict_var_destroy(minerva_dict_var_t *var) 43 | { 44 | minerva_dict_var_result_t *result; 45 | 46 | if (var == NULL) 47 | return; 48 | 49 | switch (var->type) { 50 | case MINERVA_RESULT_T: 51 | result = var->val.var; 52 | MINERVA_REFS_DEC(result); 53 | if (MINERVA_REFS(result) != 0) 54 | break; 55 | minerva_vars_destroy(result->vars); 56 | minerva_funcs_destroy(result->funcs); 57 | minerva_trace_destroy(result->trace); 58 | free(result); 59 | break; 60 | case MINERVA_STRING_T: 61 | free(var->val.str); 62 | break; 63 | default: 64 | /* do nothing */ 65 | break; 66 | } 67 | 68 | free(var); 69 | } 70 | -------------------------------------------------------------------------------- /core/minerva_func.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | void 21 | minerva_funcs_print_stats(minerva_funcs_t *funcs) 22 | { 23 | uint32_t total; 24 | minerva_func_t *func; 25 | float success_rate, failure_rate; 26 | 27 | fprintf(stderr, "\n#### FUNC STATS #####\n"); 28 | LIST_FOREACH(func, funcs, entries) { 29 | total = func->success + func->failure; 30 | if ( total != 0 ) { 31 | success_rate = (func->success / (float)total) * 100; 32 | failure_rate = (func->failure / (float)total) * 100; 33 | fprintf(stderr, "%25s %3.1f %5d %3.1f %5d %10d\n", func->name, 34 | success_rate, func->success, failure_rate, func->failure, 35 | total ); 36 | } else { 37 | fprintf(stderr, "%25s %3.1f %3.1f %10d\n", func->name, 0.0f, 0.0f, 38 | 0); 39 | } 40 | } 41 | } 42 | 43 | minerva_funcs_t * 44 | minerva_funcs_new(void) 45 | { 46 | minerva_funcs_t *head; 47 | head = xcalloc(1, sizeof(*head)); 48 | LIST_INIT(head); 49 | return head; 50 | } 51 | 52 | void 53 | minerva_funcs_add(minerva_funcs_t *funcs, 54 | const minerva_type_t return_type, void *func, const char *name, 55 | const minerva_func_flags_t flags, minerva_check_t *check, 56 | const int arg_num, ...) 57 | { 58 | minerva_func_t *new_func = xcalloc(1, sizeof(*new_func)); 59 | va_list ap; 60 | int i; 61 | 62 | if (arg_num > 0) 63 | new_func->args = xcalloc(arg_num, sizeof(*(new_func->args))); 64 | 65 | new_func->return_type = return_type; 66 | new_func->func = func; 67 | new_func->flags = flags; 68 | new_func->check = check; 69 | new_func->arg_num = arg_num; 70 | new_func->name = name; 71 | 72 | va_start(ap, arg_num); 73 | for (i = 0; i < arg_num; i++) { 74 | new_func->args[i] = va_arg(ap, minerva_arg_t *); 75 | if ((new_func->args[i]->flags & F_VAR_MUTATE) != 0) 76 | new_func->flags |= F_FUN_MUTATE; 77 | } 78 | va_end(ap); 79 | 80 | LIST_INSERT_HEAD(funcs, new_func, entries); 81 | 82 | return; 83 | } 84 | 85 | /* checks if we've got enough variables collected in order to execute the 86 | * funtion 87 | */ 88 | static int 89 | minerva_func_qualify(minerva_func_t *func, minerva_vars_t *vars, int mutate) 90 | { 91 | unsigned int var[__minerva_types_no]; 92 | int i, arg_type; 93 | 94 | if ((mutate != 0) != ((func->flags & F_FUN_MUTATE) != 0)) 95 | return 0; 96 | 97 | for (i = 0; i < __minerva_types_no; i++) 98 | var[i] = vars->len[i]; 99 | 100 | for (i = 0; i < func->arg_num; i++) { 101 | arg_type = func->args[i]->type; 102 | 103 | if (var[arg_type] == 0) 104 | return 0; 105 | 106 | /* We can't reuse variable with F_VAR_UNIQUE flag */ 107 | if ((func->args[i]->flags & F_VAR_UNIQUE) != 0) 108 | var[arg_type]--; 109 | } 110 | 111 | return 1; 112 | } 113 | 114 | minerva_func_t * 115 | minerva_func_get(minerva_funcs_t *funcs, minerva_vars_t *vars, int mutate) 116 | { 117 | static minerva_func_t * func_arr[MINERVA_FUNC_NUM]; 118 | int n; 119 | minerva_func_t *func, *ret = NULL; 120 | 121 | n = 0; 122 | LIST_FOREACH(func, funcs, entries) { 123 | if (minerva_func_qualify(func, vars, mutate) != 0) { 124 | func_arr[n++] = func; 125 | } 126 | } 127 | ret = func_arr[__rand() % n]; 128 | minerva_assert(ret != NULL); 129 | 130 | return ret; 131 | } 132 | 133 | minerva_func_t * 134 | minerva_func_find(minerva_funcs_t *funcs, const char *name) 135 | { 136 | minerva_func_t *ret = NULL; 137 | 138 | LIST_FOREACH(ret, funcs, entries) { 139 | if (strcmp(ret->name, name) == 0) { 140 | break; 141 | } 142 | } 143 | 144 | minerva_assert(ret != NULL); 145 | 146 | return ret; 147 | } 148 | 149 | static void 150 | minerva_func_destroy(minerva_func_t *func) 151 | { 152 | /* args are allocated at once by the compiler */ 153 | if (func->arg_num > 0) 154 | free(func->args[0]); 155 | free(func->args); 156 | LIST_REMOVE(func, entries); 157 | free(func); 158 | } 159 | 160 | void 161 | minerva_funcs_destroy(minerva_funcs_t *funcs) 162 | { 163 | while(!LIST_EMPTY(funcs)) 164 | minerva_func_destroy(LIST_FIRST(funcs)); 165 | 166 | free(funcs); 167 | } 168 | -------------------------------------------------------------------------------- /core/minerva_generic.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | /* generic check functions */ 16 | 17 | int 18 | generic_not_null(const void *ptr) 19 | { 20 | void *p = (void *)ptr; 21 | return (p != NULL) ? 1 : 0; 22 | } 23 | 24 | int 25 | generic_not_zero(const void *ptr) 26 | { 27 | int *p = (int *)ptr; 28 | 29 | return (p != 0) ? 1 : 0; 30 | } 31 | 32 | int 33 | generic_zero(const void *ptr) 34 | { 35 | int *p = (int *)ptr; 36 | 37 | return p == 0; 38 | } 39 | 40 | int 41 | generic_void(const void *ptr) 42 | { 43 | return 0; 44 | } 45 | 46 | int 47 | generic_success(const void *ptr) 48 | { 49 | return 1; 50 | } 51 | 52 | /* MUTATORS */ 53 | 54 | int 55 | mutate_int_xor(int a, int b) 56 | { 57 | return a^b; 58 | } 59 | 60 | int 61 | mutate_int_or(int a, int b) 62 | { 63 | return a|b; 64 | } 65 | 66 | int 67 | mutate_int_and(int a, int b) 68 | { 69 | return a&b; 70 | } 71 | 72 | /* God, have mercy on me */ 73 | 74 | #define MUTATE_TYPE_BITFLIP(type) \ 75 | type \ 76 | mutate_##type##_bitflip(type x) \ 77 | { \ 78 | type shift = rand() % (sizeof(type)*8); \ 79 | return x ^ (1< 11 | #include 12 | #include "minerva_parser.tab.h" 13 | %} 14 | 15 | %option noyywrap 16 | %option noinput 17 | %option nounput 18 | 19 | blanks [ \t\n\r]+ 20 | letter [A-Za-z_] 21 | digit [0-9] 22 | identifier {letter}({letter}|{digit})* 23 | number {digit}+ 24 | string "\""({letter}|{digit}|[ .-\/])*"\"" 25 | eq "=" 26 | lparen "(" 27 | rparen ")" 28 | comma "," 29 | 30 | %% 31 | 32 | {eq} { 33 | return (EQ); 34 | } 35 | 36 | {lparen} { 37 | return (LPAREN); 38 | } 39 | 40 | {rparen} { 41 | return (RPAREN); 42 | } 43 | 44 | {comma} { 45 | return (COMMA); 46 | } 47 | 48 | {blanks} {/*ign*/} 49 | 50 | {identifier} { 51 | yylval.sval = strdup(yytext); 52 | return (IDENTIFIER); 53 | } 54 | 55 | {string} { 56 | yylval.sval = strdup(yytext); 57 | return (STRING); 58 | } 59 | 60 | {number} { 61 | yylval.ival = atoi(yytext); 62 | return (NUMBER); 63 | } 64 | -------------------------------------------------------------------------------- /core/minerva_loop.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #ifdef WITH_PROGRESSBAR 22 | #include 23 | #endif /* !WITH_PROGRESSBAR */ 24 | 25 | static jmp_buf sig_env; 26 | 27 | int 28 | minerva_loop(unsigned int iter, minerva_vars_t **vars, 29 | minerva_funcs_t **funcs, minerva_trace_t **trace, int mutate) 30 | { 31 | int crash = 0, forever = 0; 32 | unsigned int i; 33 | #ifdef WITH_PROGRESSBAR 34 | progressbar *progress; 35 | #endif /* !WITH_PROGRESSBAR */ 36 | 37 | if (iter == 0) 38 | forever = 1; 39 | 40 | #ifdef WITH_PROGRESSBAR 41 | if (forever == 0 && !VERBOSE_LEVEL(VERBOSE_NOISY)) 42 | progress = progressbar_new(mutate == 0 ? "Fuzzing" : "Mutating", 43 | iter); 44 | #endif /* !WITH_PROGRESSBAR */ 45 | 46 | if (*vars == NULL) 47 | *vars = minerva_vars_new(); 48 | 49 | if (*funcs == NULL) { 50 | *funcs = minerva_funcs_new(); 51 | minerva_funcs_init(*funcs); 52 | } 53 | 54 | if (*trace == NULL) 55 | *trace = minerva_trace_new(); 56 | 57 | if (setjmp(sig_env)) { 58 | if (segv != 0) 59 | crash = 1; 60 | } else { 61 | minerva_signal_setup(&sig_env); 62 | exit_loop = 0; 63 | for (i = 0 ; forever || i < iter; i++) { 64 | if (exit_loop) 65 | break; 66 | minerva_random_call(*vars, *funcs, *trace, mutate); 67 | #ifdef WITH_PROGRESSBAR 68 | if (forever == 0 && !VERBOSE_LEVEL(VERBOSE_NOISY)) { 69 | if (iter/100 == 0) 70 | progressbar_inc(progress); 71 | else if (i % (iter/100) == 0) { 72 | progressbar_update(progress, i); 73 | } 74 | } 75 | #endif /* !WITH_PROGRESSBAR */ 76 | } 77 | } 78 | 79 | #ifdef WITH_PROGRESSBAR 80 | if (forever == 0 && !VERBOSE_LEVEL(VERBOSE_NOISY)) { 81 | progressbar_update(progress, iter); 82 | progressbar_finish(progress); 83 | } 84 | #endif /* !WITH_PROGRESSBAR */ 85 | 86 | if (crash) { 87 | fprintf(stderr, ANSI_COLOR_GREEN "\\o/ found crash *yay* \\o/" 88 | ANSI_COLOR_RESET "\n"); 89 | } 90 | 91 | minerva_signal_revert(); 92 | 93 | return crash; 94 | } 95 | -------------------------------------------------------------------------------- /core/minerva_parser.y: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | %{ 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "minerva_lexer.h" 19 | 20 | int yylex(void); 21 | void yyerror(const char *); 22 | 23 | static minerva_line_t *call; 24 | static int p_error = 0; 25 | %} 26 | 27 | 28 | %start ASSIGN 29 | 30 | %define parse.error verbose 31 | 32 | %union { 33 | int ival; 34 | char *sval; 35 | minerva_repl_arg_t *mvar; 36 | minerva_call_t *cvar; 37 | minerva_line_t *lvar; 38 | } 39 | 40 | %token EQ LPAREN RPAREN COMMA 41 | %token NUMBER 42 | %token STRING 43 | %token IDENTIFIER 44 | %type ARG 45 | %type ARGS 46 | %type CALL 47 | %type ASSIGN 48 | %type VAR 49 | 50 | %% 51 | ASSIGN : VAR EQ CALL { 52 | $$ = xcalloc(1, sizeof(minerva_line_t)); 53 | $$->var = $1; 54 | $$->call = $3; 55 | call = $$; 56 | } 57 | 58 | | CALL { 59 | $$ = xcalloc(1, sizeof(minerva_line_t)); 60 | $$->call = $1; 61 | call = $$; 62 | } 63 | ; 64 | 65 | VAR : IDENTIFIER { 66 | $$ = xcalloc(1, sizeof(minerva_repl_arg_t)); 67 | $$->type = VAR_VAL; 68 | $$->val.var = $1; 69 | } 70 | 71 | ; 72 | 73 | CALL : IDENTIFIER LPAREN RPAREN { 74 | $$ = xcalloc(1, sizeof(minerva_call_t)); 75 | $$->fname = $1; 76 | } 77 | | IDENTIFIER LPAREN ARGS RPAREN { 78 | $$ = $3; 79 | $$->fname = $1; 80 | } 81 | | IDENTIFIER { 82 | $$ = xcalloc(1, sizeof(minerva_call_t)); 83 | $$->fname = $1; 84 | } 85 | ; 86 | 87 | ARGS : ARGS COMMA ARG { 88 | $$ = $1; 89 | $$->num_arg++; 90 | $$->args = realloc($$->args, sizeof(minerva_repl_arg_t *) * $1->num_arg); 91 | $$->args[$1->num_arg - 1] = $3; 92 | } 93 | | ARG { 94 | $$ = xcalloc(1, sizeof(minerva_call_t)); 95 | $$->num_arg = 1; 96 | $$->args = xcalloc(1, sizeof(minerva_repl_arg_t *)); 97 | $$->args[0] = $1; 98 | } 99 | ; 100 | 101 | ARG : IDENTIFIER { 102 | $$ = xcalloc(1, sizeof(minerva_repl_arg_t)); 103 | $$->type = VAR_VAL; 104 | $$->val.var = $1; 105 | } 106 | | STRING { 107 | $$ = xcalloc(1, sizeof(minerva_repl_arg_t)); 108 | $$->type = STRING_VAL; 109 | /* trim quotes */ 110 | $$->val.str = xstrdup(&($1[1])); 111 | $$->val.str[strlen($$->val.str)-1] = '\0'; 112 | } 113 | | NUMBER { 114 | $$ = xcalloc(1, sizeof(minerva_repl_arg_t)); 115 | $$->type = NUMBER_VAL; 116 | $$->val.num = $1; 117 | } 118 | ; 119 | %% 120 | 121 | void yyerror(const char *err) { 122 | p_error = 1; 123 | minerva_repl_error(err); 124 | } 125 | 126 | minerva_line_t * 127 | minerva_repl_parse(const char *str) 128 | { 129 | YY_BUFFER_STATE buffer; 130 | p_error = 0; 131 | buffer = yy_scan_string(str); 132 | yyparse(); 133 | if (p_error != 0) 134 | return NULL; 135 | yy_delete_buffer(buffer); 136 | 137 | return call; 138 | } 139 | 140 | -------------------------------------------------------------------------------- /core/minerva_signal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | sig_atomic_t exit_loop = 0; 17 | sig_atomic_t segv = 0; 18 | static jmp_buf *sig_env; 19 | static struct sigaction old_sigsegv; 20 | static struct sigaction old_sigabrt; 21 | static struct sigaction old_sigint; 22 | 23 | static void 24 | sigint_minerva_loop(int sig) 25 | { 26 | if (exit_loop != 0) { 27 | fprintf(stderr, "panic: ^C twice?..."); 28 | exit(EXIT_FAILURE); 29 | } 30 | exit_loop = 1; 31 | longjmp(*sig_env, 1); 32 | } 33 | 34 | static void 35 | sigsegv_minerva_loop(int sig) 36 | { 37 | if (segv == 1) { 38 | fprintf(stderr, "panic: segv in segv..."); 39 | exit(EXIT_FAILURE); 40 | } 41 | segv = 1; 42 | longjmp(*sig_env, 1); 43 | } 44 | 45 | /* setup handlers for SIGSEGV and SIGINT during fuzzing... */ 46 | void 47 | minerva_signal_setup(jmp_buf *env) 48 | { 49 | struct sigaction sa = {}; 50 | 51 | segv = 0; 52 | exit_loop = 0; 53 | sig_env = env; 54 | 55 | sa.sa_handler = sigsegv_minerva_loop; 56 | sa.sa_flags = SA_NODEFER; 57 | /* signal handler - sigsegv */ 58 | if (sigaction(SIGSEGV, &sa, &old_sigsegv) != 0) { 59 | fprintf(stderr, "can't install signal handler\n"); 60 | exit(EXIT_FAILURE); 61 | } 62 | 63 | sa.sa_handler = sigsegv_minerva_loop; 64 | sa.sa_flags = SA_NODEFER | SA_RESETHAND; 65 | /* signal handler - sigabrt (for ASAN) */ 66 | if (sigaction(SIGABRT, &sa, &old_sigabrt) != 0) { 67 | fprintf(stderr, "can't install signal handler\n"); 68 | exit(EXIT_FAILURE); 69 | } 70 | 71 | sa.sa_handler = sigint_minerva_loop; 72 | sa.sa_flags = 0; 73 | /* signal handler - ^c - sigint */ 74 | if (sigaction(SIGINT, &sa, &old_sigint) != 0) { 75 | fprintf(stderr, "can't install signal handler\n"); 76 | exit(EXIT_FAILURE); 77 | } 78 | } 79 | 80 | /* XXX: cheesy name */ 81 | void 82 | minerva_signal_revert(void) 83 | { 84 | /* signal handler - sigsegv */ 85 | if (sigaction(SIGSEGV, &old_sigsegv, NULL) != 0) { 86 | fprintf(stderr, "can't install signal handler\n"); 87 | exit(EXIT_FAILURE); 88 | } 89 | 90 | /* signal handler - sigabrt */ 91 | if (sigaction(SIGABRT, &old_sigabrt, NULL) != 0) { 92 | fprintf(stderr, "can't install signal handler\n"); 93 | exit(EXIT_FAILURE); 94 | } 95 | 96 | /* signal handler - ^c - sigint */ 97 | if (sigaction(SIGINT, &old_sigint, NULL) != 0) { 98 | fprintf(stderr, "can't install signal handler\n"); 99 | exit(EXIT_FAILURE); 100 | } 101 | 102 | segv = 0; 103 | exit_loop = 0; 104 | } 105 | -------------------------------------------------------------------------------- /core/minerva_var.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | static int 20 | minerva_var_rb_cmp(minerva_var_t *a, minerva_var_t *b) 21 | { 22 | if (a->id == b->id) 23 | return 0; 24 | else if (a->id > b->id) 25 | return 1; 26 | else 27 | return -1; 28 | } 29 | 30 | RB_GENERATE(minerva_var_tree, minerva_var_t, entries, 31 | minerva_var_rb_cmp); 32 | 33 | void 34 | minerva_vars_print_stats(minerva_vars_t *vars) 35 | { 36 | minerva_var_t *var = NULL; 37 | int i; 38 | int n; 39 | 40 | fprintf(stderr, "\n#### VAR STATS #####\n"); 41 | for (i = 0; i < __minerva_types_no; i++) { 42 | n = 0; 43 | RB_FOREACH(var, minerva_var_tree, &(vars->vars[i])) { 44 | n++; 45 | } 46 | var = NULL; 47 | fprintf(stderr, "var type: %16s\telements in list: %4d\n", minerva_type_name[i], n); 48 | } 49 | 50 | fprintf(stderr, "\n"); 51 | } 52 | 53 | minerva_vars_t * 54 | minerva_vars_new(void) 55 | { 56 | int i; 57 | minerva_vars_t *vars = xcalloc(1, sizeof(*vars)); 58 | vars->vars = xcalloc(__minerva_types_no, sizeof(*(vars->vars))); 59 | vars->len = xcalloc(__minerva_types_no, sizeof(*(vars->len))); 60 | 61 | for (i = 0; i < __minerva_types_no; i++) { 62 | RB_INIT(&(vars->vars[i])); 63 | } 64 | 65 | return vars; 66 | } 67 | 68 | minerva_var_t * 69 | minerva_var_new(minerva_vars_t *vars, minerva_type_t type, unsigned int id) 70 | { 71 | minerva_var_t *new_var = xcalloc(1, sizeof(*new_var)); 72 | 73 | new_var->type = type; 74 | 75 | vars->len[type]++; 76 | 77 | /* used in replays: for now we don't check if another id is already 78 | * registered */ 79 | if (id == 0) 80 | new_var->id = vars->cur_id++; 81 | else 82 | new_var->id = id; 83 | 84 | RB_INSERT(minerva_var_tree, &(vars->vars[type]), new_var); 85 | 86 | return new_var; 87 | } 88 | 89 | void 90 | minerva_var_destroy(minerva_vars_t *vars, minerva_var_t *var) 91 | { 92 | if (var == NULL) 93 | return; 94 | 95 | if ((var->flags & F_VAR_ALLOC) != 0) 96 | xfree(var->val); 97 | 98 | vars->len[var->type]--; 99 | 100 | RB_REMOVE(minerva_var_tree, &(vars->vars[var->type]), var); 101 | xfree(var); 102 | } 103 | 104 | void 105 | minerva_vars_stringify(minerva_vars_t *vars, const char *stringify_filename) 106 | { 107 | FILE *f; 108 | char *s; 109 | int i; 110 | minerva_var_t *var; 111 | 112 | f = fopen(stringify_filename, "w"); 113 | 114 | if (f == NULL) { 115 | fprintf(stderr, 116 | "Couldn't open stringify output file %s, nothing saved.\n", 117 | stringify_filename); 118 | return; 119 | } 120 | 121 | for (i = 0; i < __minerva_types_no; i++) { 122 | RB_FOREACH(var, minerva_var_tree, &(vars->vars[i])) { 123 | minerva_assert(var->type == i); 124 | s = minerva_var_stringify(var->type, var->val); 125 | if (s != NULL) 126 | fprintf(f, "%u: %s\n", var->id, s); 127 | xfree(s); 128 | } 129 | } 130 | 131 | fclose(f); 132 | 133 | return; 134 | } 135 | 136 | void 137 | minerva_vars_destroy(minerva_vars_t *vars) 138 | { 139 | int i; 140 | 141 | if (vars == NULL) 142 | return; 143 | 144 | for (i = 0; i < __minerva_types_no; i++) { 145 | while(!RB_EMPTY(&(vars->vars[i]))) { 146 | minerva_var_destroy(vars, RB_ROOT(&(vars->vars[i]))); 147 | } 148 | } 149 | 150 | for (i = 0; i < __minerva_types_no; i++) { 151 | minerva_assert(vars->len[i] == 0); 152 | } 153 | 154 | free(vars->len); 155 | free(vars->vars); 156 | free(vars); 157 | } 158 | 159 | 160 | minerva_var_t * 161 | minerva_var_get(minerva_vars_t *vars, minerva_type_t type) 162 | { 163 | minerva_var_t *var, *ret = NULL; 164 | minerva_var_t elm; 165 | 166 | /* XXXSHM: make it uniform rand again... for now it's good enough */ 167 | var = RB_MAX(minerva_var_tree, &(vars->vars[type])); 168 | elm.id = __rand() % (var->id+1); 169 | ret = RB_NFIND(minerva_var_tree, &(vars->vars[type]), &elm); 170 | assert(ret != NULL); 171 | 172 | return ret; 173 | } 174 | 175 | minerva_var_t * 176 | minerva_var_find(minerva_vars_t *vars, minerva_type_t type, unsigned id) 177 | { 178 | minerva_var_t elm; 179 | elm.id = id; 180 | 181 | return RB_FIND(minerva_var_tree, &(vars->vars[type]), &elm); 182 | } 183 | 184 | /* STRINGIFY 185 | * 186 | * The idea behind the stringify is to be able to dump variable as a string 187 | * and use the result to check if it's equal with other dumped strings. We 188 | * need that for differential fuzzing, consider following example with simple 189 | * trace: 190 | * 191 | * 1 = get_zero() 192 | * 2 = get_one() 193 | * 3 = add(1,2) 194 | * 195 | * We execute this trace on two different versions of bignum library, then we 196 | * stringify variable 3 and compare. If we get the same result, then we're 197 | * good, if not we have to investigate because it's possible bug. 198 | * 199 | * char *minerva_var_stringify(minerva_type_t type, void *obj) returns string 200 | * representation of obj typed as type. 201 | * 202 | * Possible problems: 203 | * - cyclic recursion 204 | * - randomness 205 | * - pointers 206 | */ 207 | 208 | char *minerva_var_stringify(minerva_type_t type, void *obj) { 209 | size_t i; 210 | 211 | for (i = 0; i < MINERVA_STRINGIFY_FUNC_NUM; i++) { 212 | if (minerva_var_stringify_funcs[i].type == type) 213 | return minerva_var_stringify_funcs[i].func(obj); 214 | } 215 | 216 | /* if we can't stringify then return null */ 217 | return NULL; 218 | } 219 | -------------------------------------------------------------------------------- /core/rand.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * SPDX-License-Identifier: BSD-3-Clause 3 | * 4 | * Copyright (c) 1990, 1993 5 | * The Regents of the University of California. All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. Neither the name of the University nor the names of its contributors 16 | * may be used to endorse or promote products derived from this software 17 | * without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 | * SUCH DAMAGE. 30 | * 31 | * Posix rand_r function added May 1999 by Wes Peters . 32 | */ 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include "random.h" 41 | 42 | /* 43 | * Implement rand(3), the standard C PRNG API, using the non-standard but 44 | * higher quality random(3) implementation and the same size 128-byte state 45 | * LFSR as the random(3) default. 46 | * 47 | * It turns out there are portable applications that want a PRNG but are too 48 | * lazy to use better-but-nonstandard interfaces like random(3), when 49 | * available, and too lazy to import higher-quality and faster PRNGs into their 50 | * codebase (such as any of SFC, JSF, 128-bit LCGs, PCG, or Splitmix64). 51 | * 52 | * Since we're stuck with rand(3) due to the C standard, we can at least have 53 | * it produce a relatively good PRNG sequence using our existing random(3) 54 | * LFSR. The random(3) design is not particularly fast nor compact, but it has 55 | * the advantage of being the one already in the tree. 56 | */ 57 | static struct __random_state *rand3_state; 58 | 59 | static void 60 | initialize_rand3(void) 61 | { 62 | int error; 63 | 64 | rand3_state = allocatestate(TYPE_3); 65 | error = __initstate_r(rand3_state, 1, rand3_state->rst_randtbl, BREAK_3); 66 | assert(error == 0); 67 | } 68 | 69 | int 70 | __rand(void) 71 | { 72 | if (rand3_state == NULL) 73 | initialize_rand3(); 74 | return ((int)__random_r(rand3_state)); 75 | } 76 | 77 | void 78 | __srand(unsigned seed) 79 | { 80 | if (rand3_state == NULL) 81 | initialize_rand3(); 82 | __srandom_r(rand3_state, seed); 83 | } 84 | 85 | /* 86 | * FreeBSD 12 and prior compatibility implementation of rand(3). 87 | */ 88 | static int 89 | do_rand(unsigned long *ctx) 90 | { 91 | /* 92 | * Compute x = (7^5 * x) mod (2^31 - 1) 93 | * without overflowing 31 bits: 94 | * (2^31 - 1) = 127773 * (7^5) + 2836 95 | * From "Random number generators: good ones are hard to find", 96 | * Park and Miller, Communications of the ACM, vol. 31, no. 10, 97 | * October 1988, p. 1195. 98 | */ 99 | long hi, lo, x; 100 | 101 | /* Transform to [1, 0x7ffffffe] range. */ 102 | x = (*ctx % 0x7ffffffe) + 1; 103 | hi = x / 127773; 104 | lo = x % 127773; 105 | x = 16807 * lo - 2836 * hi; 106 | if (x < 0) 107 | x += 0x7fffffff; 108 | /* Transform to [0, 0x7ffffffd] range. */ 109 | x--; 110 | *ctx = x; 111 | return (x); 112 | } 113 | 114 | /* 115 | * Can't fix this garbage; too little state. 116 | */ 117 | int 118 | __rand_r(unsigned *ctx) 119 | { 120 | u_long val; 121 | int r; 122 | 123 | val = *ctx; 124 | r = do_rand(&val); 125 | *ctx = (unsigned)val; 126 | return (r); 127 | } 128 | -------------------------------------------------------------------------------- /core/xmalloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | void 14 | xfree(void *ptr) 15 | { 16 | free(ptr); 17 | } 18 | 19 | void * 20 | xcalloc(size_t nmemb, size_t size) 21 | { 22 | void *ret; 23 | size_t memory; 24 | 25 | /* we don't want to allocate 0 memory */ 26 | if (size == 0) { 27 | fprintf(stderr, "Failure on allocating 0 memory.\n"); 28 | exit(EXIT_FAILURE); 29 | } 30 | 31 | memory = nmemb*size; 32 | 33 | /* integer overflow */ 34 | if (memory/size != nmemb) { 35 | fprintf(stderr, "Integer overflow on xcalloc.\n"); 36 | exit(EXIT_FAILURE); 37 | } 38 | 39 | ret = calloc(nmemb, size); 40 | 41 | if (ret == NULL) { 42 | fprintf(stderr, "Failure on calloc.\n"); 43 | exit(EXIT_FAILURE); 44 | } 45 | else 46 | return ret; 47 | } 48 | 49 | void * 50 | xmalloc(size_t size) 51 | { 52 | void *ret; 53 | 54 | if (size == 0) { 55 | fprintf(stderr, "Failure on allocating 0 memory.\n"); 56 | exit(EXIT_FAILURE); 57 | } 58 | 59 | ret = malloc(size); 60 | 61 | if (ret == NULL) { 62 | fprintf(stderr, "Failure on malloc.\n"); 63 | exit(EXIT_FAILURE); 64 | } 65 | else { 66 | return ret; 67 | } 68 | } 69 | 70 | /* XXX: nuke that shit? */ 71 | void * 72 | _xrealloc(void * ptr, size_t nmemb, size_t size) 73 | { 74 | void *ret; 75 | size_t memory; 76 | 77 | /* we don't want to allocate 0 memory */ 78 | if (nmemb == 0 || size == 0) { 79 | fprintf(stderr, "Failure on allocating 0 memory.\n"); 80 | exit(EXIT_FAILURE); 81 | } 82 | 83 | memory = nmemb*size; 84 | 85 | /* integer overflow */ 86 | if (memory/size != nmemb) { 87 | fprintf(stderr, "Integer overflow on realloc.\n"); 88 | exit(EXIT_FAILURE); 89 | } 90 | 91 | ret = realloc(ptr, memory); 92 | 93 | if (ret == NULL) { 94 | fprintf(stderr, "Failure on realloc.\n"); 95 | exit(EXIT_FAILURE); 96 | } 97 | else { 98 | return ret; 99 | } 100 | } 101 | 102 | char * 103 | xstrdup(const char *str) 104 | { 105 | char * ret; 106 | ret = strdup(str); 107 | if (ret == NULL) { 108 | fprintf(stderr, "Failure on strdup.\n"); 109 | exit(EXIT_FAILURE); 110 | } else { 111 | return ret; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /include/minerva_assert.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #ifndef _MINERVA_ASSERT_H_ 10 | #define _MINERVA_ASSERT_H_ 11 | #ifdef MINERVA_DEBUG 12 | 13 | #include 14 | 15 | #define minerva_assert(X) assert(X); 16 | 17 | #else 18 | 19 | #define minerva_assert(X) do { } while(0); 20 | 21 | #endif /* ! MINERVA_DEBUG */ 22 | #endif /* ! _MINERVA_ASSERT_H_ */ 23 | -------------------------------------------------------------------------------- /include/minerva_call.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #ifndef _MINERVA_CALL_H_ 10 | #define _MINERVA_CALL_H_ 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | void sigsegv_minerva_call(int sig); 17 | void minerva_call(minerva_vars_t *, minerva_var_t *, minerva_func_t *, 18 | minerva_var_t **); 19 | void minerva_random_call(minerva_vars_t *, minerva_funcs_t *, 20 | minerva_trace_t *, int); 21 | 22 | #endif /* ! _MINERVA_CALL_H_ */ 23 | -------------------------------------------------------------------------------- /include/minerva_colors.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #ifndef _MINERVA_COLORS_H_ 10 | #define _MINERVA_COLORS_H_ 11 | 12 | #define ANSI_COLOR_RED "\x1b[31m" 13 | #define ANSI_COLOR_GREEN "\x1b[32m" 14 | #define ANSI_COLOR_YELLOW "\x1b[33m" 15 | #define ANSI_COLOR_BLUE "\x1b[34m" 16 | #define ANSI_COLOR_MAGENTA "\x1b[35m" 17 | #define ANSI_COLOR_CYAN "\x1b[36m" 18 | #define ANSI_COLOR_RESET "\x1b[0m" 19 | 20 | #define ANSI_CURSOR_HIDE "\033[?25l" 21 | #define ANSI_CURSOR_SHOW "\033[?25h" 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /include/minerva_concat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #ifndef _MINERVA_CONCAT_H_ 10 | #define _MINERVA_CONCAT_H_ 11 | 12 | void minerva_concat(char **, char *); 13 | 14 | #endif /* ! _MINERVA_CONCAT_H_ */ 15 | -------------------------------------------------------------------------------- /include/minerva_dict.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #ifndef _MINERVA_DICT_H_ 10 | #define _MINERVA_DICT_H_ 11 | #include 12 | #include 13 | #include 14 | 15 | typedef enum { 16 | MINERVA_RESULT_T, 17 | MINERVA_TRACE_T, 18 | MINERVA_VAR_T, 19 | MINERVA_DATABASE_T, 20 | MINERVA_STRING_T, 21 | MINERVA_NUMBER_T 22 | } minerva_dict_var_type_t; 23 | 24 | typedef struct { 25 | minerva_dict_var_type_t type; 26 | union { 27 | int num; 28 | char *str; 29 | void *var; 30 | } val; 31 | } minerva_dict_var_t; 32 | 33 | typedef struct { 34 | minerva_refs_t refs; 35 | minerva_vars_t *vars; 36 | minerva_funcs_t *funcs; 37 | minerva_trace_t *trace; 38 | } minerva_dict_var_result_t; 39 | 40 | typedef struct dict_t dict_t; 41 | 42 | dict_t *minerva_dict_create(void); 43 | int minerva_dict_set(dict_t *, const char *, minerva_dict_var_t *); 44 | minerva_dict_var_t *minerva_dict_get(dict_t *, const char *); 45 | void minerva_dict_destroy(dict_t *); 46 | void minerva_dict_var_destroy(minerva_dict_var_t *); 47 | #endif 48 | -------------------------------------------------------------------------------- /include/minerva_func.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #ifndef _MINERVA_FUNC_H_ 10 | #define _MINERVA_FUNC_H_ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | typedef enum { 18 | F_FUN_NONE = 0, /* none */ 19 | F_FUN_MUTATE = (1<<0) /* function mutates variables */ 20 | } minerva_func_flags_t; 21 | 22 | typedef uint8_t minerva_arg_flags_t; 23 | 24 | typedef int minerva_check_t(const void *); 25 | 26 | typedef void *minerva_function_t(minerva_var_t *new_var, 27 | minerva_var_t **vars); 28 | 29 | typedef struct { 30 | minerva_type_t type; 31 | minerva_arg_flags_t flags; 32 | } minerva_arg_t; 33 | 34 | typedef struct minerva_func_t { 35 | minerva_type_t return_type; 36 | uint32_t success; 37 | uint32_t failure; 38 | minerva_function_t *func; 39 | const char *name; 40 | minerva_func_flags_t flags; 41 | minerva_check_t *check; /* checking function */ 42 | LIST_ENTRY(minerva_func_t) entries; 43 | uint8_t arg_num; 44 | unsigned int id; 45 | minerva_arg_t **args; 46 | } minerva_func_t; 47 | typedef struct minerva_funcs_t minerva_funcs_t; 48 | LIST_HEAD(minerva_funcs_t, minerva_func_t); 49 | 50 | void minerva_funcs_print_stats(minerva_funcs_t *funcs); 51 | 52 | minerva_funcs_t *minerva_funcs_new(void); 53 | void minerva_funcs_init(minerva_funcs_t *); 54 | void minerva_funcs_add(minerva_funcs_t *funcs, const minerva_type_t return_type, 55 | void *fun, const char *name, const minerva_func_flags_t flags, 56 | minerva_check_t *check, const int arg_num, ...); 57 | minerva_func_t *minerva_func_get(minerva_funcs_t *, minerva_vars_t *, int); 58 | minerva_func_t *minerva_func_find(minerva_funcs_t *, const char *); 59 | void minerva_funcs_destroy(minerva_funcs_t *); 60 | #endif /* ! _MINERVA_FUNC_H_ */ 61 | -------------------------------------------------------------------------------- /include/minerva_generic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #ifndef _MINERVA_GENERIC_H_ 10 | #define _MINERVA_GENERIC_H_ 11 | 12 | #include 13 | #include 14 | 15 | /** checks if result is not null */ 16 | minerva_check_t generic_not_null; 17 | 18 | /** checks if result is not zero */ 19 | minerva_check_t generic_not_zero; 20 | 21 | /** checks if result is zero */ 22 | minerva_check_t generic_zero; 23 | 24 | /** void function return check - always failure */ 25 | minerva_check_t generic_void; 26 | 27 | /** always success */ 28 | minerva_check_t generic_success; 29 | 30 | /** mutators */ 31 | 32 | int mutate_int_xor(int, int); 33 | int mutate_int_or(int, int); 34 | int mutate_int_and(int, int ); 35 | 36 | /* God, have mercy on me */ 37 | #define MUTATE_TYPE_BITFLIP_PROTO(type) type mutate_##type##_bitflip(type) 38 | MUTATE_TYPE_BITFLIP_PROTO(int); 39 | MUTATE_TYPE_BITFLIP_PROTO(char); 40 | MUTATE_TYPE_BITFLIP_PROTO(long); 41 | 42 | /* God, have mercy on him */ 43 | #define CAST_TYPE_PROTO(from_type, to_type) to_type from_type##_to_##to_type(from_type x) 44 | CAST_TYPE_PROTO(int,char); 45 | CAST_TYPE_PROTO(char,int); 46 | CAST_TYPE_PROTO(long, int); 47 | CAST_TYPE_PROTO(int, long); 48 | CAST_TYPE_PROTO(float,double); 49 | CAST_TYPE_PROTO(double,float); 50 | CAST_TYPE_PROTO(int,float); 51 | CAST_TYPE_PROTO(float,int); 52 | 53 | /** stringify */ 54 | minerva_stringify_func_t minerva_generic_stringify_int; 55 | minerva_stringify_func_t minerva_generic_stringify_double; 56 | minerva_stringify_func_t minerva_generic_stringify_float; 57 | minerva_stringify_func_t minerva_generic_stringify_string; 58 | 59 | #endif /* ! _MINERVA_GENERIC_H_ */ 60 | -------------------------------------------------------------------------------- /include/minerva_loop.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #ifndef _MINERVA_LOOP_H_ 10 | #define _MINERVA_LOOP_H_ 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | int minerva_loop(unsigned int, minerva_vars_t **, minerva_funcs_t **, 19 | minerva_trace_t **, int); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /include/minerva_parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #ifndef _MINERVA_PARSER_H_ 10 | #define _MINERVA_PARSER_H_ 11 | 12 | typedef enum { 13 | NUMBER_VAL, 14 | STRING_VAL, 15 | VAR_VAL 16 | } minerva_repl_arg_type_t; 17 | 18 | typedef struct { 19 | minerva_repl_arg_type_t type; 20 | union { 21 | char *str; 22 | int num; 23 | char *var; 24 | } val; 25 | } minerva_repl_arg_t; 26 | 27 | typedef struct { 28 | char *fname; 29 | int num_arg; 30 | minerva_repl_arg_t **args; 31 | } minerva_call_t; 32 | 33 | /* lame */ 34 | typedef struct { 35 | minerva_repl_arg_t *var; 36 | minerva_call_t *call; 37 | } minerva_line_t; 38 | 39 | minerva_line_t *minerva_repl_parse(const char *); 40 | #endif 41 | -------------------------------------------------------------------------------- /include/minerva_refs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #ifndef _MINERVA_REFS_H_ 10 | #define _MINERVA_REFS_H_ 11 | 12 | #include 13 | 14 | typedef sig_atomic_t minerva_refs_t; 15 | 16 | #define MINERVA_REFS_INC(x) \ 17 | do {(x)->refs++;} while(0) 18 | 19 | #define MINERVA_REFS_DEC(x) \ 20 | do {(x)->refs--;} while(0) 21 | 22 | #define MINERVA_REFS(x) ((x)->refs) 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /include/minerva_repl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #ifndef _MINERVA_REPL_H_ 10 | #define _MINERVA_REPL_H_ 11 | 12 | #include 13 | #include 14 | 15 | typedef enum { 16 | VERBOSE_NORMAL = 0, 17 | VERBOSE_NOISY = 1, 18 | VERBOSE_DEBUG = 2 19 | } minerva_verbose_t; 20 | 21 | #define VERBOSE_LEVEL(x) (verbose >= (x)) 22 | 23 | extern int verbose; 24 | 25 | typedef minerva_dict_var_t *minerva_repl_func_t(int argc, 26 | minerva_dict_var_t **args); 27 | 28 | typedef struct { 29 | const char *fname; 30 | minerva_repl_func_t *faddr; 31 | int num_arg; 32 | const char *desc; 33 | } minerva_repl_funcs_t; 34 | 35 | void minerva_repl_eval_line(dict_t *, minerva_line_t *); 36 | void minerva_repl_error(const char *); 37 | void minerva_repl_line_destroy(minerva_line_t *); 38 | void minerva_repl(void); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /include/minerva_signal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #ifndef _MINERVA_SIGNAL_H_ 10 | #define _MINERVA_SIGNAL_H_ 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | extern sig_atomic_t exit_loop; 17 | extern sig_atomic_t segv; 18 | 19 | void minerva_signal_setup(jmp_buf *); 20 | void minerva_signal_revert(void); 21 | 22 | #endif /* ! _MINERVA_SIGNAL_H_ */ 23 | -------------------------------------------------------------------------------- /include/minerva_trace.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #ifndef _MINERVA_TRACE_H_ 10 | #define _MINERVA_TRACE_H_ 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | typedef struct minerva_fuzz_call_t { 17 | unsigned int result_id; 18 | minerva_func_t *func; 19 | unsigned int *arg_ids; 20 | TAILQ_ENTRY(minerva_fuzz_call_t) entries; 21 | } minerva_fuzz_call_t; 22 | typedef struct minerva_calls_t minerva_calls_t; 23 | TAILQ_HEAD(minerva_calls_t, minerva_fuzz_call_t); 24 | 25 | typedef struct minerva_trace_t { 26 | minerva_calls_t *calls; 27 | unsigned int calls_num; 28 | } minerva_trace_t; 29 | 30 | typedef enum { 31 | R_PLAY_NOTCRASHED = 0, 32 | R_PLAY_CRASHEDLAST = 1, 33 | R_PLAY_CRASHEDMIDDLE = 2 34 | } trace_play_result_t; 35 | 36 | minerva_trace_t *minerva_trace_new(); 37 | void minerva_trace_record(minerva_trace_t *, minerva_var_t *, minerva_func_t *, 38 | minerva_var_t **); 39 | int minerva_trace_play(minerva_trace_t *, minerva_vars_t *); 40 | void minerva_trace_save(minerva_trace_t*, const char*); 41 | minerva_trace_t *minerva_trace_restore(const char*, minerva_funcs_t *); 42 | minerva_trace_t *minerva_trace_minimize(minerva_trace_t*, minerva_funcs_t*, 43 | unsigned int); 44 | void minerva_trace_destroy(minerva_trace_t *); 45 | minerva_trace_t *minerva_trace_copy(minerva_trace_t *, minerva_funcs_t *); 46 | #endif /* ! _MINERVA_TRACE_H_ */ 47 | -------------------------------------------------------------------------------- /include/minerva_var.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #ifndef _MINERVA_VAR_H_ 10 | #define _MINERVA_VAR_H_ 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | typedef RB_HEAD(minerva_var_tree, minerva_var_t) minerva_var_rb_t; 17 | 18 | typedef struct { 19 | minerva_var_rb_t *vars; 20 | unsigned int *len; 21 | unsigned int cur_id; 22 | } minerva_vars_t; 23 | 24 | typedef enum { 25 | F_VAR_NONE = 0, /* none */ 26 | F_VAR_DESTROY = (1<<0), /* destroy argument after call */ 27 | F_VAR_UNIQUE = (1<<1), /* MUST be unique argument in call */ 28 | F_VAR_ALLOC = (1<<2), /* indicates allocated memory */ 29 | F_VAR_MUTATE = (1<<3) /* function mutates variable */ 30 | } minerva_arg_flag_t; 31 | 32 | typedef struct minerva_var_t { 33 | minerva_type_t type; /* variable type */ 34 | void *val; /* value */ 35 | minerva_arg_flag_t flags; /* variable flags */ 36 | unsigned int id; 37 | RB_ENTRY(minerva_var_t) entries; 38 | } minerva_var_t; 39 | 40 | RB_PROTOTYPE(minerva_var_tree, minerva_var_t, entries, minerva_var_rb_cmp); 41 | 42 | void minerva_vars_print_stats(minerva_vars_t *); 43 | minerva_vars_t *minerva_vars_new(void); 44 | minerva_var_t *minerva_var_new(minerva_vars_t *, minerva_type_t, 45 | unsigned int); 46 | void minerva_var_destroy(minerva_vars_t *, minerva_var_t *); 47 | void minerva_vars_destroy(minerva_vars_t *); 48 | minerva_var_t *minerva_var_get(minerva_vars_t *, minerva_type_t); 49 | minerva_var_t *minerva_var_find(minerva_vars_t *, minerva_type_t, unsigned int); 50 | void minerva_vars_evolution(minerva_vars_t *); 51 | 52 | typedef char *minerva_stringify_func_t(void *); 53 | 54 | typedef struct minerva_var_stringify_t { 55 | minerva_type_t type; 56 | minerva_stringify_func_t *func; 57 | } minerva_var_stringify_t; 58 | 59 | extern const minerva_var_stringify_t minerva_var_stringify_funcs[]; 60 | char *minerva_var_stringify(minerva_type_t, void *); 61 | void minerva_vars_stringify(minerva_vars_t *, const char *); 62 | 63 | #endif /* ! _MINERVA_VAR_H_ */ 64 | -------------------------------------------------------------------------------- /include/random.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright 2020 Conrad Meyer . All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 2. Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 | * SUCH DAMAGE. 24 | * 25 | * $FreeBSD$ 26 | */ 27 | 28 | #pragma once 29 | #include 30 | #include 31 | 32 | /* 33 | * For each of the currently supported random number generators, we have a 34 | * break value on the amount of state information (you need at least this 35 | * many bytes of state info to support this random number generator), a degree 36 | * for the polynomial (actually a trinomial) that the R.N.G. is based on, and 37 | * the separation between the two lower order coefficients of the trinomial. 38 | */ 39 | #define TYPE_0 0 /* linear congruential */ 40 | #define BREAK_0 8 41 | #define DEG_0 0 42 | #define SEP_0 0 43 | 44 | #define TYPE_1 1 /* x**7 + x**3 + 1 */ 45 | #define BREAK_1 32 46 | #define DEG_1 7 47 | #define SEP_1 3 48 | 49 | #define TYPE_2 2 /* x**15 + x + 1 */ 50 | #define BREAK_2 64 51 | #define DEG_2 15 52 | #define SEP_2 1 53 | 54 | #define TYPE_3 3 /* x**31 + x**3 + 1 */ 55 | #define BREAK_3 128 56 | #define DEG_3 31 57 | #define SEP_3 3 58 | 59 | #define TYPE_4 4 /* x**63 + x + 1 */ 60 | #define BREAK_4 256 61 | #define DEG_4 63 62 | #define SEP_4 1 63 | 64 | /* 65 | * Array versions of the above information to make code run faster -- 66 | * relies on fact that TYPE_i == i. 67 | */ 68 | #define MAX_TYPES 5 /* max number of types above */ 69 | 70 | /* A full instance of the random(3) generator. */ 71 | struct __random_state { 72 | uint32_t *rst_fptr; 73 | uint32_t *rst_rptr; 74 | uint32_t *rst_state; 75 | int rst_type; 76 | int rst_deg; 77 | int rst_sep; 78 | uint32_t *rst_end_ptr; 79 | /* Flexible array member must be last. */ 80 | uint32_t rst_randtbl[]; 81 | }; 82 | 83 | struct __random_state *allocatestate(unsigned type); 84 | int __initstate_r(struct __random_state *, unsigned, uint32_t *, size_t); 85 | long __random_r(struct __random_state *); 86 | void __srandom_r(struct __random_state *, unsigned); 87 | 88 | 89 | int __rand(void); 90 | void __srand(unsigned); 91 | int __rand_r(unsigned *ctx); 92 | -------------------------------------------------------------------------------- /include/xmalloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" 4 | * If we meet some day, and you think this stuff is worth it, you can buy us 5 | * a beer in return. 6 | * ---------------------------------------------------------------------------- 7 | */ 8 | 9 | #ifndef _XMALLOC_H_ 10 | #define _XMALLOC_H_ 11 | 12 | #include 13 | #include 14 | 15 | void xfree(void *); 16 | 17 | void *xcalloc(size_t, size_t); 18 | 19 | void *xmalloc(size_t); 20 | 21 | void *xrealloc(void *, size_t, size_t); 22 | 23 | char *xstrdup(const char *); 24 | 25 | #endif /* ! _XMALLOC_H_ */ 26 | -------------------------------------------------------------------------------- /mk/config.mk: -------------------------------------------------------------------------------- 1 | # 2 | # ---------------------------------------------------------------------------- 3 | # "THE BEER-WARE LICENSE" 4 | # If we meet some day, and you think this stuff is worth it, you can buy us 5 | # a beer in return. 6 | # ---------------------------------------------------------------------------- 7 | # 8 | 9 | BISON=bison 10 | FLEX=flex 11 | # from target perspective target/sth/ 12 | MICOMPILER=../../compiler/mi2c.py 13 | WRKDIR=bin/ 14 | TARGETWRKDIR=$(WRKDIR)/target/ 15 | COREWRKDIR=$(WRKDIR)/core 16 | LOCALWRKDIR=$(WRKDIR)/local/ 17 | 18 | COREDIR=../../core/ 19 | 20 | CFLAGS+=-I../../include/ -Wall -O0 -I$(TARGETWRKDIR) 21 | 22 | #default options 23 | WITH_READLINE=1 24 | WITH_PROGRESSBAR=1 25 | 26 | ifndef WITHOUT_READLINE 27 | CFLAGS+=-DWITH_READLINE 28 | LDFLAGS+=-lreadline -lcurses 29 | endif 30 | 31 | OS=$(shell uname -s) 32 | 33 | ifndef WITHOUT_PROGRESSBAR 34 | CFLAGS+=-DWITH_PROGRESSBAR 35 | LDFLAGS+=../../lib/progressbar/libprogressbar.a -lcurses 36 | ifeq ($(OS),FreeBSD) 37 | # clang in the FreeBSD no longer includes localbase by default so we have to 38 | # do it explicitly 39 | CFLAGS+="-I/usr/local/include/" 40 | LDFLAGS+="-L/usr/local/lib/" 41 | endif 42 | endif 43 | 44 | ifdef ASAN 45 | CFLAGS+=-fsanitize=address 46 | #XXX: fix building on gcc 47 | LDFLAGS+=-fsanitize=address 48 | endif 49 | 50 | ifdef DEBUG 51 | CFLAGS+=-DMINERVA_DEBUG -ggdb 52 | endif 53 | 54 | ifeq ($(MAKECMDGOALS),clean) 55 | MICONFIG=clean 56 | endif 57 | 58 | ifndef MICONFIG 59 | TMPMICONFIG=$(shell find . -maxdepth 1 -name "*.mi" | wc -l | tr -d ' ') 60 | ifeq ($(TMPMICONFIG), 1) 61 | MICONFIG=$(shell find . -maxdepth 1 -name "*.mi") 62 | $(info MICONFIG not provided, assuming $(MICONFIG)) 63 | endif 64 | endif 65 | 66 | ifndef MICONFIG 67 | $(error Multiple mi files in directory, specify MICONFIG (eg. make MICONFIG=foo.mi)) 68 | endif 69 | 70 | OUTFILE=minerva-$(TARGET)-$(basename $(notdir $(MICONFIG))) 71 | 72 | .PHONY: all 73 | all: bootstrap bin target local core link 74 | -------------------------------------------------------------------------------- /mk/core.mk: -------------------------------------------------------------------------------- 1 | # 2 | # ---------------------------------------------------------------------------- 3 | # "THE BEER-WARE LICENSE" 4 | # If we meet some day, and you think this stuff is worth it, you can buy us 5 | # a beer in return. 6 | # ---------------------------------------------------------------------------- 7 | # 8 | 9 | MINERVA_CORE_SRC=\ 10 | main.c \ 11 | minerva_dict.c \ 12 | minerva_call.c \ 13 | minerva_func.c \ 14 | minerva_generic.c \ 15 | minerva_var.c \ 16 | xmalloc.c \ 17 | minerva_repl.c \ 18 | minerva_loop.c \ 19 | minerva_trace.c \ 20 | minerva_signal.c \ 21 | dict.c \ 22 | random.c \ 23 | rand.c \ 24 | minerva_concat.c 25 | 26 | MINERVA_PARSER_OBJ=\ 27 | $(COREWRKDIR)/minerva_lexer.o \ 28 | $(COREWRKDIR)/minerva_parser.tab.o 29 | 30 | 31 | MINERVA_CORE_OBJ=$(patsubst %.c, $(COREWRKDIR)/%.o, $(MINERVA_CORE_SRC)) 32 | MINERVA_CORE_SRCDIR=$(patsubst %, $(COREDIR)/%, $(MINERVA_CORE_SRC)) 33 | 34 | core: core_start coredir parser $(MINERVA_CORE_OBJ) 35 | 36 | core_start: 37 | @echo "" 38 | @echo "####################################" 39 | @echo "# Building core #" 40 | @echo "####################################" 41 | @echo "" 42 | 43 | .PHONY: coredir 44 | coredir: 45 | @mkdir -p $(COREWRKDIR) 46 | 47 | $(MINERVA_CORE_OBJ): $(COREWRKDIR)/%.o : $(COREDIR)/%.c 48 | $(CC) $(CFLAGS) -I../../include/ -I../../lib/progressbar/include/ -I$(TARGETWRKDIR) -c -o $@ $< 49 | 50 | parser: $(COREWRKDIR)/minerva_parser.tab.c $(COREWRKDIR)/minerva_parser.tab.h $(COREWRKDIR)/minerva_lexer.c $(MINERVA_PARSER_OBJ) 51 | 52 | $(COREWRKDIR)/minerva_parser.tab.c $(WRKDIR)/minerva_parser.tab.h: $(COREDIR)/minerva_parser.y 53 | $(BISON) -d $(COREDIR)/minerva_parser.y -o $(COREWRKDIR)/minerva_parser.tab.c 54 | 55 | $(COREWRKDIR)/minerva_lexer.c: $(COREDIR)/minerva_lexer.l 56 | $(FLEX) -o $(COREWRKDIR)/minerva_lexer.c --header-file=$(COREWRKDIR)/minerva_lexer.h $(COREDIR)/minerva_lexer.l 57 | -------------------------------------------------------------------------------- /mk/minerva.mk: -------------------------------------------------------------------------------- 1 | include ../../mk/config.mk 2 | include ../../mk/core.mk 3 | include ../../mk/target.mk 4 | -------------------------------------------------------------------------------- /mk/target.mk: -------------------------------------------------------------------------------- 1 | # 2 | # ---------------------------------------------------------------------------- 3 | # "THE BEER-WARE LICENSE" 4 | # If we meet some day, and you think this stuff is worth it, you can buy us 5 | # a beer in return. 6 | # ---------------------------------------------------------------------------- 7 | # 8 | 9 | .PHONY: bootstrap 10 | bootstrap: 11 | @$(MAKE) -C ../../ -f Makefile.bootstrap 12 | 13 | bin: 14 | @mkdir -p $(WRKDIR) 15 | 16 | TARGET_OBJS=\ 17 | $(TARGETWRKDIR)/target.o 18 | 19 | .PHONY: target 20 | target: target_start targetdir $(TARGET_OBJS) 21 | 22 | .PHONY: target_start 23 | target_start: 24 | @echo "" 25 | @echo "####################################" 26 | @echo "# Generate & Build targets #" 27 | @echo "####################################" 28 | @echo "" 29 | 30 | $(TARGET_OBJS): $(TARGETWRKDIR)/target.c $(TARGETWRKDIR)/target.h 31 | $(CC) $(CFLAGS) -I. -c -o $@ $< 32 | 33 | $(TARGETWRKDIR)/target.c $(TARGETWRKDIR)/target.h: $(MICONFIG) 34 | $(MICOMPILER) -m $(MICONFIG) -o $(TARGETWRKDIR)/target $(MIFLAGS) 35 | 36 | .PHONY: targetdir 37 | targetdir: 38 | @mkdir -p $(TARGETWRKDIR) 39 | 40 | LOCAL_SRC?= 41 | LOCAL_OBJ=$(patsubst %.c, $(LOCALWRKDIR)/%.o, $(LOCAL_SRC)) 42 | 43 | local: local_start localdir $(LOCAL_OBJ) 44 | 45 | .PHONY: local_start 46 | local_start: 47 | @echo "" 48 | @echo "####################################" 49 | @echo "# Build local #" 50 | @echo "####################################" 51 | @echo "" 52 | 53 | $(LOCAL_OBJ): $(LOCALWRKDIR)/%.o : %.c 54 | $(CC) $(CFLAGS) -I. -c -o $@ $< 55 | 56 | .PHONY: localdir 57 | localdir: 58 | @mkdir -p $(LOCALWRKDIR) 59 | 60 | link: link_start $(WRKDIR)/$(OUTFILE) 61 | 62 | .PHONY: link_start 63 | link_start: 64 | @echo "" 65 | @echo "####################################" 66 | @echo "# Linking #" 67 | @echo "####################################" 68 | @echo "" 69 | 70 | $(WRKDIR)/$(OUTFILE): $(LOCAL_OBJ) $(MINERVA_CORE_OBJ) $(MINERVA_PARSER_OBJ) $(TARGET_OBJS) 71 | $(CC) -o $(WRKDIR)/$(OUTFILE) $(MINERVA_CORE_OBJ) $(MINERVA_PARSER_OBJ) $(TARGET_OBJS) $(LOCAL_OBJ) $(LDFLAGS) 72 | 73 | .PHONY: clean 74 | clean: 75 | @rm -fr $(WRKDIR) 76 | -------------------------------------------------------------------------------- /target/compare.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | LEFT=$1 4 | RIGHT=$2 5 | ITER=$3 6 | 7 | OSTYPE=$(uname -s) 8 | 9 | if [ "$OSTYPE" = "Linux" ]; then 10 | MD5=md5sum 11 | else 12 | MD5=md5 13 | fi 14 | 15 | while true; do 16 | while true; do 17 | SEED=$(od -A n -t u -N 4 /dev/urandom | tr -d ' ') 18 | LEFT_RESULT=$(${LEFT} -i ${ITER} -s ${SEED} -D /dev/stdout | ${MD5} | cut -d ' ' -f 1) 19 | RIGHT_RESULT=$(${RIGHT} -i ${ITER} -s ${SEED} -D /dev/stdout | ${MD5} | cut -d ' ' -f 1) 20 | 21 | if [ "${LEFT_RESULT}" != "${RIGHT_RESULT}" ] ; then 22 | break 23 | fi 24 | done 25 | 26 | echo "Found difference: ${SEED}" 27 | echo "LEFT: ${LEFT} -i ${ITER} -s ${SEED} -D /dev/stdout" 28 | echo "RIGHT: ${RIGHT} -i ${ITER} -s ${SEED} -D /dev/stdout" 29 | echo "" 30 | ${LEFT} -i ${ITER} -s ${SEED} -D $4${LEFT_RESULT}_${RIGHT_RESULT}.left -T $4${LEFT_RESULT}_${RIGHT_RESULT}.trace 31 | ${RIGHT} -i ${ITER} -s ${SEED} -D $4${LEFT_RESULT}_${RIGHT_RESULT}.right 32 | echo ${SEED} > $4${LEFT_RESULT}_${RIGHT_RESULT}.seed 33 | done 34 | -------------------------------------------------------------------------------- /target/generic/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=generic 2 | LOCAL_SRC= 3 | 4 | include ../../mk/minerva.mk 5 | -------------------------------------------------------------------------------- /target/generic/cast.mi: -------------------------------------------------------------------------------- 1 | #include 2 | --casts 3 | char int_to_char (int) => generic_success; 4 | int char_to_int (char) => generic_success; 5 | -- int long_to_int (long) => generic_success; 6 | -- long int_to_long (int) => generic_success; 7 | double float_to_double (float) => generic_success; 8 | float double_to_float (double) => generic_success; 9 | int float_to_int (float) => generic_success; 10 | float int_to_float (int) => generic_success; 11 | -------------------------------------------------------------------------------- /target/generic/mutate.mi: -------------------------------------------------------------------------------- 1 | #include 2 | --mutators 3 | int mutate_int_bitflip (int {MUTATE}) => generic_success; 4 | char mutate_char_bitflip (char {MUTATE}) => generic_success; 5 | long mutate_long_bitflip (long {MUTATE}) => generic_success; 6 | 7 | int mutate_int_xor (int {MUTATE}, int {MUTATE}) => generic_success; 8 | int mutate_int_or (int {MUTATE}, int {MUTATE}) => generic_success; 9 | int mutate_int_and (int {MUTATE}, int {MUTATE}) => generic_success; 10 | -------------------------------------------------------------------------------- /target/generic/stringify_generic.mi: -------------------------------------------------------------------------------- 1 | -- generic functions to stringify basic types 2 | 3 | int -> minerva_generic_stringify_int; 4 | float -> minerva_generic_stringify_float; 5 | double -> minerva_generic_stringify_double; 6 | char * -> minerva_generic_stringify_string; 7 | -------------------------------------------------------------------------------- /target/http/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=http 2 | LOCAL_SRC= \ 3 | http.c 4 | MIFLAGS=-I../generic/ 5 | 6 | include ../../mk/minerva.mk 7 | -------------------------------------------------------------------------------- /target/http/request.mi: -------------------------------------------------------------------------------- 1 | #include 2 | #include "minerva_concat.h" 3 | #include "http.h" 4 | 5 | HTTP_message_t *HTTP_message() => generic_not_null; 6 | HTTP_message_t * -> minerva_generic_stringify_string; 7 | -------------------------------------------------------------------------------- /target/libc/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=libc 2 | LOCAL_SRC= \ 3 | generate.c\ 4 | wrappers.c 5 | LDFLAGS=-g -pg -lrt -lm 6 | CFLAGS=-g -pg 7 | include ../../mk/minerva.mk 8 | -------------------------------------------------------------------------------- /target/libc/generate.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | static int ctr = 0; 9 | 10 | void* char_ptr_to_void_ptr(char* a) 11 | { 12 | return (void*) a; 13 | } 14 | time_t * 15 | generate_time_t(void) 16 | { 17 | return calloc(1, sizeof(time_t)); 18 | //return (ctr++)%2 == 0 ? calloc(1, sizeof(time_t)) : NULL; 19 | } 20 | 21 | char format[] = "%qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_-0987654321^#"; 22 | 23 | static char * 24 | format_string(size_t max) 25 | { 26 | char *r; 27 | size_t i; 28 | 29 | if (max == 0) 30 | max = rand() % 0x2000; 31 | 32 | r = calloc(max+1, sizeof(*r)); 33 | 34 | if (r == NULL) 35 | return NULL; 36 | 37 | for (i = 0; i < max; i++) 38 | r[i] = format[rand() % sizeof(format)]; 39 | 40 | r[max] = '\0'; 41 | 42 | return 0; 43 | } 44 | wint_t generate_wint_t() 45 | { 46 | return rand()%0x100; 47 | } 48 | /* 49 | char * 50 | strftime_wrapper(struct tm *tm) 51 | { 52 | size_t max; 53 | char *fmt; 54 | char *dst; 55 | 56 | max = 32 + rand() % 0x1000; 57 | dst = calloc(max, sizeof(*dst)); 58 | if (dst == NULL) 59 | goto out; 60 | fmt = format_string(0); 61 | if (fmt == NULL) 62 | goto out; 63 | if (strftime(dst, max, fmt, tm) == 0) { 64 | free(dst); 65 | dst = NULL; 66 | } 67 | out: 68 | free(fmt); 69 | return dst; 70 | }*/ -------------------------------------------------------------------------------- /target/libc/generate.h: -------------------------------------------------------------------------------- 1 | #ifndef _GENERATE_H_ 2 | #define _GENERATE_H_ 3 | time_t *generate_time_t(void); 4 | //char *strftime_wrapper(struct tm *tm); 5 | void* char_ptr_to_void_ptr(char* a); 6 | wint_t generate_wint_t(void); 7 | #endif 8 | -------------------------------------------------------------------------------- /target/libc/wrappers.h: -------------------------------------------------------------------------------- 1 | #ifndef _WRAPPERS_H_ 2 | #define _WRAPPERS_H_ 3 | 4 | struct my_ptr{ 5 | void* ptr; 6 | int len; 7 | int writeable; // 0 or 1 8 | }; 9 | 10 | /* STRING.H */ 11 | 12 | struct my_ptr* generate_str(); 13 | 14 | void memcpy_wrapper (struct my_ptr* ptr,int num); 15 | struct my_ptr * memmove_wrapper(struct my_ptr* ptr, int num); 16 | void strcpy_wrapper (struct my_ptr* ptr ); 17 | void strncpy_wrapper(const char * source, size_t num ); 18 | 19 | 20 | struct my_ptr * strcat_wrapper ( struct my_ptr * dst, struct my_ptr * src ); 21 | struct my_ptr *strncat_wrapper ( struct my_ptr * dst, struct my_ptr * src, size_t num ); 22 | 23 | int memcmp_wrapper ( struct my_ptr * ptr1, struct my_ptr * ptr2, size_t num ); 24 | int strcmp_wrapper ( struct my_ptr * ptr1, struct my_ptr * ptr2 ); 25 | int strcoll_wrapper ( struct my_ptr * ptr1, struct my_ptr * ptr2 ); 26 | int strncmp_wrapper ( struct my_ptr * ptr1, struct my_ptr * ptr2, size_t num ); 27 | void strxfrm_wrapper (struct my_ptr * src); 28 | 29 | void memchr_wrapper ( struct my_ptr * src, int val, int num); 30 | void strchr_wrapper ( struct my_ptr * src, int character); 31 | void strcspn_wrapper ( struct my_ptr * str1, struct my_ptr * str2 ); 32 | void strpbrk_wrapper ( struct my_ptr * str1, struct my_ptr * str2); 33 | void strrchr_wrapper ( struct my_ptr * str, int character); 34 | void strspn_wrapper ( struct my_ptr * str1, struct my_ptr * str2 ); 35 | void strstr_wrapper ( struct my_ptr * str1, struct my_ptr * str2); 36 | void strtok_wrapper ( struct my_ptr * str, struct my_ptr * delimiters ); 37 | 38 | int strlen_wrapper ( struct my_ptr * str ); 39 | 40 | struct my_ptr* asctime_wrapper(); 41 | struct my_ptr* memset_wrapper (int value, size_t num ); 42 | struct my_ptr* strerror_wrapper(int errnum); 43 | 44 | /* TIME.H */ 45 | 46 | struct my_ptr* ctime_wrapper(time_t * a); 47 | struct my_ptr* ctime_r_wrapper(time_t * a); 48 | struct tm *localtime_r_wrapper(const time_t * timep); 49 | struct my_ptr* strptime_wrapper(const char * format,struct tm * tm); 50 | time_t mktime_wrapper(struct tm * tm); 51 | struct my_ptr* asctime_r_wrapper(const struct tm * tm); 52 | struct tm *localtime_wrapper(const time_t * t); 53 | struct my_ptr* strftime_wrapper(struct my_ptr* format,struct tm* timeptr ); 54 | struct tm *gmtime_r_wrapper(const time_t *timep); 55 | struct tm *getdate_wrapper(struct my_ptr* ptr); 56 | struct tm *gmtime_wrapper(const time_t * t); 57 | 58 | /* STDLIB.H */ 59 | double atof_wrapper (struct my_ptr* str); 60 | int atoi_wrapper(struct my_ptr* str); 61 | long int atol_wrapper ( struct my_ptr* str ); 62 | double strtod_wrapper (struct my_ptr* str); 63 | long int strtol_wrapper(struct my_ptr* str); 64 | unsigned long int strtoul_wrapper (struct my_ptr* str); 65 | struct my_ptr* getenv_wrapper (struct my_ptr* str); 66 | 67 | div_t div_wrapper (int numer, int denom); 68 | ldiv_t ldiv_wrapper (long int numer, long int denom); 69 | int mblen_wrapper (struct my_ptr* str); 70 | int mbtowc_wrapper (struct my_ptr* str); 71 | int wctomb_wrapper (struct my_ptr* str); 72 | struct my_ptr* mbstowcs_wrapper(struct my_ptr* src); 73 | 74 | /* MATH.H */ 75 | double frexp_wrapper (double x , int* exp); 76 | float frexpf_wrapper (float x , int* exp); 77 | long double frexpl_wrapper (long double x, int* exp); 78 | double modf_wrapper (double x , double* intpart); 79 | float modff_wrapper (float x , float* intpart); 80 | long double modfl_wrapper (long double x, long double* intpart); 81 | 82 | /* wchar.h */ 83 | struct my_wide_ptr{ 84 | void* ptr; 85 | int len; 86 | }; 87 | struct my_wide_ptr* generate_wide_str(); 88 | double wcstod_wrapper (struct my_wide_ptr* str); 89 | long int wcstol_wrapper (struct my_wide_ptr* str); 90 | unsigned long int wcstoul_wrapper (struct my_wide_ptr* str); 91 | void mbrlen_wrapper(); 92 | void mbrtowc_wrapper (struct my_ptr* str); 93 | void mbsrtowcs_wrapper (struct my_ptr* str); 94 | void wcrtomb_wrapper (struct my_wide_ptr* str); 95 | 96 | struct my_wide_ptr* wcschr_wrapper(struct my_wide_ptr* str, wchar_t wc); 97 | int wcscmp_wrapper(struct my_wide_ptr* str1, struct my_wide_ptr* str2); 98 | int wcscoll_wrapper(struct my_wide_ptr* str1, struct my_wide_ptr* str2); 99 | int wcscspn_wrapper(struct my_wide_ptr* str1, struct my_wide_ptr* str2); 100 | int wcslen_wrapper (struct my_wide_ptr* str); 101 | int wcsncmp_wrapper(struct my_wide_ptr* str1, struct my_wide_ptr* str2); 102 | void wcspbrk_wrapper (struct my_wide_ptr* str1, struct my_wide_ptr* str2); 103 | struct my_wide_ptr* wcsrchr_wrapper(struct my_wide_ptr* str, wchar_t wc); 104 | int wcsspn_wrapper(struct my_wide_ptr* str1, struct my_wide_ptr* str2); 105 | int wcsstr_wrapper(struct my_wide_ptr* str1, struct my_wide_ptr* str2); 106 | int wcsxfrm_wrapper (struct my_wide_ptr* str); 107 | struct my_wide_ptr* wmemchr_wrapper(struct my_wide_ptr* str,wchar_t wc); 108 | 109 | void c16rtomb_wrapper ( struct my_ptr* str ); 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /target/libressl-bn/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=libressl 2 | LOCAL_SRC= \ 3 | generate.c \ 4 | stringify.c 5 | 6 | CFLAGS=-I include_dir/ -Werror 7 | LDFLAGS=-z muldefs -L . -lcompat -lcrypto -pthread 8 | 9 | include ../../mk/minerva.mk 10 | -------------------------------------------------------------------------------- /target/libressl-bn/README: -------------------------------------------------------------------------------- 1 | Installation 2 | ------------ 3 | 4 | Build libressl: 5 | 6 | Prepare sources: 7 | 8 | $ git clone https://github.com/libressl-portable/portable 9 | $ cd portable 10 | $ ./autogen.sh 11 | 12 | Compile (the example builds it with Address Sanitizer): 13 | 14 | $ CFLAGS="-fsanitize=address" LDFLAGS="-fsanitize=address" ./configure 15 | $ make -j4 16 | 17 | 18 | Create the following symlinks (or copy necessary files), this command should 19 | be performed in the target library: 20 | 21 | $ ln -s /dir/to/libressl/include include_dir 22 | $ ln -s /dir/to/libressl/crypto/.libs/libcompat.a 23 | $ ln -s /dir/to/libressl/crypto/.libs/libcrypto.a 24 | 25 | We assume libressl-portable usage, in case you use it natively you have to do 26 | some shifts in the Makefile with libcompat.a (which is not necessary). 27 | -------------------------------------------------------------------------------- /target/libressl-bn/bn.mi: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | -- stringify 8 | BIGNUM * -> stringify_bn; 9 | 10 | -- generators 11 | BIGNUM *bn_new() => generic_not_zero; 12 | BIGNUM *bn_gen_rand() => generic_not_zero; 13 | BN_ULONG bn_ulong_new() => generic_success; 14 | 15 | -- functions 16 | BIGNUM *BN_new() => generic_not_zero; 17 | void BN_free(BIGNUM *a {DESTROY}) => generic_void; 18 | --void BN_init(BIGNUM *) => generic_void; 19 | void BN_clear(BIGNUM *a) => generic_void; 20 | void BN_clear_free(BIGNUM *a {DESTROY} ) => generic_void; 21 | BN_CTX *BN_CTX_new() => generic_not_zero; 22 | -- void BN_CTX_init(BN_CTX *c) => generic_void; 23 | void BN_CTX_free(BN_CTX *c {DESTROY}) => generic_void; 24 | BIGNUM *BN_copy(BIGNUM *a, BIGNUM *b) => generic_void; 25 | BIGNUM *BN_dup(BIGNUM *a) => generic_not_zero; 26 | void BN_swap(BIGNUM *a, BIGNUM *b) => generic_void; 27 | int BN_num_bytes(BIGNUM *a) => generic_not_zero; 28 | int BN_num_bits(BIGNUM *a) => generic_not_zero; 29 | int BN_num_bits_word(BN_ULONG w) => generic_not_zero; 30 | void BN_set_negative(BIGNUM *a, int n) => generic_not_zero; int BN_is_negative(BIGNUM *a) => generic_void; 31 | int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b) => generic_not_zero; 32 | int BN_sub(BIGNUM *r, BIGNUM *a, BIGNUM *b) => generic_not_zero; 33 | int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) => generic_not_zero; 34 | int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx) => generic_not_zero; 35 | int BN_div(BIGNUM *dv, BIGNUM *rem, BIGNUM *a, BIGNUM *d, BN_CTX *ctx) => generic_not_zero; 36 | int BN_mod(BIGNUM *rem, BIGNUM *a, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 37 | int BN_nnmod(BIGNUM *rem, BIGNUM *a, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 38 | int BN_mod_add(BIGNUM *ret, BIGNUM *a, BIGNUM *b, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 39 | int BN_mod_sub(BIGNUM *ret, BIGNUM *a, BIGNUM *b, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 40 | int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 41 | int BN_mod_sqr(BIGNUM *ret, BIGNUM *a, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 42 | -- int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx) => generic_not_zero; 43 | int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 44 | int BN_gcd(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) => generic_not_zero; 45 | int BN_add_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 46 | int BN_sub_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 47 | int BN_mul_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 48 | BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 49 | BN_ULONG BN_mod_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 50 | int BN_cmp(BIGNUM *a, BIGNUM *b) => generic_not_zero; 51 | int BN_ucmp(BIGNUM *a, BIGNUM *b) => generic_not_zero; 52 | int BN_is_zero(BIGNUM *a) => generic_not_zero; 53 | int BN_is_one(BIGNUM *a) => generic_not_zero; 54 | int BN_is_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 55 | int BN_is_odd(BIGNUM *a) => generic_not_zero; 56 | int BN_zero(BIGNUM *a) => generic_not_zero; 57 | int BN_one(BIGNUM *a) => generic_not_zero; 58 | -- BIGNUM *BN_value_one() => generic_not_zero; 59 | int BN_set_word(BIGNUM *a, unsigned w) => generic_not_zero; 60 | unsigned BN_get_word(BIGNUM *a) => generic_not_zero; 61 | -- int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) => generic_not_zero; 62 | -- int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom) => generic_not_zero; 63 | -- int BN_rand_range(BIGNUM *rnd, BIGNUM *range) => generic_not_zero; 64 | -- int BN_pseudo_rand_range(BIGNUM *rnd, BIGNUM *range) => generic_not_zero; 65 | int BN_set_bit(BIGNUM *a, int n) => generic_not_zero; 66 | int BN_clear_bit(BIGNUM *a, int n) => generic_not_zero; 67 | int BN_is_bit_set(BIGNUM *a, int n) => generic_not_zero; 68 | int BN_mask_bits(BIGNUM *a, int n) => generic_not_zero; 69 | int BN_lshift(BIGNUM *r, BIGNUM *a, int n) => generic_not_zero; 70 | int BN_lshift1(BIGNUM *r, BIGNUM *a) => generic_not_zero; 71 | int BN_rshift(BIGNUM *r, BIGNUM *a, int n) => generic_not_zero; 72 | int BN_rshift1(BIGNUM *r, BIGNUM *a) => generic_not_zero; 73 | -- int BN_bn2bin(BIGNUM *a, char *to) => generic_not_zero; 74 | -- BIGNUM *BN_bin2bn(char *s, int len, BIGNUM *ret) => generic_not_zero; 75 | char *BN_bn2hex(BIGNUM *a) => generic_not_zero; 76 | char *BN_bn2dec(BIGNUM *a) => generic_not_zero; 77 | int BN_print(BIO *fp, BIGNUM *a) => generic_not_zero; 78 | int BN_print_fp(FILE *fp, BIGNUM *a) => generic_not_zero; 79 | -- int BN_bn2mpi(BIGNUM *a, char *to) => generic_not_zero; 80 | -- BIGNUM *BN_mpi2bn(char *s, int len, BIGNUM *ret) => generic_not_zero; 81 | -- BIGNUM *BN_mod_inverse(BIGNUM *r, BIGNUM *a, BIGNUM *n, BN_CTX *ctx) => generic_not_zero; 82 | BN_RECP_CTX *BN_RECP_CTX_new() => generic_not_zero; 83 | void BN_RECP_CTX_init(BN_RECP_CTX *recp) => generic_void; 84 | void BN_RECP_CTX_free(BN_RECP_CTX *recp {DESTROY}) => generic_void; 85 | int BN_RECP_CTX_set(BN_RECP_CTX *recp, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 86 | int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *a, BIGNUM *b, 87 | BN_RECP_CTX *recp, BN_CTX *ctx) => generic_not_zero; 88 | -- BN_MONT_CTX *BN_MONT_CTX_new() => generic_not_zero; 89 | -- void BN_MONT_CTX_init(BN_MONT_CTX *ctx) => generic_void; 90 | -- void BN_MONT_CTX_free(BN_MONT_CTX *mont {DESTROY}) => generic_void; 91 | -- int BN_MONT_CTX_set(BN_MONT_CTX *mont, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 92 | -- BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) => generic_void; 93 | int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_MONT_CTX *mont, BN_CTX *ctx) => generic_not_zero; 94 | int BN_from_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx) => generic_not_zero; 95 | int BN_to_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx) => generic_not_zero; 96 | BN_BLINDING *BN_BLINDING_new(BIGNUM *A, BIGNUM *Ai, BIGNUM *mod) => generic_not_zero; 97 | void BN_BLINDING_free(BN_BLINDING *b {DESTROY}) => generic_void; 98 | int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx) => generic_not_zero; 99 | int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) => generic_not_zero; 100 | int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) => generic_not_zero; 101 | int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx) => generic_not_zero; 102 | int BN_BLINDING_invert_ex(BIGNUM *n,BIGNUM *r,BN_BLINDING *b, BN_CTX *ctx) => generic_not_zero; 103 | -- long BN_BLINDING_get_thread_id(BN_BLINDING *) => generic_not_zero; 104 | -- void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned) => generic_void; 105 | long BN_BLINDING_get_flags(BN_BLINDING *) => generic_not_zero; 106 | void BN_BLINDING_set_flags(BN_BLINDING *, unsigned) => generic_void; 107 | -- BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, void (*callback)(int,int,void *), void *cb_arg) => generic_not_zero; 108 | -------------------------------------------------------------------------------- /target/libressl-bn/generate.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define GEN_RAND_MAX (12) 5 | 6 | BIGNUM * 7 | bn_new(void) 8 | { 9 | BIGNUM *x; 10 | x = BN_new(); 11 | if (!x) 12 | return NULL; 13 | //BN_rand(x, 64, 0, 0); 14 | BN_one(x); 15 | return x; 16 | } 17 | 18 | /* 19 | * bn_gen_rand - generates random BN, it uses internal minerva rand 20 | * implementation which ensures it is determnistic 21 | */ 22 | 23 | BIGNUM * 24 | bn_gen_rand(void) 25 | { 26 | int i, len; 27 | uint8_t x[GEN_RAND_MAX]; 28 | 29 | len = (rand() % (GEN_RAND_MAX-1)) + 1; 30 | 31 | for (i = 0; i < len; i++) { 32 | x[i] = rand(); 33 | } 34 | 35 | return BN_bin2bn(x, len, NULL); 36 | } 37 | 38 | BN_ULONG 39 | bn_ulong_new(void) 40 | { 41 | BN_ULONG r; 42 | uint8_t *x = (uint8_t *)&r; 43 | int i; 44 | 45 | for (i = 0; i < sizeof(r); i++) 46 | *(x++) = rand(); 47 | 48 | return r; 49 | } 50 | 51 | void __sanitizer_cov_trace_pc(void) { 52 | // printf("HERE: %p\n", __builtin_return_address(0)); 53 | } 54 | -------------------------------------------------------------------------------- /target/libressl-bn/generate.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | BIGNUM *bn_new(void); 4 | BIGNUM *bn_gen_rand(void); 5 | BN_ULONG bn_ulong_new(void); 6 | -------------------------------------------------------------------------------- /target/libressl-bn/stringify.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char *stringify_bn(void *x) { 6 | return BN_bn2dec(x); 7 | } 8 | -------------------------------------------------------------------------------- /target/libressl-bn/stringify.h: -------------------------------------------------------------------------------- 1 | #ifndef __STRINGIFY_H_ 2 | #define __STRINGIFY_H_ 3 | 4 | char *stringify_bn(void *); 5 | 6 | #endif /* ! __STRINGIFY_H_ */ 7 | -------------------------------------------------------------------------------- /target/libressl/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=libressl 2 | LOCAL_SRC= \ 3 | generate.c \ 4 | minerva_vars_init.c 5 | 6 | LDFLAGS=-g -pg -lssl -lcrypto 7 | CFLAGS=-g -pg 8 | 9 | include ../../mk/minerva.mk 10 | -------------------------------------------------------------------------------- /target/libressl/asn1.mi: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf) => generic_void; 5 | ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) => generic_void; 6 | ASN1_OBJECT *ASN1_OBJECT_new(void) => generic_void; 7 | ASN1_STRING *ASN1_STRING_dup(ASN1_STRING *a) => generic_void; 8 | ASN1_STRING *ASN1_STRING_new(void) => generic_void; 9 | ASN1_STRING *ASN1_STRING_type_new(int type) => generic_void; 10 | void ASN1_OBJECT_free(ASN1_OBJECT *a) => generic_void; 11 | void ASN1_STRING_free(ASN1_STRING *a) => generic_void; 12 | char *ASN1_STRING_data(ASN1_STRING *x) => generic_not_zero; 13 | int ASN1_STRING_length(ASN1_STRING *x) => generic_not_zero; 14 | int ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b) => generic_not_zero; 15 | int ASN1_STRING_set(ASN1_STRING *str, void *data, int len) => generic_not_zero; 16 | int ASN1_STRING_type(ASN1_STRING *x) => generic_not_zer; 17 | int ASN1_STRING_to_UTF8(char *out, ASN1_STRING *in) => generic_not_zero; 18 | int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, long flags) => generic_not_zero; 19 | int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, long flags) => generic_not_zero; 20 | int ASN1_STRING_print(BIO *out, ASN1_STRING *str) => generic_not_zero; 21 | 22 | -------------------------------------------------------------------------------- /target/libressl/bn.mi: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | BIGNUM *bn_new() => generic_not_zero; 7 | void BN_free(BIGNUM *a {DESTROY}) => generic_void; 8 | -- void BN_init(BIGNUM *) => generic_void; 9 | -- void BN_clear(BIGNUM *a) => generic_void; 10 | -- void BN_clear_free(BIGNUM *a {DESTROY} ) => generic_void; 11 | BN_CTX *BN_CTX_new() => generic_not_zero; 12 | void BN_CTX_init(BN_CTX *c) => generic_void; 13 | void BN_CTX_free(BN_CTX *c {DESTROY}) => generic_void; 14 | BIGNUM *BN_copy(BIGNUM *a, BIGNUM *b) => generic_void; 15 | BIGNUM *BN_dup(BIGNUM *a) => generic_not_zero; 16 | void BN_swap(BIGNUM *a, BIGNUM *b) => generic_void; 17 | int BN_num_bytes(BIGNUM *a) => generic_not_zero; 18 | int BN_num_bits(BIGNUM *a) => generic_not_zero; 19 | int BN_num_bits_word(BN_ULONG w) => generic_not_zero; 20 | void BN_set_negative(BIGNUM *a, int n) => generic_not_zero; int BN_is_negative(BIGNUM *a) => generic_void; 21 | int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b) => generic_not_zero; 22 | int BN_sub(BIGNUM *r, BIGNUM *a, BIGNUM *b) => generic_not_zero; 23 | int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) => generic_not_zero; 24 | int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx) => generic_not_zero; 25 | int BN_div(BIGNUM *dv, BIGNUM *rem, BIGNUM *a, BIGNUM *d, BN_CTX *ctx) => generic_not_zero; 26 | int BN_mod(BIGNUM *rem, BIGNUM *a, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 27 | int BN_nnmod(BIGNUM *rem, BIGNUM *a, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 28 | int BN_mod_add(BIGNUM *ret, BIGNUM *a, BIGNUM *b, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 29 | int BN_mod_sub(BIGNUM *ret, BIGNUM *a, BIGNUM *b, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 30 | int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 31 | int BN_mod_sqr(BIGNUM *ret, BIGNUM *a, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 32 | -- int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx) => generic_not_zero; 33 | int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 34 | int BN_gcd(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) => generic_not_zero; 35 | int BN_add_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 36 | int BN_sub_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 37 | int BN_mul_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 38 | BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 39 | BN_ULONG BN_mod_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 40 | int BN_cmp(BIGNUM *a, BIGNUM *b) => generic_not_zero; 41 | int BN_ucmp(BIGNUM *a, BIGNUM *b) => generic_not_zero; 42 | int BN_is_zero(BIGNUM *a) => generic_not_zero; 43 | int BN_is_one(BIGNUM *a) => generic_not_zero; 44 | int BN_is_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 45 | int BN_is_odd(BIGNUM *a) => generic_not_zero; 46 | int BN_zero(BIGNUM *a) => generic_not_zero; 47 | int BN_one(BIGNUM *a) => generic_not_zero; 48 | -- BIGNUM *BN_value_one() => generic_not_zero; 49 | int BN_set_word(BIGNUM *a, unsigned w) => generic_not_zero; 50 | unsigned BN_get_word(BIGNUM *a) => generic_not_zero; 51 | int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) => generic_not_zero; 52 | int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom) => generic_not_zero; 53 | int BN_rand_range(BIGNUM *rnd, BIGNUM *range) => generic_not_zero; 54 | int BN_pseudo_rand_range(BIGNUM *rnd, BIGNUM *range) => generic_not_zero; 55 | int BN_set_bit(BIGNUM *a, int n) => generic_not_zero; 56 | int BN_clear_bit(BIGNUM *a, int n) => generic_not_zero; 57 | int BN_is_bit_set(BIGNUM *a, int n) => generic_not_zero; 58 | int BN_mask_bits(BIGNUM *a, int n) => generic_not_zero; 59 | int BN_lshift(BIGNUM *r, BIGNUM *a, int n) => generic_not_zero; 60 | int BN_lshift1(BIGNUM *r, BIGNUM *a) => generic_not_zero; 61 | int BN_rshift(BIGNUM *r, BIGNUM *a, int n) => generic_not_zero; 62 | int BN_rshift1(BIGNUM *r, BIGNUM *a) => generic_not_zero; 63 | -- int BN_bn2bin(BIGNUM *a, char *to) => generic_not_zero; 64 | -- BIGNUM *BN_bin2bn(char *s, int len, BIGNUM *ret) => generic_not_zero; 65 | char *BN_bn2hex(BIGNUM *a) => generic_not_zero; 66 | char *BN_bn2dec(BIGNUM *a) => generic_not_zero; 67 | int BN_print(BIO *fp, BIGNUM *a) => generic_not_zero; 68 | int BN_print_fp(FILE *fp, BIGNUM *a) => generic_not_zero; 69 | -- int BN_bn2mpi(BIGNUM *a, char *to) => generic_not_zero; 70 | -- BIGNUM *BN_mpi2bn(char *s, int len, BIGNUM *ret) => generic_not_zero; 71 | -- BIGNUM *BN_mod_inverse(BIGNUM *r, BIGNUM *a, BIGNUM *n, BN_CTX *ctx) => generic_not_zero; 72 | -- BN_RECP_CTX *BN_RECP_CTX_new() => generic_not_zero; 73 | void BN_RECP_CTX_init(BN_RECP_CTX *recp) => generic_void; 74 | void BN_RECP_CTX_free(BN_RECP_CTX *recp {DESTROY}) => generic_void; 75 | int BN_RECP_CTX_set(BN_RECP_CTX *recp, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 76 | int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *a, BIGNUM *b, 77 | BN_RECP_CTX *recp, BN_CTX *ctx) => generic_not_zero; 78 | -- BN_MONT_CTX *BN_MONT_CTX_new() => generic_not_zero; 79 | void BN_MONT_CTX_init(BN_MONT_CTX *ctx) => generic_void; 80 | void BN_MONT_CTX_free(BN_MONT_CTX *mont {DESTROY}) => generic_void; 81 | int BN_MONT_CTX_set(BN_MONT_CTX *mont, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 82 | BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) => generic_void; 83 | int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_MONT_CTX *mont, BN_CTX *ctx) => generic_not_zero; 84 | int BN_from_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx) => generic_not_zero; 85 | int BN_to_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx) => generic_not_zero; 86 | -- BN_BLINDING *BN_BLINDING_new(BIGNUM *A, BIGNUM *Ai, BIGNUM *mod) => generic_not_zero; 87 | void BN_BLINDING_free(BN_BLINDING *b {DESTROY}) => generic_void; 88 | int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx) => generic_not_zero; 89 | int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) => generic_not_zero; 90 | int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) => generic_not_zero; 91 | int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx) => generic_not_zero; 92 | int BN_BLINDING_invert_ex(BIGNUM *n,BIGNUM *r,BN_BLINDING *b, BN_CTX *ctx) => generic_not_zero; 93 | long BN_BLINDING_get_thread_id(BN_BLINDING *) => generic_not_zero; 94 | void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned) => generic_void; 95 | long BN_BLINDING_get_flags(BN_BLINDING *) => generic_not_zero; 96 | void BN_BLINDING_set_flags(BN_BLINDING *, unsigned) => generic_void; 97 | -- BIO *minerva_BIO_new() => generic_not_zero; 98 | -- FILE *minerva_FILE_new() => generic_not_zero; 99 | BN_ULONG minerva_BN_ULONG_new() => generic_not_zero; 100 | -- BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, void (*callback)(int,int,void *), void *cb_arg) => generic_not_zero; 101 | -------------------------------------------------------------------------------- /target/libressl/generate.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | BIGNUM * 4 | bn_new(void) 5 | { 6 | BIGNUM *x; 7 | x = BN_new(); 8 | if (!x) 9 | return NULL; 10 | BN_one(x); 11 | return x; 12 | } 13 | -------------------------------------------------------------------------------- /target/libressl/generate.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | BIGNUM *bn_new(void); 4 | -------------------------------------------------------------------------------- /target/libressl/minerva_vars_init.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | unsigned short USE_ONCE = 0; 11 | 12 | 13 | BN_ULONG *minerva_BN_ULONG_new(void) 14 | { 15 | BIGNUM a; 16 | BN_ULONG v, *ret; 17 | 18 | BN_init(&a); 19 | do { 20 | BN_rand(&a, 512, 0, 0); 21 | v = a.d[0]; 22 | } while (!v); 23 | 24 | ret = &v; 25 | 26 | return (ret); 27 | } 28 | 29 | BIO *minerva_BIO_new(void) 30 | { 31 | BIO *ret = NULL; 32 | 33 | ret = BIO_new(BIO_s_file()); 34 | 35 | if (ret == NULL) 36 | fprintf(stderr, "minerva_BIO_new: BIO_new() call failed.\n"); 37 | 38 | if(!BIO_set_fp(ret, stdout, BIO_NOCLOSE)) 39 | fprintf(stderr, "minerva_BIO_new: BIO_set_fp() call failed.\n"); 40 | 41 | return (ret); 42 | } 43 | 44 | FILE *minerva_FILE_new(void) 45 | { 46 | FILE *ret = NULL; 47 | 48 | /* XXXsn: this must be definietly solved 49 | * in a different way, e.g. check if the 50 | * LIST has an element already assigned. 51 | */ 52 | if (USE_ONCE == 0) 53 | USE_ONCE = 1; 54 | else 55 | return (NULL); 56 | 57 | ret = fopen("/dev/urandom", "r"); 58 | 59 | if (ret == NULL) 60 | fprintf(stderr, "minerva_FILE_new: fopen() call failed.\n"); 61 | 62 | return (ret); 63 | } 64 | -------------------------------------------------------------------------------- /target/lm/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=lm 2 | LDFLAGS=-lm 3 | MIFLAGS=-I../generic/ # casts 4 | LOCAL_SRC=gen.c 5 | 6 | include ../../mk/minerva.mk 7 | -------------------------------------------------------------------------------- /target/lm/gen.c: -------------------------------------------------------------------------------- 1 | #include "gen.h" 2 | 3 | double getzero() { return 0; } 4 | double getone() { return 1; } 5 | -------------------------------------------------------------------------------- /target/lm/gen.h: -------------------------------------------------------------------------------- 1 | #ifndef _GEN_H_ 2 | #define _GEN_H_ 3 | 4 | double getone(); 5 | double getzero(); 6 | 7 | #endif /* ! _GEN_H_ */ 8 | -------------------------------------------------------------------------------- /target/lm/lm.mi: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "gen.h" 5 | 6 | %include 7 | %include 8 | %include 9 | 10 | -- 11 | -- MATH 12 | -- 13 | 14 | -- double drand48() => generic_success; 15 | 16 | double getone() => generic_success; 17 | double getzero() => generic_success; 18 | 19 | int isinf(double) => generic_success; 20 | int isnan(double) => generic_success; 21 | 22 | double acos(double) => generic_success; 23 | double asin(double) => generic_success; 24 | double atan(double) => generic_success; 25 | double atan2(double, double) => generic_success; 26 | double cos(double) => generic_success; 27 | double sin(double) => generic_success; 28 | double tan(double) => generic_success; 29 | 30 | double cosh(double) => generic_success; 31 | double sinh(double) => generic_success; 32 | double tanh(double) => generic_success; 33 | 34 | double exp(double) => generic_success; 35 | double frexp(double, int *) => generic_success; 36 | double ldexp(double, int) => generic_success; 37 | double log(double) => generic_success; 38 | double log10(double) => generic_success; 39 | double modf(double, double *) => generic_success; 40 | 41 | double pow(double, double) => generic_success; 42 | double sqrt(double) => generic_success; 43 | 44 | double ceil(double) => generic_success; 45 | double fabs(double) => generic_success; 46 | double floor(double) => generic_success; 47 | double fmod(double, double) => generic_success; 48 | 49 | double j0(double) => generic_success; 50 | double j1(double) => generic_success; 51 | double jn(int, double) => generic_success; 52 | double y0(double) => generic_success; 53 | double y1(double) => generic_success; 54 | double yn(int, double) => generic_success; 55 | double gamma(double) => generic_success; 56 | double scalb(double, double) => generic_success; 57 | double copysign(double, double) => generic_success; 58 | double fdim(double, double) => generic_success; 59 | double fmax(double, double) => generic_success; 60 | double fmin(double, double) => generic_success; 61 | double nearbyint(double) => generic_success; 62 | double round(double) => generic_success; 63 | double scalbln(double, long) => generic_success; 64 | double scalbn(double, int) => generic_success; 65 | double tgamma(double) => generic_success; 66 | double trunc(double) => generic_success; 67 | double drem(double, double) => generic_success; 68 | int finite(double) => generic_success; 69 | int isnanf(float) => generic_success; 70 | double lgamma_r(double, int *) => generic_success; 71 | double significand(double) => generic_success; 72 | float acosf(float) => generic_success; 73 | float asinf(float) => generic_success; 74 | float atanf(float) => generic_success; 75 | float atan2f(float, float) => generic_success; 76 | float cosf(float) => generic_success; 77 | float sinf(float) => generic_success; 78 | float tanf(float) => generic_success; 79 | float coshf(float) => generic_success; 80 | float sinhf(float) => generic_success; 81 | float tanhf(float) => generic_success; 82 | float exp2f(float) => generic_success; 83 | float expf(float) => generic_success; 84 | float expm1f(float) => generic_success; 85 | float frexpf(float, int *) => generic_success; 86 | int ilogbf(float) => generic_success; 87 | float ldexpf(float, int) => generic_success; 88 | float log10f(float) => generic_success; 89 | float log1pf(float) => generic_success; 90 | float log2f(float) => generic_success; 91 | float logf(float) => generic_success; 92 | float modff(float, float *) => generic_success; 93 | 94 | float powf(float, float) => generic_success; 95 | float sqrtf(float) => generic_success; 96 | 97 | float ceilf(float) => generic_success; 98 | float fabsf(float) => generic_success; 99 | float floorf(float) => generic_success; 100 | float fmodf(float, float) => generic_success; 101 | float roundf(float) => generic_success; 102 | float erff(float) => generic_success; 103 | float erfcf(float) => generic_success; 104 | float hypotf(float, float) => generic_success; 105 | float lgammaf(float) => generic_success; 106 | float tgammaf(float) => generic_success; 107 | float acoshf(float) => generic_success; 108 | float asinhf(float) => generic_success; 109 | float atanhf(float) => generic_success; 110 | float cbrtf(float) => generic_success; 111 | float logbf(float) => generic_success; 112 | float copysignf(float, float) => generic_success; 113 | long long llrintf(float) => generic_success; 114 | long long llroundf(float) => generic_success; 115 | long lrintf(float) => generic_success; 116 | long lroundf(float) => generic_success; 117 | float nanf(char *) => generic_success; 118 | float nearbyintf(float) => generic_success; 119 | float nextafterf(float, float) => generic_success; 120 | float remainderf(float, float) => generic_success; 121 | float remquof(float, float, int *) => generic_success; 122 | float rintf(float) => generic_success; 123 | float scalblnf(float, long) => generic_success; 124 | float scalbnf(float, int) => generic_success; 125 | float truncf(float) => generic_success; 126 | float fdimf(float, float) => generic_success; 127 | float fmaf(float, float, float) => generic_success; 128 | float fmaxf(float, float) => generic_success; 129 | float fminf(float, float) => generic_success; 130 | float dremf(float, float) => generic_success; 131 | int finitef(float) => generic_success; 132 | float gammaf(float) => generic_success; 133 | float j0f(float) => generic_success; 134 | float j1f(float) => generic_success; 135 | float jnf(int, float) => generic_success; 136 | float scalbf(float, float) => generic_success; 137 | float y0f(float) => generic_success; 138 | float y1f(float) => generic_success; 139 | float ynf(int, float) => generic_success; 140 | float lgammaf_r(float, int *) => generic_success; 141 | float significandf(float) => generic_success; 142 | long double acoshl(long double) => generic_success; 143 | long double acosl(long double) => generic_success; 144 | long double asinhl(long double) => generic_success; 145 | long double asinl(long double) => generic_success; 146 | long double atan2l(long double, long double) => generic_success; 147 | long double atanhl(long double) => generic_success; 148 | long double atanl(long double) => generic_success; 149 | long double cbrtl(long double) => generic_success; 150 | long double ceill(long double) => generic_success; 151 | long double copysignl(long double, long double) => generic_success; 152 | long double coshl(long double) => generic_success; 153 | long double cosl(long double) => generic_success; 154 | long double erfcl(long double) => generic_success; 155 | long double erfl(long double) => generic_success; 156 | long double exp2l(long double) => generic_success; 157 | long double expl(long double) => generic_success; 158 | long double expm1l(long double) => generic_success; 159 | long double fabsl(long double) => generic_success; 160 | long double fdiml(long double, long double) => generic_success; 161 | long double floorl(long double) => generic_success; 162 | long double fmal(long double, long double, long double) => generic_success; 163 | long double fmaxl(long double, long double) => generic_success; 164 | long double fminl(long double, long double) => generic_success; 165 | long double fmodl(long double, long double) => generic_success; 166 | long double frexpl(long double value, int *) => generic_success; 167 | long double hypotl(long double, long double) => generic_success; 168 | int ilogbl(long double) => generic_success; 169 | long double ldexpl(long double, int) => generic_success; 170 | long double lgammal(long double) => generic_success; 171 | long long llrintl(long double) => generic_success; 172 | long long llroundl(long double) => generic_success; 173 | long double log10l(long double) => generic_success; 174 | long double log1pl(long double) => generic_success; 175 | long double log2l(long double) => generic_success; 176 | long double logbl(long double) => generic_success; 177 | long double logl(long double) => generic_success; 178 | long lrintl(long double) => generic_success; 179 | long lroundl(long double) => generic_success; 180 | long double modfl(long double, long double *) => generic_success; 181 | long double nanl( const char *) => generic_success; 182 | long double nearbyintl(long double) => generic_success; 183 | long double nextafterl(long double, long double) => generic_success; 184 | double nexttoward(double, long double) => generic_success; 185 | float nexttowardf(float, long double) => generic_success; 186 | long double nexttowardl(long double, long double) => generic_success; 187 | long double powl(long double, long double) => generic_success; 188 | long double remainderl(long double, long double) => generic_success; 189 | long double remquol(long double, long double, int *) => generic_success; 190 | long double rintl(long double) => generic_success; 191 | long double roundl(long double) => generic_success; 192 | long double scalblnl(long double, long) => generic_success; 193 | long double scalbnl(long double, int) => generic_success; 194 | long double sinhl(long double) => generic_success; 195 | long double sinl(long double) => generic_success; 196 | long double sqrtl(long double) => generic_success; 197 | long double tanhl(long double) => generic_success; 198 | long double tanl(long double) => generic_success; 199 | long double tgammal(long double) => generic_success; 200 | long double truncl(long double) => generic_success; 201 | -------------------------------------------------------------------------------- /target/netbsd-syscalls/Makefile: -------------------------------------------------------------------------------- 1 | # Compile using: 2 | # CC=rump-cc make WITHOUT_READLINE=1 WITHOUT_PROGRESSBAR=1 DEBUG=1 MICONFIG=syscalls.mi 3 | TARGET=netbsd-syscalls 4 | LOCAL_SRC= \ 5 | rump-syscalls.c 6 | MIFLAGS=-I ../generic/ 7 | 8 | include ../../mk/minerva.mk 9 | -------------------------------------------------------------------------------- /target/netbsd-syscalls/rump-syscalls.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "rump-syscalls.h" 4 | 5 | int * 6 | get_int() 7 | { 8 | int *x = malloc(sizeof(int)); 9 | 10 | if (x == NULL) 11 | return NULL; 12 | 13 | *x = rand(); 14 | 15 | return x; 16 | } 17 | 18 | int 19 | filter_write(int a, char *b, int c) { 20 | if (a <= 2) 21 | return 0; 22 | else 23 | return rump___sysimpl_write(a, b, c); 24 | 25 | } 26 | 27 | int 28 | filter_read(int a, char *b, int c) { 29 | if (a <= 2) 30 | return 0; 31 | else 32 | return rump___sysimpl_read(a, b, c); 33 | 34 | } 35 | 36 | char * 37 | empty(int x) 38 | { 39 | char *r = malloc(x); 40 | if (r == NULL) 41 | return NULL; 42 | memset(r, 0, x); 43 | return r; 44 | } 45 | 46 | char * 47 | randstr(int x) 48 | { 49 | char *r = malloc(x); 50 | int i; 51 | 52 | if (r == NULL) 53 | return NULL; 54 | 55 | for (i = 0 ; i < x; i++) 56 | r[i] = rand() % 256; 57 | 58 | return r; 59 | } 60 | 61 | int 62 | zero(void) 63 | { 64 | return 0; 65 | } 66 | 67 | int 68 | add_one(int x) 69 | { 70 | return x+1; 71 | } 72 | -------------------------------------------------------------------------------- /target/netbsd-syscalls/rump-syscalls.h: -------------------------------------------------------------------------------- 1 | #ifndef _TOY_H_ 2 | #define _TOY_H_ 3 | 4 | int zero(void); 5 | int add_one(int x); 6 | int crashme(int x); 7 | int *get_int(); 8 | char *empty(int x); 9 | char *randstr(int x); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /target/netbsd-syscalls/syscalls.mi: -------------------------------------------------------------------------------- 1 | #include 2 | #include "rump-syscalls.h" 3 | 4 | -- mutators 5 | 6 | %include 7 | 8 | -- DUMMY 9 | 10 | int zero() => generic_success; 11 | int add_one(int x) => generic_success; 12 | 13 | -- HELPERS 14 | 15 | char *empty(int x) => generic_not_null; 16 | char *randstr(int x) => generic_not_null; 17 | int *get_int() => generic_not_null; 18 | 19 | -- SYSCALLS 20 | 21 | int filter_write(int, char *, int) => generic_success; 22 | int filter_read(int, char *, int) => generic_success; 23 | int rump___sysimpl_close(int) => generic_success; 24 | int rump___sysimpl_fchdir(int) => generic_success; 25 | void rump___sysimpl_sync() => generic_success; 26 | int rump___sysimpl_open(char *, int, int, int) => generic_success; 27 | int rump___sysimpl_kqueue() => generic_success; 28 | int rump___sysimpl_faccessat(int, char *, int, int) => generic_success; 29 | int rump___sysimpl_fchmodat(int, char *, int, int) => generic_success; 30 | int rump___sysimpl_fchownat(int, char *, int, int, int) => generic_success; 31 | int rump___sysimpl_fstatat(int, char *, struct stat *, int) => generic_success; 32 | int rump___sysimpl_utimensat(int, char *, struct timespec *, int) => generic_success; 33 | int rump___sysimpl_link(char *, char *) => generic_success; 34 | int rump___sysimpl_unlink(char *) => generic_success; 35 | int rump___sysimpl_chdir(char *) => generic_success; 36 | int rump___sysimpl_chmod(char *, int) => generic_success; 37 | int rump___sysimpl_chown(char *, int, int) => generic_success; 38 | int rump___sysimpl_getpid() => generic_success; 39 | int rump___sysimpl_unmount(char *, int) => generic_success; 40 | int rump___sysimpl_setuid(int) => generic_success; 41 | int rump___sysimpl_getuid() => generic_success; 42 | int rump___sysimpl_geteuid() => generic_success; 43 | int rump___sysimpl_recvmsg(int, struct msghdr *, int) => generic_success; 44 | int rump___sysimpl_sendmsg(int, struct msghdr *, int) => generic_success; 45 | -- int rump___sysimpl_recvfrom(int, char *, int, int, struct sockaddr *, int *) => generic_success; 46 | -- int rump___sysimpl_accept(int, struct sockaddr *, int *) => generic_success; 47 | -- int rump___sysimpl_getpeername(int, struct sockaddr *, int *) => generic_success; 48 | -- int rump___sysimpl_getsockname(int, struct sockaddr *, int *) => generic_success; 49 | int rump___sysimpl_access(char *, int) => generic_success; 50 | int rump___sysimpl_chflags(char *, long) => generic_success; 51 | int rump___sysimpl_fchflags(int, long) => generic_success; 52 | int rump___sysimpl_getppid() => generic_success; 53 | int rump___sysimpl_dup(int) => generic_success; 54 | int rump___sysimpl_getegid() => generic_success; 55 | int rump___sysimpl_ktrace(char *, int, int, int) => generic_success; 56 | int rump___sysimpl_getgid() => generic_success; 57 | int rump___sysimpl___getlogin(char *, int) => generic_success; 58 | int rump___sysimpl___setlogin(char *) => generic_success; 59 | int rump___sysimpl_flock(int, int) => generic_success; 60 | int rump___sysimpl_setsid() => generic_success; 61 | int rump___sysimpl_socket30(int, int, int) => generic_success; 62 | int rump___sysimpl_dup3(int, int, int) => generic_success; 63 | int rump___sysimpl_kqueue1(int) => generic_success; 64 | int rump___sysimpl_issetugid() => generic_success; 65 | int rump___sysimpl_fchroot(int) => generic_success; 66 | int rump___sysimpl_setgid(int) => generic_success; 67 | int rump___sysimpl_setegid(int) => generic_success; 68 | -- int rump___sysimpl_reboot(int, char *) => generic_success; 69 | int rump___sysimpl_seteuid(int) => generic_success; 70 | int rump___sysimpl_shutdown(int, int) => generic_success; 71 | int rump___sysimpl_fdatasync(int) => generic_success; 72 | -- int rump___sysimpl_socketpair(int, int, int, int *) => generic_success; 73 | int rump___sysimpl_ftruncate(int, int) => generic_success; 74 | int rump___sysimpl_fchown(int, int, int) => generic_success; 75 | int rump___sysimpl_fchmod(int, int) => generic_success; 76 | int rump___sysimpl_setreuid(int, int) => generic_success; 77 | int rump___sysimpl_setregid(int, int) => generic_success; 78 | int rump___sysimpl_rename(char *, char *) => generic_success; 79 | int rump___sysimpl_mkfifo(char *, int) => generic_success; 80 | int rump___sysimpl___posix_chown(char *, int, int) => generic_success; 81 | int rump___sysimpl___posix_fchown(int, int, int) => generic_success; 82 | int rump___sysimpl___posix_lchown(char *, int, int) => generic_success; 83 | int rump___sysimpl_getsid(int) => generic_success; 84 | int rump___sysimpl_revoke(char *) => generic_success; 85 | int rump___sysimpl_fktrace(int, int, int, int) => generic_success; 86 | -- ?? int rump___sysimpl_pipe(int *) => generic_success; 87 | int rump___sysimpl_posix_fallocate(int, int, int) => generic_success; 88 | int rump___sysimpl_fdiscard(int, int, int) => generic_success; 89 | int rump___sysimpl___quotactl(char *, struct quotactl_args *) => generic_success; 90 | int rump___sysimpl_unlinkat(int, char *, int) => generic_success; 91 | int rump___sysimpl_futimens(int, struct timespec *) => generic_success; 92 | int rump___sysimpl_recvmmsg(int, struct mmsghdr *, int, int, struct timespec *) => generic_success; 93 | int rump___sysimpl_sendmmsg(int, struct mmsghdr *, int, int) => generic_success; 94 | int rump___sysimpl_clock_nanosleep(clockid_t, int, struct timespec *, struct timespec *) => generic_success; 95 | int rump___sysimpl_chroot(char *) => generic_success; 96 | int rump___sysimpl_symlink(char *, char *) => generic_success; 97 | int rump___sysimpl_readlink(char *, char *, int) => generic_success; 98 | int rump___sysimpl_umask(int) => generic_success; 99 | int rump___sysimpl_dup2(int, int) => generic_success; 100 | -- int rump___sysimpl_fcntl(int, int, int, int, int, int) => generic_success; 101 | int rump___sysimpl_listen(int, int) => generic_success; 102 | int rump___sysimpl_fsync(int) => generic_success; 103 | int rump___sysimpl_getpgrp() => generic_success; 104 | int rump___sysimpl_setpgid(int, int) => generic_success; 105 | int rump___sysimpl_getgroups(int, int *) => generic_success; 106 | int rump___sysimpl_setgroups(int, int *) => generic_success; 107 | int rump___sysimpl_pathconf(char *, int) => generic_success; 108 | int rump___sysimpl_fpathconf(int, int) => generic_success; 109 | int rump___sysimpl_pread(int, char *, int, int) => generic_success; 110 | int rump___sysimpl_pwrite(int, char *, int, int) => generic_success; 111 | int rump___sysimpl_truncate(char *, int) => generic_success; 112 | int rump___sysimpl_lseek(int, int, int) => generic_success; 113 | int rump___sysimpl_getpgid(int) => generic_success; 114 | int rump___sysimpl_mkdir(char *, int) => generic_success; 115 | int rump___sysimpl_rmdir(char *) => generic_success; 116 | -- int rump___sysimpl_utimes(char *, struct timeval *) => generic_success; 117 | int rump___sysimpl_fsync_range(int, int, int, int) => generic_success; 118 | --int rump___sysimpl_utrace(char *, char *, size_t) => generic_success; 119 | -- int rump___sysimpl_getfh(char *, char *, int *) => generic_success; 120 | -- int rump___sysimpl_nfssvc(int, char *) => generic_success; 121 | -- int rump___sysimpl_modctl(int, char *) => generic_success; 122 | int rump___sysimpl___getcwd(char *, int) => generic_success; 123 | int rump___sysimpl_ioctl(int, int, int, int, int, int) => generic_success; 124 | -- int rump___sysimpl_lio_listio(int, struct aiocb **, int, struct sigevent *) => generic_success; 125 | -- int rump___sysimpl_mount(char *, char *, int, char *, int) => generic_success; 126 | -- int rump___sysimpl_posix_fadvise(int, int, int, int) => generic_success; 127 | -- int rump___sysimpl_gettimeofday(struct timeval *, char *) => generic_success; 128 | -- int rump___sysimpl_settimeofday(struct timeval *, char *) => generic_success; 129 | -- int rump___sysimpl_adjtime(struct timeval *, struct timeval *) => generic_success; 130 | -- int rump___sysimpl_setitimer(int, struct itimerval *, struct itimerval *) => generic_success; 131 | -- int rump___sysimpl_getitimer(int, struct itimerval *) => generic_success; 132 | -- int rump___sysimpl_clock_gettime(clockid_t, struct timespec *) => generic_success; 133 | -- int rump___sysimpl_clock_settime(clockid_t, struct timespec *) => generic_success; 134 | -- int rump___sysimpl_clock_getres(clockid_t, struct timespec *) => generic_success; 135 | -- int rump___sysimpl_nanosleep(struct timespec *, struct timespec *) => generic_success; 136 | -- int rump___sysimpl_aio_suspend(struct aiocb **, int, struct timespec *) => generic_success; 137 | -- int rump___sysimpl_timer_settime(timer_t, int, struct itimerspec *, struct itimerspec *) => generic_success; 138 | -- int rump___sysimpl_timer_gettime(timer_t, struct itimerspec *) => generic_success; 139 | -- int rump___sysimpl_mknod(char *, int, dev_t) => generic_success; 140 | -- int rump___sysimpl_pipe2(int *, int) => generic_success; 141 | -- int rump___sysimpl_getdents(int, char *, int) => generic_success; 142 | -- int rump___sysimpl_select(int, fd_set *, fd_set *, fd_set *, struct timeval *) => generic_success; 143 | int rump___sysimpl_connect(int, const struct sockaddr *, int) => generic_success; 144 | int rump___sysimpl_bind(int, struct sockaddr *, int) => generic_success; 145 | int rump___sysimpl_setsockopt(int, int, int, const char *, int) => generic_success; 146 | int rump___sysimpl_getsockopt(int, int, int, char *, int *) => generic_success; 147 | int rump___sysimpl_getrlimit(int, struct rlimit *) => generic_success; 148 | int rump___sysimpl_setrlimit(int, const struct rlimit *) => generic_success; 149 | -------------------------------------------------------------------------------- /target/openssl-bn/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=openssl 2 | LOCAL_SRC= \ 3 | generate.c \ 4 | stringify.c 5 | 6 | CFLAGS=-I include_dir/ 7 | LDFLAGS=-z muldefs -L . -lcrypto -ldl -pthread 8 | 9 | include ../../mk/minerva.mk 10 | -------------------------------------------------------------------------------- /target/openssl-bn/README: -------------------------------------------------------------------------------- 1 | Installation 2 | ------------ 3 | 4 | Get sources: 5 | 6 | $ git clone --depth=1 --branch=OpenSSL_1_1_1-stable https://github.com/openssl/openssl/ 7 | 8 | Build OpenSSL (in the example OpenSSL is build with debug options and 9 | address sanitizer): 10 | 11 | $ ./config --debug -fsanitize=address 12 | $ make -j4 13 | 14 | Create the following symlinks (or copy necessary files): 15 | 16 | $ ln -s /dir/to/openssl/include include_dir 17 | $ ln -s /dir/to/openssl/libcrypto.a 18 | -------------------------------------------------------------------------------- /target/openssl-bn/bn.mi: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | -- stringify 8 | BIGNUM * -> stringify_bn; 9 | 10 | -- generators 11 | BIGNUM *bn_new() => generic_not_zero; 12 | BIGNUM *bn_gen_rand() => generic_not_zero; 13 | BN_ULONG bn_ulong_new() => generic_success; 14 | 15 | -- functions 16 | BIGNUM *BN_new() => generic_not_zero; 17 | void BN_free(BIGNUM *a {DESTROY}) => generic_void; 18 | --void BN_init(BIGNUM *) => generic_void; 19 | void BN_clear(BIGNUM *a) => generic_void; 20 | void BN_clear_free(BIGNUM *a {DESTROY} ) => generic_void; 21 | BN_CTX *BN_CTX_new() => generic_not_zero; 22 | -- void BN_CTX_init(BN_CTX *c) => generic_void; 23 | void BN_CTX_free(BN_CTX *c {DESTROY}) => generic_void; 24 | BIGNUM *BN_copy(BIGNUM *a, BIGNUM *b) => generic_void; 25 | BIGNUM *BN_dup(BIGNUM *a) => generic_not_zero; 26 | void BN_swap(BIGNUM *a, BIGNUM *b) => generic_void; 27 | int BN_num_bytes(BIGNUM *a) => generic_not_zero; 28 | int BN_num_bits(BIGNUM *a) => generic_not_zero; 29 | int BN_num_bits_word(BN_ULONG w) => generic_not_zero; 30 | void BN_set_negative(BIGNUM *a, int n) => generic_not_zero; int BN_is_negative(BIGNUM *a) => generic_void; 31 | int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b) => generic_not_zero; 32 | int BN_sub(BIGNUM *r, BIGNUM *a, BIGNUM *b) => generic_not_zero; 33 | int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) => generic_not_zero; 34 | int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx) => generic_not_zero; 35 | int BN_div(BIGNUM *dv, BIGNUM *rem, BIGNUM *a, BIGNUM *d, BN_CTX *ctx) => generic_not_zero; 36 | int BN_mod(BIGNUM *rem, BIGNUM *a, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 37 | int BN_nnmod(BIGNUM *rem, BIGNUM *a, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 38 | int BN_mod_add(BIGNUM *ret, BIGNUM *a, BIGNUM *b, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 39 | int BN_mod_sub(BIGNUM *ret, BIGNUM *a, BIGNUM *b, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 40 | int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 41 | int BN_mod_sqr(BIGNUM *ret, BIGNUM *a, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 42 | -- int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx) => generic_not_zero; 43 | int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 44 | int BN_gcd(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) => generic_not_zero; 45 | int BN_add_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 46 | int BN_sub_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 47 | int BN_mul_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 48 | BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 49 | BN_ULONG BN_mod_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 50 | int BN_cmp(BIGNUM *a, BIGNUM *b) => generic_not_zero; 51 | int BN_ucmp(BIGNUM *a, BIGNUM *b) => generic_not_zero; 52 | int BN_is_zero(BIGNUM *a) => generic_not_zero; 53 | int BN_is_one(BIGNUM *a) => generic_not_zero; 54 | int BN_is_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 55 | int BN_is_odd(BIGNUM *a) => generic_not_zero; 56 | int BN_zero(BIGNUM *a) => generic_not_zero; 57 | int BN_one(BIGNUM *a) => generic_not_zero; 58 | -- BIGNUM *BN_value_one() => generic_not_zero; 59 | int BN_set_word(BIGNUM *a, unsigned w) => generic_not_zero; 60 | unsigned BN_get_word(BIGNUM *a) => generic_not_zero; 61 | -- int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) => generic_not_zero; 62 | -- int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom) => generic_not_zero; 63 | -- int BN_rand_range(BIGNUM *rnd, BIGNUM *range) => generic_not_zero; 64 | -- int BN_pseudo_rand_range(BIGNUM *rnd, BIGNUM *range) => generic_not_zero; 65 | int BN_set_bit(BIGNUM *a, int n) => generic_not_zero; 66 | int BN_clear_bit(BIGNUM *a, int n) => generic_not_zero; 67 | int BN_is_bit_set(BIGNUM *a, int n) => generic_not_zero; 68 | int BN_mask_bits(BIGNUM *a, int n) => generic_not_zero; 69 | int BN_lshift(BIGNUM *r, BIGNUM *a, int n) => generic_not_zero; 70 | int BN_lshift1(BIGNUM *r, BIGNUM *a) => generic_not_zero; 71 | int BN_rshift(BIGNUM *r, BIGNUM *a, int n) => generic_not_zero; 72 | int BN_rshift1(BIGNUM *r, BIGNUM *a) => generic_not_zero; 73 | -- int BN_bn2bin(BIGNUM *a, char *to) => generic_not_zero; 74 | -- BIGNUM *BN_bin2bn(char *s, int len, BIGNUM *ret) => generic_not_zero; 75 | char *BN_bn2hex(BIGNUM *a) => generic_not_zero; 76 | char *BN_bn2dec(BIGNUM *a) => generic_not_zero; 77 | int BN_print(BIO *fp, BIGNUM *a) => generic_not_zero; 78 | int BN_print_fp(FILE *fp, BIGNUM *a) => generic_not_zero; 79 | -- int BN_bn2mpi(BIGNUM *a, char *to) => generic_not_zero; 80 | -- BIGNUM *BN_mpi2bn(char *s, int len, BIGNUM *ret) => generic_not_zero; 81 | -- BIGNUM *BN_mod_inverse(BIGNUM *r, BIGNUM *a, BIGNUM *n, BN_CTX *ctx) => generic_not_zero; 82 | BN_RECP_CTX *BN_RECP_CTX_new() => generic_not_zero; 83 | void BN_RECP_CTX_init(BN_RECP_CTX *recp) => generic_void; 84 | void BN_RECP_CTX_free(BN_RECP_CTX *recp {DESTROY}) => generic_void; 85 | int BN_RECP_CTX_set(BN_RECP_CTX *recp, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 86 | int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *a, BIGNUM *b, 87 | BN_RECP_CTX *recp, BN_CTX *ctx) => generic_not_zero; 88 | -- BN_MONT_CTX *BN_MONT_CTX_new() => generic_not_zero; 89 | -- void BN_MONT_CTX_init(BN_MONT_CTX *ctx) => generic_void; 90 | -- void BN_MONT_CTX_free(BN_MONT_CTX *mont {DESTROY}) => generic_void; 91 | -- int BN_MONT_CTX_set(BN_MONT_CTX *mont, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 92 | -- BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) => generic_void; 93 | int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_MONT_CTX *mont, BN_CTX *ctx) => generic_not_zero; 94 | int BN_from_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx) => generic_not_zero; 95 | int BN_to_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx) => generic_not_zero; 96 | BN_BLINDING *BN_BLINDING_new(BIGNUM *A, BIGNUM *Ai, BIGNUM *mod) => generic_not_zero; 97 | void BN_BLINDING_free(BN_BLINDING *b {DESTROY}) => generic_void; 98 | int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx) => generic_not_zero; 99 | int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) => generic_not_zero; 100 | int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) => generic_not_zero; 101 | int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx) => generic_not_zero; 102 | int BN_BLINDING_invert_ex(BIGNUM *n,BIGNUM *r,BN_BLINDING *b, BN_CTX *ctx) => generic_not_zero; 103 | -- long BN_BLINDING_get_thread_id(BN_BLINDING *) => generic_not_zero; 104 | -- void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned) => generic_void; 105 | long BN_BLINDING_get_flags(BN_BLINDING *) => generic_not_zero; 106 | void BN_BLINDING_set_flags(BN_BLINDING *, unsigned) => generic_void; 107 | -- BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, void (*callback)(int,int,void *), void *cb_arg) => generic_not_zero; 108 | -------------------------------------------------------------------------------- /target/openssl-bn/generate.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define GEN_RAND_MAX (12) 5 | 6 | BIGNUM * 7 | bn_new(void) 8 | { 9 | BIGNUM *x; 10 | x = BN_new(); 11 | if (!x) 12 | return NULL; 13 | //BN_rand(x, 64, 0, 0); 14 | BN_one(x); 15 | return x; 16 | } 17 | 18 | /* 19 | * bn_gen_rand - generates random BN, it uses internal minerva rand 20 | * implementation which ensures it is determnistic 21 | */ 22 | 23 | BIGNUM * 24 | bn_gen_rand(void) 25 | { 26 | int i, len; 27 | uint8_t x[GEN_RAND_MAX]; 28 | 29 | len = (rand() % (GEN_RAND_MAX-1)) + 1; 30 | 31 | for (i = 0; i < len; i++) { 32 | x[i] = rand(); 33 | } 34 | 35 | return BN_bin2bn(x, len, NULL); 36 | } 37 | 38 | BN_ULONG 39 | bn_ulong_new(void) 40 | { 41 | BN_ULONG r; 42 | uint8_t *x = (uint8_t *)&r; 43 | int i; 44 | 45 | for (i = 0; i < sizeof(r); i++) 46 | *(x++) = rand(); 47 | 48 | return r; 49 | } 50 | 51 | void __sanitizer_cov_trace_pc(void) { 52 | // printf("HERE: %p\n", __builtin_return_address(0)); 53 | } 54 | -------------------------------------------------------------------------------- /target/openssl-bn/generate.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | BIGNUM *bn_new(void); 4 | BIGNUM *bn_gen_rand(void); 5 | BN_ULONG bn_ulong_new(void); 6 | -------------------------------------------------------------------------------- /target/openssl-bn/stringify.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char *stringify_bn(void *x) { 6 | return BN_bn2dec(x); 7 | } 8 | -------------------------------------------------------------------------------- /target/openssl-bn/stringify.h: -------------------------------------------------------------------------------- 1 | #ifndef __STRINGIFY_H_ 2 | #define __STRINGIFY_H_ 3 | 4 | char *stringify_bn(void *); 5 | 6 | #endif /* ! __STRINGIFY_H_ */ 7 | -------------------------------------------------------------------------------- /target/openssl/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=openssl 2 | LOCAL_SRC= \ 3 | minerva_vars_init.c 4 | 5 | LDFLAGS=-lssl -lcrypto 6 | 7 | include ../../mk/minerva.mk 8 | -------------------------------------------------------------------------------- /target/openssl/asn1.mi: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf) => generic_void; 5 | ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) => generic_void; 6 | ASN1_OBJECT *ASN1_OBJECT_new() => generic_void; 7 | ASN1_STRING *ASN1_STRING_dup(ASN1_STRING *a) => generic_void; 8 | ASN1_STRING *ASN1_STRING_new() => generic_void; 9 | ASN1_STRING *ASN1_STRING_type_new(int type) => generic_void; 10 | void ASN1_OBJECT_free(ASN1_OBJECT *a) => generic_void; 11 | void ASN1_STRING_free(ASN1_STRING *a) => generic_void; 12 | char *ASN1_STRING_data(ASN1_STRING *x) => generic_not_zero; 13 | int ASN1_STRING_length(ASN1_STRING *x) => generic_not_zero; 14 | int ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b) => generic_not_zero; 15 | int ASN1_STRING_set(ASN1_STRING *str, void *data, int len) => generic_not_zero; 16 | int ASN1_STRING_type(ASN1_STRING *x) => generic_not_zero; 17 | -- int ASN1_STRING_to_UTF8(char *out, ASN1_STRING *in) => generic_not_zero; 18 | int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, long flags) => generic_not_zero; 19 | int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, long flags) => generic_not_zero; 20 | int ASN1_STRING_print(BIO *out, ASN1_STRING *str) => generic_not_zero; 21 | -------------------------------------------------------------------------------- /target/openssl/bn.mi: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | BIGNUM *BN_new() => generic_not_zero; 6 | void BN_free(BIGNUM *a {DESTROY}) => generic_void; 7 | void BN_init(BIGNUM *) => generic_void; 8 | void BN_clear(BIGNUM *a) => generic_void; 9 | void BN_clear_free(BIGNUM *a {DESTROY} ) => generic_void; 10 | BN_CTX *BN_CTX_new() => generic_not_zero; 11 | void BN_CTX_init(BN_CTX *c) => generic_void; 12 | void BN_CTX_free(BN_CTX *c {DESTROY}) => generic_void; 13 | BIGNUM *BN_copy(BIGNUM *a, BIGNUM *b) => generic_void; 14 | BIGNUM *BN_dup(BIGNUM *a) => generic_not_zero; 15 | void BN_swap(BIGNUM *a, BIGNUM *b) => generic_void; 16 | int BN_num_bytes(BIGNUM *a) => generic_not_zero; 17 | int BN_num_bits(BIGNUM *a) => generic_not_zero; 18 | int BN_num_bits_word(BN_ULONG w) => generic_not_zero; 19 | void BN_set_negative(BIGNUM *a, int n) => generic_not_zero; int BN_is_negative(BIGNUM *a) => generic_void; 20 | int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b) => generic_not_zero; 21 | int BN_sub(BIGNUM *r, BIGNUM *a, BIGNUM *b) => generic_not_zero; 22 | int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) => generic_not_zero; 23 | int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx) => generic_not_zero; 24 | int BN_div(BIGNUM *dv, BIGNUM *rem, BIGNUM *a, BIGNUM *d, BN_CTX *ctx) => generic_not_zero; 25 | int BN_mod(BIGNUM *rem, BIGNUM *a, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 26 | int BN_nnmod(BIGNUM *rem, BIGNUM *a, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 27 | int BN_mod_add(BIGNUM *ret, BIGNUM *a, BIGNUM *b, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 28 | int BN_mod_sub(BIGNUM *ret, BIGNUM *a, BIGNUM *b, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 29 | int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 30 | int BN_mod_sqr(BIGNUM *ret, BIGNUM *a, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 31 | int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx) => generic_not_zero; 32 | int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 33 | int BN_gcd(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) => generic_not_zero; 34 | int BN_add_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 35 | int BN_sub_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 36 | int BN_mul_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 37 | BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 38 | BN_ULONG BN_mod_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 39 | int BN_cmp(BIGNUM *a, BIGNUM *b) => generic_not_zero; 40 | int BN_ucmp(BIGNUM *a, BIGNUM *b) => generic_not_zero; 41 | int BN_is_zero(BIGNUM *a) => generic_not_zero; 42 | int BN_is_one(BIGNUM *a) => generic_not_zero; 43 | int BN_is_word(BIGNUM *a, BN_ULONG w) => generic_not_zero; 44 | int BN_is_odd(BIGNUM *a) => generic_not_zero; 45 | int BN_zero(BIGNUM *a) => generic_not_zero; 46 | int BN_one(BIGNUM *a) => generic_not_zero; 47 | -- BIGNUM *BN_value_one() => generic_not_zero; 48 | int BN_set_word(BIGNUM *a, unsigned w) => generic_not_zero; 49 | unsigned BN_get_word(BIGNUM *a) => generic_not_zero; 50 | int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) => generic_not_zero; 51 | int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom) => generic_not_zero; 52 | int BN_rand_range(BIGNUM *rnd, BIGNUM *range) => generic_not_zero; 53 | int BN_pseudo_rand_range(BIGNUM *rnd, BIGNUM *range) => generic_not_zero; 54 | int BN_set_bit(BIGNUM *a, int n) => generic_not_zero; 55 | int BN_clear_bit(BIGNUM *a, int n) => generic_not_zero; 56 | int BN_is_bit_set(BIGNUM *a, int n) => generic_not_zero; 57 | int BN_mask_bits(BIGNUM *a, int n) => generic_not_zero; 58 | int BN_lshift(BIGNUM *r, BIGNUM *a, int n) => generic_not_zero; 59 | int BN_lshift1(BIGNUM *r, BIGNUM *a) => generic_not_zero; 60 | int BN_rshift(BIGNUM *r, BIGNUM *a, int n) => generic_not_zero; 61 | int BN_rshift1(BIGNUM *r, BIGNUM *a) => generic_not_zero; 62 | -- int BN_bn2bin(BIGNUM *a, char *to) => generic_not_zero; 63 | -- BIGNUM *BN_bin2bn(char *s, int len, BIGNUM *ret) => generic_not_zero; 64 | char *BN_bn2hex(BIGNUM *a) => generic_not_zero; 65 | char *BN_bn2dec(BIGNUM *a) => generic_not_zero; 66 | int BN_print(BIO *fp, BIGNUM *a) => generic_not_zero; 67 | int BN_print_fp(FILE *fp, BIGNUM *a) => generic_not_zero; 68 | -- int BN_bn2mpi(BIGNUM *a, char *to) => generic_not_zero; 69 | -- BIGNUM *BN_mpi2bn(char *s, int len, BIGNUM *ret) => generic_not_zero; 70 | -- BIGNUM *BN_mod_inverse(BIGNUM *r, BIGNUM *a, BIGNUM *n, BN_CTX *ctx) => generic_not_zero; 71 | BN_RECP_CTX *BN_RECP_CTX_new() => generic_not_zero; 72 | void BN_RECP_CTX_init(BN_RECP_CTX *recp) => generic_void; 73 | void BN_RECP_CTX_free(BN_RECP_CTX *recp {DESTROY}) => generic_void; 74 | int BN_RECP_CTX_set(BN_RECP_CTX *recp, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 75 | int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *a, BIGNUM *b, 76 | BN_RECP_CTX *recp, BN_CTX *ctx) => generic_not_zero; 77 | BN_MONT_CTX *BN_MONT_CTX_new() => generic_not_zero; 78 | void BN_MONT_CTX_init(BN_MONT_CTX *ctx) => generic_void; 79 | void BN_MONT_CTX_free(BN_MONT_CTX *mont {DESTROY}) => generic_void; 80 | int BN_MONT_CTX_set(BN_MONT_CTX *mont, BIGNUM *m, BN_CTX *ctx) => generic_not_zero; 81 | BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) => generic_void; 82 | int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_MONT_CTX *mont, BN_CTX *ctx) => generic_not_zero; 83 | int BN_from_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx) => generic_not_zero; 84 | int BN_to_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx) => generic_not_zero; 85 | BN_BLINDING *BN_BLINDING_new(BIGNUM *A, BIGNUM *Ai, BIGNUM *mod) => generic_not_zero; 86 | void BN_BLINDING_free(BN_BLINDING *b {DESTROY}) => generic_void; 87 | int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx) => generic_not_zero; 88 | int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) => generic_not_zero; 89 | int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) => generic_not_zero; 90 | int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx) => generic_not_zero; 91 | int BN_BLINDING_invert_ex(BIGNUM *n,BIGNUM *r,BN_BLINDING *b, BN_CTX *ctx) => generic_not_zero; 92 | long BN_BLINDING_get_thread_id(BN_BLINDING *) => generic_not_zero; 93 | void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned) => generic_void; 94 | long BN_BLINDING_get_flags(BN_BLINDING *) => generic_not_zero; 95 | void BN_BLINDING_set_flags(BN_BLINDING *, unsigned) => generic_void; 96 | -- BIO *minerva_BIO_new() => generic_not_zero; 97 | -- FILE *minerva_FILE_new() => generic_not_zero; 98 | BN_ULONG minerva_BN_ULONG_new() => generic_not_zero; 99 | -- BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, void (*callback)(int,int,void *), void *cb_arg) => generic_not_zero; 100 | -------------------------------------------------------------------------------- /target/openssl/minerva_vars_init.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | unsigned short USE_ONCE = 0; 11 | 12 | 13 | BN_ULONG *minerva_BN_ULONG_new(void) 14 | { 15 | BIGNUM a; 16 | BN_ULONG v, *ret; 17 | 18 | BN_init(&a); 19 | do { 20 | BN_rand(&a, 512, 0, 0); 21 | v = a.d[0]; 22 | } while (!v); 23 | 24 | ret = &v; 25 | 26 | return (ret); 27 | } 28 | 29 | BIO *minerva_BIO_new(void) 30 | { 31 | BIO *ret = NULL; 32 | 33 | ret = BIO_new(BIO_s_file()); 34 | 35 | if (ret == NULL) 36 | fprintf(stderr, "minerva_BIO_new: BIO_new() call failed.\n"); 37 | 38 | if(!BIO_set_fp(ret, stdout, BIO_NOCLOSE)) 39 | fprintf(stderr, "minerva_BIO_new: BIO_set_fp() call failed.\n"); 40 | 41 | return (ret); 42 | } 43 | 44 | FILE *minerva_FILE_new(void) 45 | { 46 | FILE *ret = NULL; 47 | 48 | /* XXXsn: this must be definietly solved 49 | * in a different way, e.g. check if the 50 | * LIST has an element already assigned. 51 | */ 52 | if (USE_ONCE == 0) 53 | USE_ONCE = 1; 54 | else 55 | return (NULL); 56 | 57 | ret = fopen("/dev/urandom", "r"); 58 | 59 | if (ret == NULL) 60 | fprintf(stderr, "minerva_FILE_new: fopen() call failed.\n"); 61 | 62 | return (ret); 63 | } 64 | -------------------------------------------------------------------------------- /target/openssl/minerva_vars_init.h: -------------------------------------------------------------------------------- 1 | #ifndef _MINERVA_VARS_INIT_H_ 2 | #define _MINERVA_VARS_INIT_H_ 3 | 4 | #include 5 | #include 6 | 7 | BN_ULONG minerva_BN_ULONG_new(void); 8 | BIO *minerva_BIO_new(void); 9 | FILE *minerva_FILE_new(void); 10 | 11 | #endif /* ! _MINERVA_VARS_INIT_H_ */ 12 | -------------------------------------------------------------------------------- /target/toy/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=toy 2 | LOCAL_SRC= \ 3 | toy.c 4 | 5 | include ../../mk/minerva.mk 6 | -------------------------------------------------------------------------------- /target/toy/toy.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "toy.h" 4 | 5 | int 6 | zero(void) 7 | { 8 | return 0; 9 | } 10 | 11 | int 12 | add_one(int x) 13 | { 14 | return x+1; 15 | } 16 | 17 | int 18 | crashme(int x) 19 | { 20 | int *y = NULL; 21 | if (x > 4) 22 | return *y; 23 | else 24 | return x+2; 25 | } 26 | -------------------------------------------------------------------------------- /target/toy/toy.h: -------------------------------------------------------------------------------- 1 | #ifndef _TOY_H_ 2 | #define _TOY_H_ 3 | 4 | int zero(void); 5 | int add_one(int x); 6 | int crashme(int x); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /target/toy/toy.mi: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int zero() => generic_success; 5 | int add_one(int x) => generic_success; 6 | int crashme(int x) => generic_success; 7 | -------------------------------------------------------------------------------- /target/toy2/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=toy 2 | LOCAL_SRC= \ 3 | toy.c 4 | 5 | include ../../mk/minerva.mk 6 | -------------------------------------------------------------------------------- /target/toy2/mutators.mi: -------------------------------------------------------------------------------- 1 | int mutate_int_and(int a {MUTATE}, int b {MUTATE}) => generic_success; 2 | int mutate_int_or(int a {MUTATE}, int b {MUTATE}) => generic_success; 3 | int mutate_int_xor(int a {MUTATE}, int b {MUTATE}) => generic_success; 4 | int mutate_int_bitflip(int a {MUTATE}) => generic_success; 5 | -------------------------------------------------------------------------------- /target/toy2/toy.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "toy.h" 4 | 5 | int 6 | zero(void) 7 | { 8 | return 0; 9 | } 10 | 11 | int 12 | add_one(int x) 13 | { 14 | return x+1; 15 | } 16 | 17 | int 18 | crashme(int x) 19 | { 20 | int *y = NULL; 21 | if (x > 33) 22 | return *y; 23 | else 24 | return x+2; 25 | } 26 | -------------------------------------------------------------------------------- /target/toy2/toy.h: -------------------------------------------------------------------------------- 1 | #ifndef _TOY_H_ 2 | #define _TOY_H_ 3 | 4 | int zero(void); 5 | int add_one(int x); 6 | int crashme(int x); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /target/toy2/toy.mi: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int zero() => generic_success; 5 | int add_one(int x) => generic_success; 6 | int crashme(int x) => generic_success; 7 | 8 | %include "mutators.mi" 9 | -------------------------------------------------------------------------------- /target/url/Makefile.curl: -------------------------------------------------------------------------------- 1 | TARGET=curl 2 | LOCAL_SRC= \ 3 | url.c \ 4 | exec-curl.c 5 | 6 | CFLAGS=-I /usr/local/include 7 | LDFLAGS=-L /usr/local/lib -lcurl 8 | 9 | include ../../mk/minerva.mk 10 | -------------------------------------------------------------------------------- /target/url/Makefile.fetch: -------------------------------------------------------------------------------- 1 | TARGET=fetch 2 | LOCAL_SRC= \ 3 | url.c \ 4 | exec-fetch.c 5 | 6 | LDFLAGS=-lfetch 7 | 8 | include ../../mk/minerva.mk 9 | -------------------------------------------------------------------------------- /target/url/exec-curl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "exec.h" 4 | 5 | char * 6 | get_host(URI_t *x) { 7 | char *r = NULL; 8 | CURLU *h = curl_url(); 9 | 10 | if (curl_url_set(h, CURLUPART_URL, x, 0) != CURLUE_OK) 11 | goto cleanup; 12 | 13 | curl_url_get(h, CURLUPART_HOST, &r, 0); 14 | 15 | cleanup: 16 | curl_url_cleanup(h); 17 | return r; 18 | } 19 | -------------------------------------------------------------------------------- /target/url/exec-fetch.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "exec.h" 8 | 9 | char * 10 | get_host(URI_t *x) { 11 | struct url *u = fetchParseURL(x); 12 | char *r = NULL; 13 | 14 | if (u == NULL || strlen(u->host) == 0) 15 | goto cleanup; 16 | 17 | r = strdup(u->host); 18 | 19 | cleanup: 20 | free(u); 21 | return r; 22 | } 23 | -------------------------------------------------------------------------------- /target/url/exec.h: -------------------------------------------------------------------------------- 1 | #include "url.h" 2 | 3 | char *get_host(URI_t *); 4 | -------------------------------------------------------------------------------- /target/url/url.abnf: -------------------------------------------------------------------------------- 1 | URI = scheme ":" hier_part [ "?" query ] [ "#" fragment ] ; 2 | 3 | hier_part = "//" authority path_abempty 4 | / path_absolute 5 | / path_rootless 6 | / path_empty ; 7 | 8 | URI_reference = URI / relative_ref ; 9 | 10 | absolute_URI = scheme ":" hier_part [ "?" query ] ; 11 | 12 | relative_ref = relative_part [ "?" query ] [ "#" fragment ] ; 13 | 14 | relative_part = "//" authority path_abempty 15 | / path_absolute 16 | / path_noscheme 17 | / path_empty ; 18 | 19 | scheme = "http" ; IGNORE: / ALPHA *( ALPHA / DIGIT / "+" / "_" / "." ) 20 | 21 | authority = [ userinfo "@" ] host [ ":" port ] ; 22 | userinfo = *( unreserved / pct_encoded / sub_delims / ":" ) ; 23 | host = IP_literal / IPv4address / reg_name ; 24 | port = *DIGIT ; 25 | 26 | IP_literal = "[" ( IPv6address / IPvFuture ) "]" ; 27 | 28 | IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub_delims / ":" ) ; 29 | 30 | IPv6address = 6( h16 ":" ) ls32 31 | / "::" 5( h16 ":" ) ls32 32 | / [ h16 ] "::" 4( h16 ":" ) ls32 33 | / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 34 | / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 35 | / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 36 | / [ *4( h16 ":" ) h16 ] "::" ls32 37 | / [ *5( h16 ":" ) h16 ] "::" h16 38 | / [ *6( h16 ":" ) h16 ] "::" ; 39 | 40 | h16 = 1*4HEXDIG ; 41 | ls32 = ( h16 ":" h16 ) / IPv4address ; 42 | IPv4address = dec_octet "." dec_octet "." dec_octet "." dec_octet ; 43 | 44 | dec_octet = DIGIT 45 | / %x31-39 DIGIT 46 | / "1" 2DIGIT 47 | / "2" %x30-34 DIGIT 48 | / "25" %x30-35 ; 49 | 50 | reg_name = *( unreserved / pct_encoded / sub_delims ) ; 51 | 52 | path = path_abempty 53 | / path_absolute 54 | / path_noscheme 55 | / path_rootless 56 | / path_empty ; 57 | 58 | path_abempty = *( "/" segment ) ; 59 | path_absolute = "/" [ segment_nz *( "/" segment ) ] ; 60 | path_noscheme = segment_nz_nc *( "/" segment ) ; 61 | path_rootless = segment_nz *( "/" segment ) ; 62 | path_empty = 0 ; 63 | 64 | segment = *pchar ; 65 | segment_nz = 1*pchar ; 66 | segment_nz_nc = 1*( unreserved / pct_encoded / sub_delims / "@" ) 67 | ; non_zero_length segment without any colon ":" ; 68 | 69 | pchar = unreserved / pct_encoded / sub_delims / ":" / "@" ; 70 | 71 | query = *( pchar / "/" / "?" ) ; 72 | 73 | fragment = *( pchar / "/" / "?" ) ; 74 | 75 | pct_encoded = "%" HEXDIG HEXDIG ; 76 | 77 | unreserved = ALPHA / DIGIT / "_" / "." / "_" / "~" ; 78 | reserved = gen_delims / sub_delims ; 79 | gen_delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" ; 80 | sub_delims = "!" / "$" / "&" / "'" / "(" / ")" 81 | / "*" / "+" / "," / ";" / "=" ; 82 | 83 | ALPHA = %x41-5A / %x61-7A ; 84 | DIGIT = %x30-39 ; 85 | HEXDIG = %x30-39 / %x40-46 86 | -------------------------------------------------------------------------------- /target/url/urltest.mi: -------------------------------------------------------------------------------- 1 | #include 2 | #include "exec.h" 3 | 4 | -- stringify 5 | char * -> minerva_generic_stringify_string; 6 | URI_t * -> minerva_generic_stringify_string; 7 | 8 | -- methods 9 | URI_t *URI() => generic_not_null; 10 | char *get_host(URI_t *) => generic_not_null; 11 | -------------------------------------------------------------------------------- /utils/abnf/abnf_ast.py: -------------------------------------------------------------------------------- 1 | class Element(): 2 | def __init__(self, repeat, element): 3 | self.repeat = repeat 4 | self.element = element 5 | 6 | def __str__(self): 7 | return "%s %s" % (self.repeat, self.element) 8 | 9 | def __repr__(self): 10 | return self.__str__() 11 | 12 | class Rule(): 13 | def __init__(self, rulename, operator, rule): 14 | self.rule = rule 15 | self.rulename = rulename 16 | self.operator = operator 17 | 18 | def __str__(self): 19 | return '%s %s %s' % (self.rulename, self.operator, self.rule) 20 | 21 | def __repr__(self): 22 | return self.__str__() 23 | 24 | class Alternation(): 25 | def add(self, x): 26 | self.alternation.insert(0, x) 27 | 28 | def __init__(self, x = None): 29 | self.alternation = [] 30 | if x is not None: 31 | self.alternation.append(x) 32 | 33 | def __str__(self): 34 | s = map(str, self.alternation) 35 | return '|'.join(s) 36 | 37 | def __repr__(self): 38 | return self.__str__() 39 | 40 | class Concatenation(): 41 | def add(self, x): 42 | self.concat.insert(0, x) 43 | 44 | def __init__(self, x = None): 45 | self.concat = [] 46 | 47 | if x is not None: 48 | self.concat.append(x) 49 | 50 | def __str__(self): 51 | s = map(str, self.concat) 52 | return '.'.join(s) 53 | 54 | def __repr__(self): 55 | return self.__str__() 56 | 57 | class Group(): 58 | def __init__(self, group): 59 | self.group = group 60 | 61 | class Option(): 62 | def __init__(self, opt): 63 | self.option = opt 64 | 65 | 66 | 67 | class NumVal(): 68 | const = None 69 | def __init__(self, num): 70 | base = {'b': 2, 'd': 10, "x": 16}[num[1]] 71 | num = num[2:] 72 | 73 | if '.' in num or '-' not in num: 74 | self.const = "" 75 | num = num.split('.') 76 | for p in num: 77 | self.const += "\\x%02x" % int(p, base) 78 | else: 79 | self.lower, self.upper = map(lambda x: int(x, base), num.split('-')) 80 | 81 | class CharVal(): 82 | def __init__(self, string): 83 | self.string = string 84 | 85 | class ProseVal(): 86 | def __init__(self, string): 87 | self.string = string 88 | 89 | class Rulename(): 90 | def __init__(self, name): 91 | self.name = name 92 | 93 | def __str__(self): 94 | return self.name 95 | 96 | def traverse_rule(ast, callback, global_state = None): 97 | # XXX: do not go into Rules? 98 | # XXX: POSTORDER/PREORDER switch? 99 | if type(ast) in [NumVal, ProseVal, CharVal, Rulename]: 100 | return callback(ast, None, global_state) 101 | elif isinstance(ast, Group): 102 | r = traverse_rule(ast.group, callback, global_state) 103 | return callback(ast, r, global_state) 104 | elif isinstance(ast, Option): 105 | r = traverse_rule(ast.option, callback, global_state) 106 | return callback(ast, r, global_state) 107 | elif isinstance(ast, Alternation): 108 | rs = list(map(lambda x: traverse_rule(x, callback, global_state), ast.alternation)) 109 | return callback(ast, rs, global_state) 110 | elif isinstance(ast, Element): 111 | r = traverse_rule(ast.element, callback, global_state) 112 | return callback(ast, r, global_state) 113 | elif isinstance(ast, Concatenation): 114 | rs = list(map(lambda x: traverse_rule(x, callback, global_state), ast.concat)) 115 | return callback(ast, rs, global_state) 116 | 117 | assert False, "AST node type not supported: {typename}".format(typename = type(ast)) 118 | -------------------------------------------------------------------------------- /utils/abnf/compiler.py: -------------------------------------------------------------------------------- 1 | from abnf_ast import Option, Group, Concatenation, Alternation, Rule, Element, Rulename, NumVal, CharVal, ProseVal, traverse_rule 2 | 3 | def rule_to_type(name, ptr = False): 4 | return "{name}_t{ptr}".format(name = name, ptr = " *" if ptr else "") 5 | 6 | def variable_to_decl(var, prefix = 'v'): 7 | var_num, var_type = var 8 | 9 | return "{var_type}{prefix}{number}".format(var_type = rule_to_type(var_type, ptr = True), prefix = prefix, number = var_num) 10 | 11 | def add_tab(s): 12 | s = s.split('\n') 13 | s = map(lambda x: '\t' + x, s) 14 | return '\n'.join(s) 15 | 16 | def compile_ast(ast, state, global_state): 17 | 18 | if isinstance(state, list): 19 | state = list(map(add_tab, state)) 20 | elif state is not None: 21 | state = add_tab(state) 22 | 23 | 24 | if isinstance(ast, NumVal): 25 | if ast.const is not None: 26 | return "minerva_concat(&r, \"%s\");" % ast.const 27 | else: 28 | return "{char x[2]; x[1] = 0; x[0] = (__rand() %% %d) + %d; minerva_concat(&r, x); }\n" % (ast.upper-ast.lower+1, ast.lower) 29 | elif isinstance(ast, CharVal): 30 | return "minerva_concat(&r, {text});\n".format(text = ast.string) 31 | elif isinstance(ast, ProseVal): 32 | return "minerva_concat(&r, \"{text}\");\n".format(text = ast.string) 33 | elif isinstance(ast, Rulename): 34 | return "minerva_concat(&r, {fname}());".format(fname = ast.name) 35 | elif isinstance(ast, Element): 36 | if ast.repeat is None: 37 | return state 38 | 39 | r = ["{ int num = 0;\n"] 40 | if ast.repeat[0] == 'exact': 41 | r.append(" num = %s;\n" % ast.repeat[1]) 42 | else: 43 | if ast.repeat[1] is not None: 44 | r.append(" num = %s;\n" % ast.repeat[1]) 45 | else: 46 | r.append(" num = 0;") 47 | 48 | if ast.repeat[2] is None: 49 | upper = "10" # XXX: arbitrary? 50 | else: 51 | upper = ast.repeat[2] 52 | 53 | r.append(" num += (__rand() %% %s);" % upper) 54 | r.append("while(num--)") 55 | r.append("{") 56 | r.append(state) 57 | r.append("}") 58 | r.append("}") 59 | return "\n".join(r) 60 | elif isinstance(ast, Alternation): 61 | r = ["switch(__rand() % {branches}) ".format(branches = len(state))] 62 | r.append("{") 63 | for n, code in enumerate(state): 64 | r.append("\tcase {num}: {code} break;".format(num = n, code = code.strip())) 65 | r.append("}") 66 | return "\n".join(r) 67 | elif isinstance(ast, Option): 68 | # XXX: does it make sense? 69 | r = ["if (__rand() % 2) {\n"] 70 | r.append(state) 71 | r.append("}") 72 | return "\n".join(r) 73 | elif isinstance(ast, Concatenation): 74 | return "\n".join(state) 75 | else: 76 | return state or "" 77 | 78 | def compile_rule(rule): 79 | # header 80 | r = [] 81 | r.append("") 82 | r.append("{return_type}".format(return_type = rule_to_type(rule.rulename, ptr = True))) 83 | r.append("{name}()".format(name = rule.rulename)) 84 | r.append("{"); 85 | r.append("char *r = \"\";") 86 | r.append(traverse_rule(rule.rule, compile_ast)) 87 | r.append("return r;") 88 | r.append("}"); 89 | 90 | return '\n'.join(r) 91 | 92 | def compile_include(rules): 93 | # create typedefs 94 | r = [] 95 | 96 | r.append("#include \"minerva_concat.h\"") 97 | 98 | # typedefs 99 | for rule in rules: 100 | r.append("typedef char {name}_t;".format(name = rule.rulename)) 101 | 102 | r.append("") 103 | 104 | # GENERATE INCLUDE 105 | for rule in rules: 106 | r.append("{return_type}{name}();".format(return_type = rule_to_type(rule.rulename, ptr = True), name = rule.rulename)) 107 | 108 | return '\n'.join(r) + "\n" 109 | 110 | 111 | def compile_miconfig(rules, name): 112 | r = [] 113 | r.append("#include ") 114 | r.append("#include \"minerva_concat.h\"") 115 | r.append("#include \"{}.h\"".format(name)) 116 | 117 | # GENERATE MINERVA RULES 118 | for rule in rules: 119 | r.append("{return_type}{name}() => generic_not_null;".format(return_type = rule_to_type(rule.rulename, ptr = True), name = rule.rulename)) 120 | r.append("{return_type} -> minerva_generic_stringify_string;".format(return_type = 121 | rule_to_type(rule.rulename, ptr = True))) 122 | 123 | return '\n'.join(r) + "\n" 124 | 125 | def compile_rules(rules, name): 126 | r = ["#include "] 127 | r.append("#include ") 128 | r.append("#include \"{}.h\"".format(name)) 129 | r.append("") 130 | 131 | return '\n'.join(r) + ''.join(map(compile_rule, rules)) + "\n" 132 | 133 | def compile(rules, name): 134 | with open("{}.h".format(name), "w") as include_file: 135 | include_file.write(compile_include(rules)) 136 | 137 | with open("{}.mi".format(name), "w") as miconfig_file: 138 | miconfig_file.write(compile_miconfig(rules, name)) 139 | 140 | with open("{}.c".format(name), "w") as code_file: 141 | code_file.write(compile_rules(rules, name)) 142 | -------------------------------------------------------------------------------- /utils/abnf/parser.py: -------------------------------------------------------------------------------- 1 | from abnf_ast import Option, Group, Concatenation, Alternation, Rule, Element, Rulename, NumVal, CharVal, ProseVal 2 | import ply.yacc as yacc 3 | import ply.lex as lex 4 | 5 | # Parser of ABNF definied in the RFC5234 6 | # https://datatracker.ietf.org/doc/html/rfc5234 7 | 8 | tokens = ( 9 | 'BIN_VAL', 'DEC_VAL', 'HEX_VAL', 'STRING', 'NOT_EQUAL', 'COMMENT', 10 | 'NUMBER', 'PROSE_VAL', 'CHAR_VAL', 'newline' 11 | ) 12 | 13 | def t_newline(t): 14 | r'\n+' 15 | t.lexer.lineno += t.value.count("\n") 16 | 17 | t_CHAR_VAL = r'"[^"]*"' 18 | t_PROSE_VAL = r'<[^>]+>' 19 | t_NUMBER = r'[0-9]+' 20 | d_BIN = r'[01]+' 21 | d_DEC = r'[0-9]+' 22 | d_HEX = r'[0-9A-Fa-f]+' 23 | 24 | def create_num_token(prefix, definition): 25 | return r'%' + prefix + definition + '(-' + definition + '|(\.' + definition + ')*)' 26 | 27 | t_BIN_VAL = create_num_token('b', d_BIN) 28 | t_DEC_VAL = create_num_token('d', d_DEC) 29 | t_HEX_VAL = create_num_token('x', d_HEX) 30 | t_STRING = r'[A-Za-z_-][A-Za-z0-9_-]+' 31 | t_NOT_EQUAL = r'=/' 32 | t_COMMENT = r';[^\n]*' 33 | t_ignore = "\n\t " # ignore spaces and tabs 34 | 35 | literals = ['=' , '<', '>', '(', ')', '[', ']', '/', '*'] 36 | 37 | def t_error(t): 38 | print("Illegal character '%s' at %d line" % (t.value[0], t.lexer.lineno)) 39 | 40 | lex.lex() 41 | 42 | 43 | def p_rulelist(t): 44 | '''rulelist : rulelist rule 45 | | rule''' 46 | 47 | if len(t) == 2: 48 | t[0] = [t[1]] 49 | return 50 | 51 | t[1].append(t[2]) 52 | t[0] = t[1] 53 | 54 | def p_rule(t): 55 | '''rule : rulename defined_as elements 56 | | rulename defined_as elements COMMENT''' 57 | 58 | t[0] = Rule(t[1], t[2], t[3]) 59 | 60 | def p_rulename(t): 61 | '''rulename : STRING''' 62 | t[0] = Rulename(t[1].replace('-','_')) 63 | 64 | def p_defined_as(t): 65 | '''defined_as : operator ''' 66 | t[0] = t[1] 67 | 68 | def p_elements(t): 69 | '''elements : alternation ''' 70 | t[0] = t[1] 71 | 72 | def p_operator(t): 73 | '''operator : '=' 74 | | NOT_EQUAL ''' 75 | t[0] = t[1] 76 | 77 | def p_alternation(t): 78 | '''alternation : concatenation 79 | | concatenation '/' alternation''' 80 | 81 | if len(t) == 2: 82 | t[0] = t[1] 83 | else: 84 | if isinstance(t[3], Alternation): 85 | t[3].add(t[1]) 86 | t[0] = t[3] 87 | else: 88 | t[0] = Alternation(t[3]) 89 | t[0].add(t[1]) 90 | 91 | def p_concatenation(t): 92 | '''concatenation : repetition 93 | | repetition concatenation''' 94 | 95 | if len(t) == 2: 96 | t[0] = t[1] 97 | else: 98 | if isinstance(t[2], Concatenation): 99 | t[2].add(t[1]) 100 | t[0] = t[2] 101 | else: 102 | t[0] = Concatenation(t[2]) 103 | t[0].add(t[1]) 104 | 105 | def p_repetition(t): 106 | '''repetition : repeat element 107 | | element''' 108 | if len(t) == 2: 109 | t[0] = Element(None, t[1]) 110 | else: 111 | t[0] = Element(t[1], t[2]) 112 | 113 | def p_repeat(t): 114 | '''repeat : NUMBER '*' 115 | | NUMBER '*' NUMBER 116 | | '*' NUMBER 117 | | '*' 118 | | NUMBER ''' 119 | 120 | if len(t) == 3: 121 | if t[1] == '*': 122 | t[0] = ('repeat', None, t[2]) 123 | else: 124 | t[0] = ('repeat', t[1], None) 125 | 126 | if len(t) == 4: 127 | t[0] = ('repeat', t[1], t[3]) 128 | 129 | if len(t) == 2: 130 | if t[1] == '*': 131 | t[0] = ('repeat', None, None) 132 | else: 133 | t[0] = ('exact', t[1]) 134 | 135 | def p_element(t): 136 | '''element : rulename 137 | | group 138 | | option 139 | | char_val 140 | | num_val 141 | | prose_val''' 142 | t[0] = t[1] 143 | 144 | def p_char_val(t): 145 | '''char_val : CHAR_VAL''' 146 | t[0] = CharVal(t[1].replace("\\", "\\\\")) 147 | 148 | def p_prose_val(t): 149 | '''prose_val : PROSE_VAL''' 150 | t[0] = ProseVal(t[1]) 151 | 152 | def p_group(t): 153 | '''group : '(' alternation ')' ''' 154 | t[0] = Group(t[2]) 155 | 156 | def p_option(t): 157 | '''option : '[' alternation ']' ''' 158 | t[0] = Option(t[2]) 159 | 160 | def p_num_val(t): 161 | '''num_val : BIN_VAL 162 | | DEC_VAL 163 | | HEX_VAL''' 164 | t[0] = NumVal(t[1]) 165 | 166 | def p_error(t): 167 | print("Syntax error '%s' at line %d" % (t.value, t.lexer.lineno)) 168 | 169 | yacc.yacc() 170 | 171 | if __name__ == '__main__': 172 | import sys 173 | import compiler 174 | if len(sys.argv) > 2: 175 | p = yacc.parse(open(sys.argv[1]).read()) 176 | compiler.compile(p, sys.argv[2]) 177 | else: 178 | while 1: 179 | try: 180 | line = input('parser_test> ') 181 | line = line + '\n' 182 | print(yacc.parse(line)) 183 | except EOFError: 184 | break 185 | -------------------------------------------------------------------------------- /utils/queue/.gitignore: -------------------------------------------------------------------------------- 1 | # Python files 2 | *.py[cod] 3 | __pycache__/ 4 | lib/__pycache__/ 5 | 6 | # Artifacts 7 | results 8 | compare_output 9 | -------------------------------------------------------------------------------- /utils/queue/compare-worker.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import subprocess 4 | import base64 5 | import filecmp 6 | import os 7 | import itertools 8 | import filecmp 9 | import shutil 10 | import difflib 11 | 12 | from lib.task import TaskWorker 13 | from server import topath 14 | 15 | OUTPUT_PATH = "compare_output" 16 | 17 | def compare_files(a, b): 18 | return filecmp.cmp(a, b) 19 | 20 | 21 | def compare_dir(path): 22 | if path: 23 | seeds = [d for d in os.listdir(path) if os.path.isdir(os.path.join(path, d))] 24 | for seed in seeds: 25 | fnames = [] 26 | for f in os.listdir(os.path.join(path, seed)): 27 | fname = os.path.join(path, seed, f) 28 | if os.path.isfile(fname): 29 | fnames.append(fname) 30 | 31 | diff = [] 32 | # get different files 33 | for a, b in list(itertools.combinations(fnames, 2)): 34 | if not compare_files(a, b): 35 | diff.append(a) 36 | diff.append(b) 37 | 38 | # copy different files to outpud directory 39 | if len(diff) > 0: 40 | dest = os.path.join(OUTPUT_PATH, str(seed).zfill(10)) 41 | os.makedirs(dest, exist_ok=True) 42 | for src in diff: 43 | shutil.copy(src, os.path.join(dest, topath(src))) 44 | 45 | # save diff 46 | fd0 = open(diff[0]).readlines() 47 | fd1 = open(diff[1]).readlines() 48 | outdiff = difflib.unified_diff(fd0, fd1, diff[0], diff[1]) 49 | with open(os.path.join(dest, 'diff'), 'w') as f: 50 | f.write(''.join(outdiff)) 51 | 52 | return {'cmpresult': 'ok', 'diff': ''} 53 | else: 54 | return {'cmpresult': 'error', 'error': f'Path not provided'} 55 | 56 | if __name__ == '__main__': 57 | try: 58 | worker_name = sys.argv[1] 59 | except IndexError: 60 | worker_name = 'compare-worker-1' 61 | 62 | worker = TaskWorker(worker_name) 63 | try: 64 | worker.start(task_type='compare', callback=compare_dir, srvhost='127.0.0.1') 65 | except ConnectionError as e: 66 | sys.exit(e) 67 | except KeyboardInterrupt: 68 | worker.stop() 69 | sys.exit(0) 70 | -------------------------------------------------------------------------------- /utils/queue/lib/exceptions.py: -------------------------------------------------------------------------------- 1 | class TaskException(Exception): 2 | pass 3 | -------------------------------------------------------------------------------- /utils/queue/lib/task.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import platform 3 | 4 | from time import sleep 5 | 6 | import zmq 7 | 8 | from lib.exceptions import TaskException 9 | 10 | logging.basicConfig(level=logging.DEBUG, 11 | format='%(asctime)s [%(levelname)s] %(message)s') 12 | 13 | 14 | class TaskServer: 15 | """ Server """ 16 | def __init__(self): 17 | self.logger = logging.getLogger(self.__class__.__name__) 18 | self._tasks = [] 19 | self._to_compare = [] 20 | self.socket = None 21 | self.running = False 22 | 23 | def __str__(self): 24 | ret = [] 25 | i = 0 26 | for t in self._tasks: 27 | i += 1 28 | ret.append(f'Task #{i:03}') 29 | for k, v in t.items(): 30 | ret.append(' {} → {}'.format(k, v)) 31 | return '\n'.join(ret) 32 | 33 | def start(self, host='127.0.0.1', port='5555'): 34 | self.running = True 35 | self.logger.info(f'Task Server running on {host}:{port}') 36 | 37 | context = zmq.Context() 38 | self.socket = context.socket(zmq.REP) 39 | self.socket.bind(f'tcp://{host}:{port}') 40 | 41 | def add_to_compare(self, path): 42 | if path not in self._to_compare: 43 | self._to_compare.append(path) 44 | 45 | def get_compare(self): 46 | for p in self._to_compare: 47 | return p 48 | return False 49 | 50 | @property 51 | def to_compare(self): 52 | return self._to_compare 53 | 54 | @to_compare.setter 55 | def to_compare(self, cmp): 56 | self._to_compare = cmp 57 | 58 | def process_task(self): 59 | if self.running: 60 | try: 61 | message = self.socket.recv_json() 62 | self.logger.debug(f'Received message from {message["worker_info"]["node"]} ({message["worker_info"]["id"]})') 63 | except ValueError: 64 | strerr = 'Wrong messsage format, could not decode JSON' 65 | self.logger.error(strerr) 66 | self.socket.send_json({'type': 'error', 'error': strerr}) 67 | raise TaskException(strerr) 68 | 69 | try: 70 | mtype = message['type'] 71 | worker_info = message['worker_info'] 72 | except KeyError as e: 73 | strerr = "Wrong message! Missing key: {}".format(e.message) 74 | self.logger.error(strerr) 75 | self.socket.send_json({'type': 'error', 'error': strerr}) 76 | raise TaskException(strerr) 77 | 78 | if mtype == 'task': 79 | if (t := self.get_task(worker_info['system'])): 80 | msg = {'type': 'task', 'task': t} 81 | self.socket.send_json(msg) 82 | self._tasks.remove(t) 83 | else: 84 | self.socket.send_json({'type': 'queue_empty'}) 85 | 86 | elif mtype == 'compare': 87 | self.logger.info('Compare request') 88 | if (path := self.get_compare()): 89 | msg = {'type': 'compare', 'compare': path} 90 | self._to_compare.remove(path) 91 | self.socket.send_json(msg) 92 | else: 93 | self.socket.send_json({'type': 'queue_empty'}) 94 | 95 | elif mtype in ('result', 'compare_result'): 96 | self.logger.info('Result received') 97 | self.socket.send_json({'type': 'ack'}) 98 | return message 99 | 100 | def stop(self): 101 | self.running = False 102 | self.logger.info('Server terminated.') 103 | 104 | @property 105 | def tasks(self): 106 | return self._tasks 107 | 108 | def get_task(self, system): 109 | for t in self._tasks: 110 | if t['system'].lower() == system.lower(): 111 | return t 112 | return False 113 | 114 | @tasks.setter 115 | def tasks(self, tasks): 116 | self._tasks = tasks 117 | 118 | 119 | class TaskWorker: 120 | """ Worker """ 121 | def __init__(self, worker_id): 122 | self.logger = logging.getLogger(self.__class__.__name__) 123 | 124 | self.info = { 125 | 'id': worker_id, 126 | 'node': platform.node(), 127 | 'system': platform.system() 128 | } 129 | 130 | self.context = None 131 | self.zmq_socket = None 132 | 133 | self.running = False 134 | 135 | def __str__(self): 136 | s = '' 137 | for k, v in self.info.items(): 138 | s += f'{k}={v}; ' 139 | return s 140 | 141 | def start(self, callback=print, task_type='task', srvhost='127.0.0.1', srvport='5555'): 142 | self.running = True 143 | 144 | try: 145 | self.logger.info(f'Connecting to server on {srvhost}:{srvport}') 146 | 147 | self.context = zmq.Context() 148 | self.zmq_socket = self.context.socket(zmq.REQ) 149 | #self.zmq_socket.setsockopt(zmq.RCVTIMEO, 1000) 150 | #Do not wait infinitely for socket shutdown 151 | #self.zmq_socket.setsockopt(zmq.LINGER, 2000) 152 | self.zmq_socket.connect(f'tcp://{srvhost}:{srvport}') 153 | 154 | while self.running: 155 | req_msg = {'type': task_type, 'worker_info': self.info} 156 | self.zmq_socket.send_json(req_msg) 157 | message = self.zmq_socket.recv_json() 158 | 159 | mtype = message['type'] 160 | if mtype == 'task' or mtype == 'compare': 161 | if mtype == 'task': 162 | task = message['task'] 163 | elif mtype == 'compare': 164 | task = message['compare'] 165 | 166 | result = callback(task) 167 | result_msg = {'worker_info': self.info} 168 | 169 | if mtype == 'task': 170 | result_msg['type'] = 'result' 171 | result_msg['target'] = task['target'] 172 | elif mtype == 'compare': 173 | result_msg['type'] = 'compare_result' 174 | result_msg['path'] = task 175 | 176 | result_msg['data'] = result 177 | 178 | self.zmq_socket.send_json(result_msg) 179 | r = self.zmq_socket.recv_json() 180 | if r['type'] != 'ack': 181 | self.logger.error(r['error']) 182 | #else: 183 | # self.logger.debug('ACK') 184 | 185 | elif mtype == 'queue_empty': 186 | self.logger.debug('Queue empty') 187 | sleep(1) 188 | 189 | elif mtype == 'error': 190 | self.logger.error(message) 191 | 192 | #except zmq.error.Again as e: 193 | # raise ConnectionError(e.strerror + ' - server down?') 194 | except KeyboardInterrupt: 195 | self.logger.info('SIGINT received') 196 | self.stop() 197 | 198 | def stop(self): 199 | self.zmq_socket.close() 200 | self.context.term() 201 | self.running = False 202 | self.logger.info('Worker finished.') 203 | -------------------------------------------------------------------------------- /utils/queue/run_fuzz.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | minerva_lib/target/toy/bin/minerva-toy-toy -T /dev/stdout -s $1 4 | -------------------------------------------------------------------------------- /utils/queue/server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import base64 4 | import uuid 5 | import random 6 | import string 7 | 8 | from datetime import datetime 9 | 10 | from lib.task import TaskServer 11 | from lib.exceptions import TaskException 12 | 13 | RESULTS_DIR = 'results' 14 | RUN_TS = str(int(datetime.timestamp(datetime.now()))) 15 | RUN_TS = '1660060837' 16 | 17 | targets = set() 18 | targets_done = set() 19 | 20 | def random_task(): 21 | #rnd_target = random.choice(['openssl', 'libressl']) 22 | #rnd_sys = random.choice(['linux', 'freebsd', 'openbsd']) 23 | #seed = str(random.randint(0, 999999999)).zfill(9) 24 | seed = '1234' 25 | task = {'target': 'toy', 'system': 'linux', 'seed': seed} 26 | 27 | return task 28 | 29 | def toy_task(seed): 30 | task = {'target': 'minerva_lib/target/toy/bin/minerva-toy-toy', 'system': 'linux', 'seed': str(seed)} 31 | return task 32 | 33 | def poll(current_tasks=[], queue_size=10): 34 | if len(current_tasks) <= queue_size: 35 | tasks = [] 36 | #for i in range(0, random.randint(0, queue_size)): 37 | # tasks.append(random_task()) 38 | for i in range(3): 39 | seed = random.randint(1000, 2999) 40 | 41 | # TUTAJ DODAĆ ZADANIE 42 | t = toy_task(seed) 43 | 44 | tasks.append(t) 45 | targets.add(t['target']) 46 | return current_tasks + tasks 47 | 48 | return current_tasks 49 | 50 | 51 | def topath(name): 52 | clear_name = '' 53 | for n in name: 54 | if n in string.ascii_letters + string.digits: 55 | clear_name += n 56 | else: 57 | clear_name += '_' 58 | return clear_name 59 | 60 | 61 | if __name__ == '__main__': 62 | ts = TaskServer() 63 | 64 | ts.start('127.0.0.1') 65 | 66 | ts.tasks = poll(ts.tasks) 67 | while True: 68 | #ts.tasks = poll(ts.tasks) 69 | #print(ts) 70 | 71 | if len(ts.tasks) == 0: 72 | for target in targets: 73 | if target not in targets_done: 74 | ts.add_to_compare(os.path.join(RESULTS_DIR, RUN_TS, 75 | topath(target))) 76 | targets_done.add(target) 77 | 78 | try: 79 | r = ts.process_task() 80 | if r: 81 | if r['type'] == 'result': 82 | result = r['data'] 83 | fname = '{system}@{worker}_{uniq}'.format( 84 | system=r['worker_info']['system'].lower(), 85 | worker=r['worker_info']['id'], 86 | uniq=uuid.uuid4().hex 87 | ) 88 | 89 | results_path = os.path.join(RESULTS_DIR, RUN_TS, 90 | topath(r['target']), 91 | topath(result['seed'])) 92 | os.makedirs(results_path, exist_ok=True) 93 | 94 | if result['ret'] == 0: 95 | with open(os.path.join(results_path, fname) + '.out', 'wb') as fd: 96 | fd.write(base64.b64decode(result['stdout'])) 97 | else: 98 | with open(os.path.join(results_path, fname) + '.err', 'wb') as fd: 99 | fd.write(base64.b64decode(result['stderr'])) 100 | if r['type'] == 'compare_result': 101 | if r['data']['cmpresult'] != 'error': 102 | print(r['data']['cmpresult']) 103 | else: 104 | print('Error:', r['data']['error']) 105 | 106 | except TaskException as e: 107 | print('ERROR: {}'.format(e)) 108 | except KeyboardInterrupt: 109 | ts.stop() 110 | break 111 | -------------------------------------------------------------------------------- /utils/queue/worker.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import subprocess 4 | import base64 5 | 6 | from lib.task import TaskWorker 7 | 8 | 9 | def process_task(task): 10 | cmd = [task['target'], '-T', '/dev/stdout', '-s', task['seed']] 11 | p = subprocess.run(cmd, capture_output=True) 12 | 13 | return {'args': '_'.join(p.args), 14 | 'seed': task['seed'], 15 | 'ret': p.returncode, 16 | 'stdout': base64.b64encode(p.stdout).decode(), 17 | 'stderr': base64.b64encode(p.stderr).decode()} 18 | 19 | 20 | if __name__ == '__main__': 21 | try: 22 | worker_name = sys.argv[1] 23 | except IndexError: 24 | worker_name = 'test-worker-1' 25 | 26 | worker = TaskWorker(worker_name) 27 | try: 28 | worker.start(callback=process_task, srvhost='127.0.0.1') 29 | except ConnectionError as e: 30 | sys.exit(e) 31 | except KeyboardInterrupt: 32 | worker.stop() 33 | sys.exit(0) 34 | --------------------------------------------------------------------------------