 Open source case studies for Frama-C ==================================== This repository is a collection of open source C codes to be used with [Frama-C](http://frama-c.com), in particular with the Eva (Evolved Value Analysis) plug-in. Most directories contain open-source code that constitutes a "case study". A few contain sets of tests, benchmarks or tutorials. # Requirements - GNU Make >= 4.0; - (optional, for some scripts) Python >= 3.7. # Basic usage - (required once) `make submodules`: initializes the local Frama-C submodule; - (required once) `make framac`: prepares a git submodule with a clone of the public git of Frama-C, compiles it and installs it locally (in `frama-c/build/bin`); - (required once) add the following alias to your shell: alias fcmake='make -C .frama-c' Each "case study" contains a `.frama-c` subdirectory with the Frama-C Makefile. Running `fcmake` will run Frama-C related targets; running `make` will run the case study's original Makefile (if it exists). - `cd` to the subdirectory of one of the case studies; We recommend `2048` for a short and fast analysis, or `debie1` for a finalized analysis. - Run `fcmake` to parse and run Eva on the predefined targets. ## Makefile targets The scripts provided with Frama-C create several Makefile targets, according to the intended usage. The main ones are: - `display-targets`: lists the base targets - For each base target `t`, the following targets are generated: - `t.parse`: parse the sources; - `t.eva`: run Eva; - `t.eva.gui`: open the GUI. Each target depends on the previous one: running `t.eva.gui` will automatically run `t.eva` if required; the same for `t.parse`. Other generated targets: - `t.parse.gui`: open the GUI with the result of the parsing, *without* running Eva. Mostly useful in conjunction with other plug-ins. - `t.stats`: print time/memory usage. ### Remarks - The output of `t.eva` is verbose, but you can ignore it; the important information (warnings and alarms) can be inspected via the GUI. - The result of the analysis is stored inside `.frama-c`, in subdirectories `t.parse` for parsing and `t.eva` for the Eva analysis. Each subdirectory contains a few log files. - To try other parametrizations, simply edit variables `CPPFLAGS/FCFLAGS/EVAFLAGS` in `.frama-c/GNUmakefile` and re-run `fcmake`. # Notes A summary of the case studies, with a brief description, URL, number of Eva targets, etc, is available at [summary.md](summary.md). ## Source code modifications We attempt to minimize changes to each case study, to keep the code close to the original. Here are the most common kinds of changes: - A `.frama-c` directory is added, with a `GNUmakefile` which defines the Frama-C targets and parameters; - Some stubs file (e.g. `stubs.c`) are added to the `.frama-c` directory, either to emulate an initial state with command-line arguments, or to provide code/specifications for library functions, missing code, non-portable features, etc. - When code modifications are needed (and cannot be moved to the stubs file, e.g. when adding a specification to a `static` functions), we often protect them by `#ifdef __FRAMAC__` guards, to ensure the code compiles as before when not using Frama-C. Note that this is not always the case. - Some unnecessary files for the analysis (e.g. documentation, project setups for IDEs, non-code resources) are removed. - Some Makefiles were renamed `Makefile.original`, and a simplified OSCS-related `Makefile` has been added. This enables compiling some targets in a way that is useful for certain build tools. In case studies related to benchmarking, examples or test suites, we often apply modifications more liberally. ## Rationale The main objectives of these files are: 1. Non-regression tests; 2. Benchmarking; 3. Practical examples. Therefore, some of the code bases are voluntarily parametrized with suboptimal parameters, for non-regression testing. Some code bases undergo partial, progressive improvements. Only a few constitute "finalized" case studies. # Contributions If you know of other open source code bases where Frama-C/Eva produces interesting results, please contribute with pull requests including the case study sources and your `.frama-c/GNUmakefile`. On the other hand, if you have some interesting open-source C software (ideally, C99-compatible) that you are unable to parse and/or run with Frama-C/Eva, consider creating an issue in this repository¹ with the description of the problem you are facing (e.g. missing/incompatible declarations in the Frama-C libc, problems when preprocessing/parsing the code, constructs unsupported by Eva, etc). Ideally, create a (WIP) pull request with the sources in a new directory, ready to be prepared for the case study. ¹ *Note*: direct account creation is disabled in Frama-C's Gitlab; linking a Github account is always possible. # License License files are kept in each directory where they were originally found, when available. We also summarize the license of each directory below. - `2048`: MIT - `basic-cwe-examples`: see `LICENSE` - `bench-moerman2018`: MIT - `c-testsuite`: see `LICENSE` and `LICENSE-tests` - `c-utils` : MIT - `cerberus`: see `LICENSE` - `chrony`: GPL - `debie1`: distribution and use authorized by Patria Aviation Oy, Space Systems Finland Ltd. and Tidorum Ltd, see `README.txt` and `terms_of_use-2014-05.pdf` - `genann`: Zlib, see `LICENSE` - `gnugo`: GPL - `gzip124`: GPL - `hiredis`: Redis license (BSD-style), see `COPYING` - `icpc`: Unlicense - `ioccc`: Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0), see `COPYING` - `itc-benchmarks`: BSD 2-clause, see `COPYING` - `jsmn`: MIT - `kgflags`: MIT, see `LICENSE` - `khash`: MIT - `kilo`: BSD 2-clause "Simplified", see `LICENSE` - `libmodbus`: LGPL - `libspng`: BSD 2-clause, see `LICENSE` - `libyaml`: MIT, see `License` - `line-following-robot`: MIT + modified BSD (for included `avr-libc`), see `LICENSE` and `avr-libc/include/LICENSE` - `mibench`: several, see `LICENSE` file inside each subdirectory - `mini-gmp`: LGPL or GPL - `miniz`: MIT - `microstrain`: GPL and others, see `LICENSE` - `monocypher`: see `README` - `papabench`: GPL - `polarssl`: GPL - `powerwindow`: GPL - `qlz`: GPL - `safestringlib`: MIT - `semver`: MIT - `solitaire`: public domain, see `solitaire.c` - `stmr`: MIT - `tsvc`: MIT, see `license.txt` - `tweetnacl-usable`: public domain, see `LICENSE.txt` - `verisec`: several, according to each app - `x509-parser` : GPLv2 / BSD, see `LICENSE` # Troubleshooting / Debugging (This section is mainly for Frama-C/plug-in developers who want to test OSCS with specific versions of Frama-C) OSCS can work in different modes: 1. With a local Frama-C, installed via the Git submodule 'frama-c' (after running `make framac`); 2. With another, locally-installed Frama-C; 3. With Frama-C installed in the PATH. This behavior is defined in `path.mk`. This file is included (as a symbolic link) in the `.frama-c` directory for each case study. Changing this file will change the behavior of all case studies. - Mode 1 (by default) is enabled as soon as `make framac` is executed. - To enable mode 2, modify the `FRAMAC_DIR=` line in `path.mk` to point to the `bin` directory of your locally installed Frama-C. - To enable mode 3, simply comment the `FRAMAC_DIR=` line. If the value of `FRAMAC_DIR` is invalid (does not point to an existing directory), an error will be raised. If you need help debugging, consider adding messages such as `$(info FRAMAC_DIR is: $(FRAMAC_DIR))` to `path.mk`. When running one of the `make` targets, these messages might help understand if the path has been properly set.